Author | Jakob Wakeling <[email protected]> |
Date | 2021-09-06 15:42:35 |
Commit | 272888243bd3c867399ae0423c0b33a9f8fc0008 |
Parent | 431f98e2da1b4d79b70c00c85c1e840f49140215 |
parse: Streamline declaration parsing
Diffstat
M | doc/g.ebnf | | | 11 | ++++++----- |
M | src/g.h | | | 2 | +- |
M | src/lex.c | | | 5 | +++-- |
M | src/parse.c | | | 95 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
4 files changed, 50 insertions, 63 deletions
diff --git a/doc/g.ebnf b/doc/g.ebnf index 299abaf..259076d 100644 --- a/doc/g.ebnf +++ b/doc/g.ebnf @@ -9,11 +9,12 @@ prog = { decl } ; (* Declarations *) -decl = decl_variable | decl_constant | decl_procedure ; -decl_variable = iden, ":", ( type, [ "=", expr ] ) | ( "=", expr ), ";" ; -decl_constant = iden, ":", [ type ], ":", expr, ";" ; -decl_procedure = iden, ":", [ type ], ":", "proc", "(", [ parm_list ], ")" - , "->", type, "{", { decl | stmt | expr }, "}" ; +decl = iden, ":", decl_constant | decl_variable ; +decl_constant = [ type ], ":", expr, ";" ; +decl_variable = ( type, [ "=", expr ] ) | ( "=", expr ), ";" ; + +decl_procedure = [ type ], ":", "proc", "(", [ parm_list ], ")" , "->", type + , "{", { decl | stmt | expr }, "}" ; (* Statements *) stmt = "{", stmt, "}" diff --git a/src/g.h b/src/g.h index 5f39dde..d79947b 100644 --- a/src/g.h +++ b/src/g.h @@ -22,7 +22,7 @@ typedef enum { LK_LBRACE, LK_RBRACE, LK_COLON, LK_SCOLON, LK_PERIOD, LK_COMMA, - LK_RARROW, + LK_EQUALS, LK_RARROW, LK_PROC, LK_RETURN, } tok_k; diff --git a/src/lex.c b/src/lex.c index b7ad3b4..e325515 100644 --- a/src/lex.c +++ b/src/lex.c @@ -33,8 +33,8 @@ char *tok_ks[] = { "LK_LBRACE", "LK_RBRACE", "LK_COLON", "LK_SCOLON", "LK_PERIOD", "LK_COMMA", + "LK_EQUALS", "LK_RARROW", - "LK_RARROW", "LK_PROC", "LK_RETURN", }; @@ -91,6 +91,7 @@ skip:; case ';': { n.k = LK_SCOLON; } goto esc_1; case '.': { n.k = LK_PERIOD; } goto esc_1; case ',': { n.k = LK_COMMA; } goto esc_1; + case '=': { n.k = LK_EQUALS; } goto esc_1; case '-': switch (D) { case '>': { n.k = LK_RARROW; } goto esc_2; } diff --git a/src/parse.c b/src/parse.c index ca9bc96..f394045 100644 --- a/src/parse.c +++ b/src/parse.c @@ -31,44 +31,41 @@ char *ast_ks[] = { "AK_RETURN", }; -static ast *parser_parse_root(lex *l); -static ast *parser_parse_decl(lex *l); +static ast *parse_decl(lex *l); -static ast *parser_parse_stmt(lex *l); -static ast *parser_parse_stmt_comp(lex *l); +static ast *parse_stmt(lex *l); +static ast *parse_stmt_comp(lex *l); -static ast *parser_parse_expr(lex *l); -static ast *parser_parse_expr_term(lex *l); -static ast *parser_parse_expr_fact(lex *l); +static ast *parse_expr(lex *l); -static ast *parser_parse_proc(lex *l); -static ast *parser_parse_proc_parm(lex *l); -static ast *parser_parse_proc_rett(lex *l); +static ast *parse_proc(lex *l); +static ast *parse_proc_parm(lex *l); +static ast *parse_proc_rett(lex *l); -static ast *parser_parse_int(lex *l); +static ast *parse_int(lex *l); ast *ast_init() { return calloc(1, sizeof (ast)); } void ast_free(ast *a) { stack_free(a->cs); free(a); return; } -ast *parse(lex *l) { return parser_parse_root(l); } - -static ast *parser_parse_root(lex *l) { - return parser_parse_decl(l); +/* prog = { decl } ; */ +ast *parse(lex *l) { + return parse_decl(l); } -/* Parse a declaration. */ -static ast *parser_parse_decl(lex *l) { +/* decl = iden, ":", decl_variable | decl_constant ; */ +/* decl_constant = [ type ], ":", expr, ";" ; */ +/* decl_variable = ( type, [ "=", expr ] ) | ( "=", expr ), ";" ; */ +static ast *parse_decl(lex *l) { ast *a = ast_init(); - a->s = lex_kind(l, LK_IDN).s; - lex_kind(l, LK_COLON); + a->s = lex_kind(l, LK_IDN).s; lex_kind(l, LK_COLON); - if (lex_peek(l).k == LK_IDN) { /* lookup and store type */ } + if (lex_peek(l).k == LK_IDN) { /* TODO lookup and store type */ } switch (lex_peek(l).k) { case LK_COLON: { lex_kind(l, LK_COLON); a->k = AK_DECL; } goto decl_expr; - // case LK_ASSN: { lex_kind(l, LK_ASSN); a->k = AK_ASSN; } goto decl_expr; - decl_expr: { a->cl = parser_parse_expr(l); } break; + case LK_EQUALS: { lex_kind(l, LK_EQUALS); a->k = AK_DECL; } goto decl_expr; + decl_expr: { a->cl = parse_expr(l); } break; default: { error( 1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_decl)", lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k] @@ -79,11 +76,11 @@ static ast *parser_parse_decl(lex *l) { } /* Parse a statement. */ -static ast *parser_parse_stmt(lex *l) { +static ast *parse_stmt(lex *l) { ast *a = ast_init(); switch (lex_peek(l).k) { - case LK_RETURN: { a->k = AK_RETURN; lex_kind(l, LK_RETURN); a->c = parser_parse_expr(l); } break; + case LK_RETURN: { a->k = AK_RETURN; lex_kind(l, LK_RETURN); a->c = parse_expr(l); } break; default: { error( 1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_stmt)", lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k] @@ -94,7 +91,7 @@ static ast *parser_parse_stmt(lex *l) { } /* Parse a compound statement. */ -static ast *parser_parse_stmt_comp(lex *l) { +static ast *parse_stmt_comp(lex *l) { lex_kind(l, LK_LBRACE); ast *a = ast_init(); a->k = AK_COMP; a->cs = stack_init(); @@ -102,8 +99,8 @@ static ast *parser_parse_stmt_comp(lex *l) { /* Parse statements and expressions until EOF or closing brace */ for (; lex_peek(l).k != LK_EOF && lex_peek(l).k != LK_RBRACE;) { switch (lex_peek(l).k) { - case LK_RETURN: { stack_push(a->cs, parser_parse_stmt(l)); } break; - default: { stack_push(a->cs, parser_parse_expr(l)); } break; + case LK_RETURN: { stack_push(a->cs, parse_stmt(l)); } break; + default: { stack_push(a->cs, parse_expr(l)); } break; } if (lex_peek(l).k == LK_SCOLON) { lex_kind(l, LK_SCOLON); } @@ -113,37 +110,23 @@ static ast *parser_parse_stmt_comp(lex *l) { } /* Parse an expression. */ -static ast *parser_parse_expr(lex *l) { - ast *al = parser_parse_expr_term(l); - - - - return al; -} - -/* Parse an expression term. */ -static ast *parser_parse_expr_term(lex *l) { - ast *al = parser_parse_expr_fact(l); - - +static ast *parse_expr(lex *l) { + ast *a = ast_init(); - return al; -} - -/* Parse an expression factor. */ -static ast *parser_parse_expr_fact(lex *l) { switch (lex_peek(l).k) { - case LK_PROC: { return parser_parse_proc(l); } break; - case LK_INT: { return parser_parse_int(l); } break; + case LK_PROC: { return parse_proc(l); } break; + case LK_INT: { return parse_int(l); } break; default: { error( 1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_expr_fact)", lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k] ); } break; } + + return a; } /* Parse a procedure. */ -static ast *parser_parse_proc(lex *l) { +static ast *parse_proc(lex *l) { lex_kind(l, LK_PROC); ast *a = ast_init(); a->k = AK_PROCEDURE; @@ -152,11 +135,11 @@ static ast *parser_parse_proc(lex *l) { /* Parse optional procedure parameter(s) */ if (lex_peek(l).k != LK_RPAREN) { - stack_push(a->cs, parser_parse_proc_parm(l)); + stack_push(a->cs, parse_proc_parm(l)); while (lex_peek(l).k == LK_COMMA) { lex_kind(l, LK_COMMA); - stack_push(a->cs, parser_parse_proc_parm(l)); + stack_push(a->cs, parse_proc_parm(l)); } } @@ -171,22 +154,22 @@ static ast *parser_parse_proc(lex *l) { lex_kind(l, LK_IDN); a->t = t_s64; } - a->c = parser_parse_stmt_comp(l); + a->c = parse_stmt_comp(l); return a; } /* Parse a procedure parameter. */ -static ast *parser_parse_proc_parm(lex *l) { +static ast *parse_proc_parm(lex *l) { return NULL; /* TODO */ } /* Parse a procedure return type. */ -static ast *parser_parse_proc_rett(lex *l) { +static ast *parse_proc_rett(lex *l) { return NULL; /* TODO */ } -static ast *parser_parse_int(lex *l) { +static ast *parse_int(lex *l) { val v = val_strint(lex_kind(l, LK_INT).s); ast *a = ast_init(); a->k = AK_INT; a->v = v; return a;