/*** definition section ***/ %{ /* C to be copied verbatim */ #include "lexer.h" #include "node.h" void yyerror(Node **root, const char *msg); %} %code requires { #include "node.h" } %union { Node *node; int ival; char *sval; }; %locations %start input %parse-param {Node **root} %token L_PAREN R_PAREN L_BRACK R_BRACK SEMI_COL COMP MULT DIV MOD MINUS PLUS INT VOID RET %token WORD %token NUMBER %type input %type func %type stmt %type exp %type term %type factor %type un_op /*** rules section ***/ %% input: func { *root = create_node(PROG); add_child(*root, $1); } ; func: INT WORD L_PAREN VOID R_PAREN L_BRACK stmt R_BRACK { $$ = create_function($2); add_child($$, $7); } ; stmt: RET exp SEMI_COL { $$ = create_node(STMT); add_child($$, $2); } ; exp: term { $$ = $1; } | exp PLUS term { $$ = create_expr(PLUS_SYM); add_child($$, $1); add_child($$, $3); } | exp MINUS term { $$ = create_expr(MINUS_SYM); add_child($$, $1); add_child($$, $3); } ; term: factor { $$ = $1; } | term MULT factor { $$ = create_expr(MULT_SYM); add_child($$, $1); add_child($$, $3); } | term DIV factor { $$ = create_expr(DIV_SYM); add_child($$, $1); add_child($$, $3); } | term MOD factor { $$ = create_expr(MOD_SYM); add_child($$, $1); add_child($$, $3); } ; factor: NUMBER { $$ = create_const($1); } | un_op factor { $$ = create_expr($1); add_child($$, $2); } | L_PAREN exp R_PAREN { $$ = $2; } ; un_op: COMP { $$ = COMP_SYM; } | MINUS { $$ = NEG_SYM; } ; %% void yyerror(Node **root, const char *msg) { printf("** Line %d: %s\n", yylineno, msg); }