From 9e09767e23a4edb6b31540195bfe885f83e080d7 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 28 Jan 2025 14:39:47 -0500 Subject: [Ongoing] Rewrite frontend to use Flex/Bison This is a merge of another experiment, so the changes are large: - separated "modules" directory into frontend/backend - adjusted module names and moved files for this to happen - removed modules lexer & parser - removed all the unit tests (most were outdated) - added Bison, flex, and C development tools to manifest.scm - added lexer.l, a source file used by the flex utility with a functioning lexing implementation - added parser.y, a source file used by the bison utility with a functioning parser implementation - added node.c and node.h, which parser.y uses to construct an AST of a C source file (up to binary ops) - added driver.c, a Guile-C interface that provides a module to scheme programs - added a Makefile to make all of this - added stuff to .gitignore --- src/frontend/parser.y | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/frontend/parser.y (limited to 'src/frontend/parser.y') 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 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); + } +| 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); +} + -- cgit v1.2.3