/* $Id$ */ %{ #include "kmakefile.h" #include "y.tab.h" #include #include #include #include struct parse_param* yyparam; char** yylist = NULL; int yylex(); int yyerror(const char*); void push_yylist(const char* value); int call_function(const char* name, int argc, char** argv); void define_var(const char* key, const char* value); char* get_var(const char* key); %} %union { struct { char* value; int type; } scalar; } %start statement_list %token NEWLINE EQUAL IDENT STRING DELIM SPACES %% statement_list : statement | statement_list statement; statement : assignment NEWLINE | call NEWLINE | NEWLINE; assignment : IDENT EQUAL value { define_var($1, $3); } | IDENT EQUAL { define_var($1, ""); }; call : IDENT bracket_start bracket_end { char* args[1]; args[0] = NULL; if(call_function($1, 0, args)){ fprintf(stderr, "runtime error in function call `%s'\n", $1); return 1; } } | IDENT bracket_start call_args bracket_end { int i; if(yylist != NULL){ for(i = 0; yylist[i] != NULL; i++); if(call_function($1, i, yylist)){ fprintf(stderr, "runtime error in function call `%s'\n", $1); return 1; } for(i = 0; yylist[i] != NULL; i++) free(yylist[i]); free(yylist); } yylist = NULL; }; call_args : call_arg { push_yylist($1); } | call_args DELIM call_arg { push_yylist($3); }; call_arg : value; bracket_start : '('; bracket_end : ')'; value : STRING | IDENT { char* var = get_var($$); if(var == NULL){ fprintf(stderr, "variable `%s' not defined\n", $$); return 1; } $$ = KMAKE_STRING; free($$); $$ = malloc(strlen(var) + 1); strcpy($$, var); }; %% void push_yylist(const char* value){ int i; char** old; if(yylist == NULL){ yylist = malloc(sizeof(*yylist)); yylist[0] = NULL; } old = yylist; for(i = 0; old[i] != NULL; i++); yylist = malloc(sizeof(*yylist) * (i + 2)); for(i = 0; old[i] != NULL; i++) yylist[i] = old[i]; yylist[i] = malloc(strlen(value) + 1); yylist[i + 1] = NULL; strcpy(yylist[i], value); free(old); }