summaryrefslogtreecommitdiff
path: root/src/frontend/parser.y
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-01-28 14:39:47 -0500
committerbd <bdunahu@operationnull.com>2025-01-28 14:39:47 -0500
commit9e09767e23a4edb6b31540195bfe885f83e080d7 (patch)
tree42454c51ea8e0c8cf90b7c9020dedf3a5627cea2 /src/frontend/parser.y
parentc63a873fe7fbf7947e07acfaf2402fe85100deba (diff)
[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
Diffstat (limited to 'src/frontend/parser.y')
-rw-r--r--src/frontend/parser.y116
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);
+}
+