%{ #include #include #include "syntax.h" using namespace std; int yylex(); void yyerror(const char* p) { fprintf(stderr, p); } %} %define parse.trace %union { float num; std::string *sym; Node *expr; NodeList *exprlist; } %token ID %token NUM %token STRING %token STOP %token INDENT DEDENT %token IF ELIF ELSE %right GETS %left CAT %left '+' '-' %left '/' '*' %left MAPS %nterm expr %nterm exprlist %% program: statements | statements statement; statements: statements statement STOP | statements STOP | // null production ; statement: assignment | funcall | conditional; assignment: ID GETS expr; assignments: assignments assignment STOP | // null production; expr: funcdef | funcall | objdef | expr CAT expr { $$ = new OpNode(CAT, $1, $3); } | expr '+' expr { $$ = new OpNode('+', $1, $3); } | expr '-' expr { $$ = new OpNode('-', $1, $3); } | expr '*' expr { $$ = new OpNode('*', $1, $3); } | expr '/' expr { $$ = new OpNode('/', $1, $3); } | '(' expr ')' {$$ = $2;} | ID {$$ = new IdNode($1);} | NUM {$$ = new NumNode($1);} | STRING {$$ = new StringNode($1);}; funcdef: param MAPS expr | param MAPS block; param: ID | '_' | // null production; funcall: ID '(' exprlist ')' { print_expression_list($3); } exprlist: exprlist ',' expr { $1 -> push_back($3); $$ = $1; } | expr { $$ = new NodeList(); $$ -> push_back($1); } | { $$ = new NodeList(); } // null production; conditional: IF expr block elifs | IF expr block elifs ELSE block; elifs: ELIF expr block elifs| // null production; objdef: '{' block_assignments '}' | '{' '}' block: STOP INDENT statement statements DEDENT block_assignments: STOP INDENT assignments DEDENT %%