From d8fff3fe8265449c0e770eed982c09213e40fffd Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 21 May 2018 09:55:49 -0400 Subject: [PATCH] fixed segfault in parser --- source/parser.c | 86 ++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 54 deletions(-) diff --git a/source/parser.c b/source/parser.c index a461186..c0d8c34 100644 --- a/source/parser.c +++ b/source/parser.c @@ -1,9 +1,3 @@ -/** - @file parser.c - @brief See header for details - $Revision$ - $HeadURL$ - */ #include /* Private Declarations @@ -24,12 +18,11 @@ static AST* func_app(Parser* p, AST* fn); // Parsing Routines static void fetch(Parser* parser); static Tok* peek(Parser* parser); -static bool parser_eof(Parser* parser); -static void parser_resume(Parser* parser); static void error(Parser* parser, const char* text); static bool match(Parser* parser, TokType type); -static Tok* accept(Parser* parser, TokType type); -static Tok* expect(Parser* parser, TokType type); +static bool accept(Parser* parser, TokType type); +static void expect(Parser* parser, TokType type); +static Tok* expect_val(Parser* parser, TokType type); /* Grammar Definition *****************************************************************************/ @@ -46,7 +39,7 @@ AST* toplevel(Parser* p) { static AST* const_definition(Parser* p) { AST* expr; - Tok* id = expect(p, T_ID); + Tok* id = expect_val(p, T_ID); if (peek(p)->type == T_LPAR) { expr = function(p); } else { @@ -65,7 +58,7 @@ static AST* const_expression(Parser* p) { } else if (accept(p, T_FN)) { expr = function(p); } else if (match(p, T_ID)) { - expr = Ident(expect(p,T_ID)); + expr = Ident(expect_val(p, T_ID)); } else { expr = literal(p); } @@ -74,7 +67,7 @@ static AST* const_expression(Parser* p) { static AST* definition(Parser* p) { AST* expr; - Tok* id = expect(p, T_ID); + Tok* id = expect_val(p, T_ID); if (peek(p)->type == T_LPAR) { expr = function(p); } else { @@ -95,7 +88,7 @@ static AST* expression(Parser* p) { } else if (accept(p, T_FN)) { expr = function(p); } else if (match(p, T_ID)) { - expr = Ident(expect(p,T_ID)); + expr = Ident(expect_val(p,T_ID)); } else { expr = literal(p); } @@ -109,7 +102,7 @@ static AST* function(Parser* p) { AST* func = Func(); expect(p, T_LPAR); while(peek(p)->type != T_RPAR) { - func_add_arg(func, Ident(expect(p,T_ID))); + func_add_arg(func, Ident(expect_val(p,T_ID))); type_annotation(p); if(peek(p)->type != T_RPAR) expect(p, T_COMMA); @@ -142,7 +135,7 @@ static AST* literal(Parser* p) { case T_STRING: case T_INT: case T_FLOAT: - ret = token_to_tree(expect(p, tok->type)); + ret = token_to_tree(expect_val(p, tok->type)); break; default: error(p, "Expected a literal"); @@ -175,8 +168,7 @@ static AST* expr_block(Parser* p) { return block; } -static AST* token_to_tree(Tok* tok) -{ +static AST* token_to_tree(Tok* tok) { switch (tok->type) { case T_BOOL: return Bool(tok); case T_CHAR: return Char(tok); @@ -213,8 +205,7 @@ static AST* func_app(Parser* p, AST* fn) { /* Parsing Routines *****************************************************************************/ -Parser* parser_new(char* prompt, FILE* input) -{ +Parser* parser_new(char* prompt, FILE* input) { Parser* parser = emalloc(sizeof(Parser)); memset(parser, 0, sizeof(Parser)); parser->input = input; @@ -222,56 +213,43 @@ Parser* parser_new(char* prompt, FILE* input) return parser; } -static void fetch(Parser* parser) -{ - gettoken(parser, &(parser->tok)); -} - -static Tok* peek(Parser* p) -{ +static Tok* peek(Parser* p) { if (T_NONE == p->tok.type) gettoken(p, &(p->tok)); return &(p->tok); } -static bool parser_eof(Parser* parser) -{ - return (peek(parser)->type == T_END_FILE); -} - -static void parser_resume(Parser* parser) -{ - if ((T_NONE != parser->tok.type) && (T_END_FILE != parser->tok.type)) - parser->tok.type = T_NONE; - /* We ignore the rest of the current line and attempt to start parsing - * again on the next line */ - fetchline(parser); -} - -static void error(Parser* parser, const char* text) -{ +static void error(Parser* parser, const char* text) { Tok* tok = peek(parser); fprintf(stderr, ":%zu:%zu:Error: %s\n", tok->line, tok->col, text); exit(1); } -static bool match(Parser* parser, TokType type) -{ +static bool match(Parser* parser, TokType type) { return (peek(parser)->type == type); } -static Tok* accept(Parser* parser, TokType type) -{ - Tok* tok = peek(parser); - if (tok->type == type) +static bool accept(Parser* parser, TokType type) { + if (peek(parser)->type == type) { parser->tok.type = T_NONE; - return tok; + return true; + } + return false; +} + +static void expect(Parser* parser, TokType type) { + if (!accept(parser, type)) + error(parser, "Unexpected token"); } -static Tok* expect(Parser* parser, TokType type) -{ - Tok* tok = accept(parser, type); - if (tok == NULL) +static Tok* expect_val(Parser* parser, TokType type) { + Tok* tok = NULL; + if (peek(parser)->type == type) { + tok = calloc(1, sizeof(Tok)); + *tok = *(peek(parser)); + parser->tok.type = T_NONE; + } else { error(parser, "Unexpected token"); + } return tok; } -- 2.54.0