]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
fixed segfault in parser
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 21 May 2018 13:55:49 +0000 (09:55 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 21 May 2018 13:55:49 +0000 (09:55 -0400)
source/parser.c

index a4611860ddd9da09043467638294b05a3b29c402..c0d8c348f917e7d83da6c28162dab36d3f8e9da4 100644 (file)
@@ -1,9 +1,3 @@
-/**
-  @file parser.c
-  @brief See header for details
-  $Revision$
-  $HeadURL$
-  */
 #include <sclpl.h>
 
 /* 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, "<file>:%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;
 }