diff options
Diffstat (limited to 'cscmd/parse.y')
-rw-r--r-- | cscmd/parse.y | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/cscmd/parse.y b/cscmd/parse.y new file mode 100644 index 0000000..cdb2d5b --- /dev/null +++ b/cscmd/parse.y @@ -0,0 +1,107 @@ + +%{ + +#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(); } + ; + +%% + |