%{
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#include <locale.h>
#include <wchar.h>
#include <wctype.h>
#include <defs.h>
#include <main.h>
#include <error.h>
#include <msglog.h>
#include <xalloc.h>
#include <utf8ing.h>
#include <symtab.h>
#include <parse.h>
#include <lex.h>
%}
%union
{
SYMBOL *sym;
}
%token <sym> VARIABLE 501 SECTION 502 REPO 503
%token <sym> NUMERICAL 510 STRING 511 PATH 512
%right '='
%left UNARYMINUS
/************************************************************
Following tokens declared only for verbose error messaging
to prevent "$undefined" values of unexpected symbols:
*/
%token '!' '"' '#' '$' '%' '&' '\'' '(' ')' '*' '/' '+' '-'
%token '.' ',' ':' '<' '>' '?' '@' '[' '\\' ']' '^' '`'
%start list
%%
list: /* nothing */
| list ';'
| list repo
| list section
| list assign ';'
| list error ';' { return 1; }
;
assign: VARIABLE '=' NUMERICAL { (void)assign_value( $1, $3 ); }
| VARIABLE '=' '+' NUMERICAL { (void)assign_value( $1, $4 ); }
| VARIABLE '=' '-' NUMERICAL %prec UNARYMINUS { $4->u.value = -$4->u.value; (void)assign_value( $1, $4 ); }
| VARIABLE '=' STRING { (void)assign_value( $1, $3 ); }
| VARIABLE '=' PATH { (void)assign_value( $1, $3 ); }
| NUMERICAL '=' NUMERICAL { (void)assign_value( $1, $3 ); }
| STRING '=' STRING { (void)assign_value( $1, $3 ); }
| PATH '=' PATH { (void)assign_value( $1, $3 ); }
;
alist: /* nothing */
| alist ';'
| alist assign ';'
;
repo: REPO PATH '{'
{
if( lookup_repo( $2->u.path ) )
{
error( "Repository '%s' is already defined", $2->u.path );
return 1;
}
(void)assign_value( $1, $2 ); push_symlist( (SYMBOL **)&($1->list) );
}
alist
'}' { pop_symlist(); }
;
rlist: /* nothing */
| rlist repo
;
section:
SECTION STRING '{'
{
if( lookup_section( $2->u.string ) )
{
error( "Section '%s' is already defined", $2->u.string );
return 1;
}
(void)assign_value( $1, $2 ); push_symlist( (SYMBOL **)&($1->list) );
}
rlist
'}' { pop_symlist(); }
;
%%