From 0259de8caf917f5f7f9832ffbd2616ec8f93a8c4 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 23 Sep 2014 22:24:11 -0400 Subject: [PATCH] fixed EOF handling --- source/sclpl/lexer.c | 18 ++++++++++-------- source/sclpl/lexer.h | 2 +- source/sclpl/main.c | 17 +++++++++-------- source/sclpl/scanner.c | 9 ++++++--- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/source/sclpl/lexer.c b/source/sclpl/lexer.c index 04c92e4..4523414 100644 --- a/source/sclpl/lexer.c +++ b/source/sclpl/lexer.c @@ -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("", 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("", 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; } diff --git a/source/sclpl/lexer.h b/source/sclpl/lexer.h index 9233b91..4013142 100644 --- a/source/sclpl/lexer.h +++ b/source/sclpl/lexer.h @@ -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 { diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 430c260..43c1a11 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -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."); } diff --git a/source/sclpl/scanner.c b/source/sclpl/scanner.c index fcfe78f..e6fafb4 100644 --- a/source/sclpl/scanner.c +++ b/source/sclpl/scanner.c @@ -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; } } } -- 2.52.0