]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
fixed EOF handling
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 24 Sep 2014 02:24:11 +0000 (22:24 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 24 Sep 2014 02:24:11 +0000 (22:24 -0400)
source/sclpl/lexer.c
source/sclpl/lexer.h
source/sclpl/main.c
source/sclpl/scanner.c

index 04c92e4d46be59bc7c78c92152d913fc58295e39..452341414f2c70661946e2d318c64b72a8afef03 100644 (file)
@@ -44,15 +44,17 @@ lex_tok_t* lexer_read(lexer_t* p_lexer) {
     mpc_result_t r;
     lex_tok_t* p_tok = NULL;
     char* text = scanner_read(p_lexer->scanner);
-    if (mpc_parse("<stdin>", text, p_lexer->lexrule, &r)) {
-        mpc_ast_print(((mpc_ast_t*)r.output)->children[1]);
-        p_tok = lexer_translate( ((mpc_ast_t*)r.output)->children[1] );
-        mpc_ast_delete(r.output);
-    } else {
-        mpc_err_print(r.error);
-        mpc_err_delete(r.error);
+    if (NULL != text) {
+        if (mpc_parse("<stdin>", text, p_lexer->lexrule, &r)) {
+            mpc_ast_print(((mpc_ast_t*)r.output)->children[1]);
+            p_tok = lexer_translate( ((mpc_ast_t*)r.output)->children[1] );
+            mpc_ast_delete(r.output);
+        } else {
+            mpc_err_print(r.error);
+            mpc_err_delete(r.error);
+        }
+        free(text);
     }
-    free(text);
     return p_tok;
 }
 
index 9233b918d9bc82365e55fbff0ba6bf092cdea097..40131428b794b3f22a1941cb295a36045f14c501 100644 (file)
@@ -20,7 +20,7 @@ typedef struct {
 
 typedef enum {
     END, STRING, CHAR, INT, FLOAT, BOOL, LBRACE, RBRACE, LBRACK, RBRACK, LPAR,
-    RPAR, COMMA, VAR
+    RPAR, COMMA, VAR, END_FILE
 } lex_tok_type_t;
 
 typedef struct {
index 430c26007646c0353dc42a71d29b39ebef0635b9..43c1a11a8ef1d72addabe2c8fd0e21fc943201c1 100644 (file)
@@ -9,6 +9,8 @@ typedef struct {
     lex_tok_t* p_tok;
 } parser_t;
 
+lex_tok_t tok_eof = { END_FILE, NULL, 0, 0, NULL };
+
 parser_t* parser_new(char* p_prompt, FILE* input)
 {
     parser_t* p_parser = (parser_t*)malloc(sizeof(parser_t));
@@ -20,6 +22,8 @@ parser_t* parser_new(char* p_prompt, FILE* input)
 void parser_fetch(parser_t* p_parser)
 {
     p_parser->p_tok = lexer_read(p_parser->p_lexer);
+    if (NULL == p_parser->p_tok)
+        p_parser->p_tok = &tok_eof;
 }
 
 lex_tok_t* parser_peek(parser_t* p_parser)
@@ -29,6 +33,10 @@ lex_tok_t* parser_peek(parser_t* p_parser)
     return p_parser->p_tok;
 }
 
+bool parser_eof(parser_t* p_parser) {
+    return (parser_peek(p_parser)->type == END_FILE);
+}
+
 void parser_error(parser_t* p_parser, const char* p_text)
 {
     (void)p_parser;
@@ -193,7 +201,6 @@ void parser_fn_stmnt(parser_t* p_parser)
  *****************************************************************************/
 /* TODO:
 
-    * Gracefully handle EOF
     * Formalize grammar for parser
     * Paren for function application must be on same line as variable in REPL
     * "end" and ';' must be equivalent
@@ -209,14 +216,8 @@ int main(int argc, char **argv) {
     (void)argc;
     (void)argv;
 
-    //scanner_t* p_scanner = scanner_new(":> ", stdin);
-    //while(!scanner_eof(p_scanner)) {
-    //    printf("TOK: '%s'\n", scanner_read(p_scanner) );
-    //    puts("OK.");
-    //}
-
     parser_t* p_parser = parser_new(":> ", stdin);
-    while(true) {
+    while(!parser_eof(p_parser)) {
         parser_toplevel(p_parser);
         puts("OK.");
     }
index fcfe78f3ccc94601a36b03742fc5ecf74522a970..e6fafb40301f0fd3e1e30371865429772863c3a1 100644 (file)
@@ -89,11 +89,14 @@ static void scanner_skip_ws(scanner_t* p_scanner) {
     /* If we haven't read a line yet, read one now */
     if (NULL == p_scanner->p_line)
         scanner_getline(p_scanner);
-    while('\0' == scanner_current(p_scanner) || scanner_oneof(p_scanner, " \t\r\n")) {
-        if ('\0' == scanner_current(p_scanner) && !scanner_eof(p_scanner)) {
+    /* Fast forward past whitespace and read a newline if necessary  */
+    while(!scanner_eof(p_scanner)) {
+        if ('\0' == scanner_current(p_scanner)) {
             scanner_getline(p_scanner);
-        } else {
+        } else if (scanner_oneof(p_scanner, " \t\r\n")) {
             p_scanner->index++;
+        } else {
+            break;
         }
     }
 }