]> granicus.if.org Git - jq/commitdiff
More error handling in the parser.
authorStephen Dolan <mu@netsoc.tcd.ie>
Tue, 11 Sep 2012 09:12:25 +0000 (10:12 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Tue, 11 Sep 2012 09:18:18 +0000 (10:18 +0100)
Add a special case in the lexer to detect unterminated strings.
Add some error recovery in the parser for more copious error spam.

c/lexer.l
c/parser.y

index 5ceb3a0a490f08a0bf2e5430a99f145bf825560e..9c20a95302bca291aa17c0fdac1ed6818c60d29d 100644 (file)
--- a/c/lexer.l
+++ b/c/lexer.l
    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]+  {}
index 3d81ea4a4efc1cb41ef2fc9d9338dd262f49b600..111d8ee708bb9525b23ced8bf3c7b9bb4edcde3d 100644 (file)
@@ -3,7 +3,6 @@
 #include <string.h>
 #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) {