diff options
Diffstat (limited to 'src/frontend/parser.y')
-rw-r--r-- | src/frontend/parser.y | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/frontend/parser.y b/src/frontend/parser.y new file mode 100644 index 0000000..aa58f64 --- /dev/null +++ b/src/frontend/parser.y @@ -0,0 +1,116 @@ +/*** 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 <sval> WORD +%token <ival> NUMBER + +%type <node> input +%type <node> func +%type <node> stmt +%type <node> exp +%type <node> term +%type <node> factor +%type <ival> 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); + } +| un_op exp { + $$ = create_expr($1); + add_child($$, $2); + } +; + +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); + } +| 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); +} + |