]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
added some error handling
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 2 Oct 2014 00:00:05 +0000 (20:00 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 2 Oct 2014 00:00:05 +0000 (20:00 -0400)
source/sclpl/grammar.c
source/sclpl/lexer.c
source/sclpl/lexer.h
source/sclpl/main.c
source/sclpl/parser.c
source/sclpl/parser.h
source/sclpl/scanner.c
source/sclpl/scanner.h

index 9ab652304e22d311181c550009664f1d2c250b2f..8a4a33c2a5022d7ac84dfb52c377f2fd790b1654 100644 (file)
@@ -5,18 +5,25 @@
   $HeadURL$
   */
 #include "grammar.h"
+#include "exn.h"
 
 tree_t* grammar_toplevel(parser_t* p_parser)
 {
-    if (parser_accept_str(p_parser, T_VAR, "import"))
-        grammar_import(p_parser);
-    else if (parser_accept_str(p_parser, T_VAR, "def"))
-        grammar_definition(p_parser);
-    else if (p_parser->p_lexer->scanner->p_input == stdin)
-        grammar_expression(p_parser);
-    else
-        parser_error(p_parser, "Unrecognized top-level form");
-    return parser_get_tree(p_parser);
+    tree_t* p_tree = NULL;
+    try {
+        if (parser_accept_str(p_parser, T_VAR, "import"))
+            grammar_import(p_parser);
+        else if (parser_accept_str(p_parser, T_VAR, "def"))
+            grammar_definition(p_parser);
+        else if (p_parser->p_lexer->scanner->p_input == stdin)
+            grammar_expression(p_parser);
+        else
+            parser_error(p_parser, "Unrecognized top-level form");
+        p_tree = parser_get_tree(p_parser);
+    } catch(ParseException) {
+        fprintf(stderr, "Invalid Syntax\n");
+    }
+    return p_tree;
 }
 
 void grammar_import(parser_t* p_parser)
index b0bafe5946777f130fbf77711090b13663e065a7..dc0f6aeda1488c84196d75a1dcd01043f34f94c2 100644 (file)
@@ -52,13 +52,17 @@ lex_tok_t* lexer_read(lexer_t* p_lexer) {
     char* text = scanner_read(p_lexer->scanner);
     if (NULL != text) {
         p_tok = lexer_make_token(text);
-        if (NULL != p_tok)
-            printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok));
+        //if (NULL != p_tok)
+        //    printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok));
         free(text);
     }
     return p_tok;
 }
 
+void lexer_skipline(lexer_t* p_lexer) {
+    scanner_getline(p_lexer->scanner);
+}
+
 static lex_tok_t* lexer_make_token(char* text) {
     lex_tok_t* p_tok = NULL;
     if ((0 == strcmp(text,"end") || (text[0] == ';'))) {
index e0536b81e2814669f0f859e4c1cb1da2dbc6ed0c..40d65fa559f4adc97c4b796cd0e1e33ebb3b35ed 100644 (file)
@@ -33,6 +33,8 @@ lexer_t* lexer_new(char* p_prompt, FILE* p_input);
 
 lex_tok_t* lexer_read(lexer_t* p_lexer);
 
+void lexer_skipline(lexer_t* p_lexer);
+
 char* lexer_tok_type_str(lex_tok_t* p_tok);
 
 #endif /* LEXER_H */
index 2aebbb352787d2c992353e64879407c26dffc48c..0e032a7dc3e01769991bdb16bb5fe4dc75cd69b6 100644 (file)
@@ -50,9 +50,13 @@ int main(int argc, char **argv) {
     parser_t* p_parser = parser_new(":> ", stdin);
     while(!parser_eof(p_parser)) {
         tree_t* p_tree = grammar_toplevel(p_parser);
-        print_tree(p_tree, 0);
-        mem_release(p_tree);
-        puts("OK.");
+        if (NULL != p_tree) {
+            print_tree(p_tree, 0);
+            mem_release(p_tree);
+            puts("OK.");
+        } else {
+            parser_resume(p_parser);
+        }
     }
     mem_release(p_parser);
 
index 94824598180d964c6b10984055ff4ccc667f0bae..93175943d13c7bf14cd9ad91ce47fe6f07701f81 100644 (file)
@@ -7,6 +7,8 @@
 #include "parser.h"
 #include "vec.h"
 
+DEFINE_EXCEPTION(ParseException, &RuntimeException);
+
 lex_tok_t tok_eof = { T_END_FILE, NULL, 0, 0, NULL };
 
 static void parser_free(void* p_obj) {
@@ -59,11 +61,16 @@ bool parser_eof(parser_t* p_parser) {
     return (parser_peek(p_parser)->type == T_END_FILE);
 }
 
+void parser_resume(parser_t* p_parser) {
+    if (NULL != p_parser->p_tok)
+        mem_release(p_parser->p_tok);
+    vec_clear(p_parser->p_tok_buf);
+    lexer_skipline(p_parser->p_lexer);
+}
+
 void parser_error(parser_t* p_parser, const char* p_text)
 {
-    (void)p_parser;
-    fprintf(stderr,"Error: %s\n",p_text);
-    exit(1);
+    throw_msg(ParseException, p_text);
 }
 
 bool parser_accept(parser_t* p_parser, lex_tok_type_t type)
@@ -128,8 +135,14 @@ void parser_reduce(parser_t* p_parser, size_t mark)
 }
 
 tree_t* parser_get_tree(parser_t* p_parser) {
-    tree_t* p_tree = parser_tree_new(TREE, p_parser->p_tok_buf);
-    p_parser->p_tok_buf = vec_new(0);
+    tree_t* p_tree = NULL;
+    if (1 == vec_size(p_parser->p_tok_buf)) {
+        p_tree = mem_retain(vec_at(p_parser->p_tok_buf, 0));
+        vec_clear(p_parser->p_tok_buf);
+    } else {
+        p_tree = parser_tree_new(TREE, p_parser->p_tok_buf);
+        p_parser->p_tok_buf = vec_new(0);
+    }
     return p_tree;
 }
 
index 0e62b1a851eda26b498e143f664aad44c499ff26..0ab71fce2c328fe407607f8bf80a462c1bb96a36 100644 (file)
@@ -9,6 +9,9 @@
 
 #include "lexer.h"
 #include "vec.h"
+#include "exn.h"
+
+DECLARE_EXCEPTION(ParseException);
 
 typedef enum { ATOM, TREE } tree_tag_t;
 
@@ -34,6 +37,8 @@ lex_tok_t* parser_peek(parser_t* p_parser);
 
 bool parser_eof(parser_t* p_parser);
 
+void parser_resume(parser_t* p_parser);
+
 void parser_error(parser_t* p_parser, const char* p_text);
 
 bool parser_accept(parser_t* p_parser, lex_tok_type_t type);
index 4813dc749c0d9230053af9b7184a2a0896a8123c..0dc278547d9aae437da2e033bc962e9ef6ac19f3 100644 (file)
@@ -1,7 +1,6 @@
 #include "scanner.h"
 #include "mem.h"
 
-static void scanner_getline(scanner_t* p_scanner);
 static void scanner_skip_ws(scanner_t* p_scanner);
 static char scanner_current(scanner_t* p_scanner);
 static bool scanner_oneof(scanner_t* p_scanner, const char* p_set);
@@ -60,7 +59,7 @@ bool scanner_eol(scanner_t* p_scanner)
     return ret;
 }
 
-static void scanner_getline(scanner_t* p_scanner) {
+void scanner_getline(scanner_t* p_scanner) {
     int c;
     size_t capacity = 8;
     size_t index    = 0;
index 0cc14f12f8fe2af616c19b4972e0e3082e53f5b1..31afceabdc983f14380edfc7d79ea96ed396aa50 100644 (file)
@@ -25,4 +25,6 @@ bool scanner_eof(scanner_t* p_scanner);
 
 bool scanner_eol(scanner_t* p_scanner);
 
+void scanner_getline(scanner_t* p_scanner);
+
 #endif /* SCANNER_H */