%{ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include %} %union { SYMBOL *sym; } %token VARIABLE 501 SECTION 502 REPO 503 %token 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(); } ; %%