diff --git a/c/lexer.l b/c/lexer.l index 5ceb3a0a..9c20a953 100644 --- a/c/lexer.l +++ b/c/lexer.l @@ -39,6 +39,12 @@ yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL; } +\"(\\.|[^\\\"])* { + yylval->literal = jv_invalid_with_msg(jv_string("Unterminated string")); + return LITERAL; +} + + [[:alnum:]]+ { yylval->literal = jv_string(yytext); return IDENT;} [ \n\t]+ {} diff --git a/c/parser.y b/c/parser.y index 3d81ea4a..111d8ee7 100644 --- a/c/parser.y +++ b/c/parser.y @@ -3,7 +3,6 @@ #include #include "compile.h" %} - %code requires { #include "locfile.h" #define YYLTYPE location @@ -170,6 +169,10 @@ Term "as" '$' IDENT '|' Exp { "if" Exp "then" Exp ElseBody { $$ = gen_cond($2, $4, $5); } | +"if" Exp error { + FAIL(@$, "Possibly unterminated 'if' statment"); + $$ = $2; +} | Exp '=' Exp { block assign = gen_op_simple(DUP); @@ -188,7 +191,6 @@ Exp "and" Exp { $$ = gen_and($1, $3); } | - "not" Exp { $$ = gen_not($2); } | @@ -236,6 +238,8 @@ Term { $$ = $1; } + + ElseBody: "elif" Exp "then" Exp ElseBody { $$ = gen_cond($2, $4, $5); @@ -304,16 +308,19 @@ IDENT '(' Exp ')' { block_join($3, gen_op_simple(RET))), gen_noop(), OP_IS_CALL_PSEUDO))); jv_free($1); -} +} | +'(' error ')' { $$ = gen_noop(); } | +'[' error ']' { $$ = gen_noop(); } | +Term '[' error ']' { $$ = $1; } | +'{' error '}' { $$ = gen_noop(); } MkDict: { $$=gen_noop(); -} -| -MkDictPair -{ $$ = $1; } +} | + MkDictPair { $$ = $1; } | MkDictPair ',' MkDict { $$=block_join($1, $3); } +| error ',' MkDict { $$ = $3; } MkDictPair : IDENT ':' ExpD { @@ -332,6 +339,7 @@ MkDictPair | '(' Exp ')' ':' ExpD { $$ = gen_dictpair($2, $5); } +| '(' error ')' ':' ExpD { $$ = $5; } %% int compile(const char* str, block* answer) {