how: fix multi-line incomplete strings

Location tracking was incorrect for multi-line
strings/comments/parentheses.  This also fixes and tests recovery on
inclosed strings/comments/parentheses.

* src/hoaparse/hoaparse.yy: Abort on expected EOF.
* src/hoaparse/hoascan.ll: Track newlines inside strings and comments.
Do not use unput() to close incomplete parentheses.
* src/tgbatest/neverclaimread.test, src/tgbatest/hoaparse.test: Add
more tests.
This commit is contained in:
Alexandre Duret-Lutz 2014-12-04 09:55:00 +01:00
parent ebc3d64927
commit ad77145496
4 changed files with 82 additions and 30 deletions

View file

@ -203,8 +203,11 @@
%%
aut: aut-1 { res.h->loc = @$; YYACCEPT; }
| ENDOFFILE { YYABORT; }
| error ENDOFFILE { YYABORT; }
aut-1: hoa
| never
aut-1: hoa | never
/**********************************************************************/
/* Rules for HOA */
@ -212,7 +215,6 @@ aut-1: hoa | never
hoa: header "--BODY--" body "--END--"
hoa: error "--END--"
hoa: error ENDOFFILE
string_opt: | STRING
BOOLEAN: 't' | 'f'

View file

@ -149,9 +149,11 @@ identifier [[:alpha:]_][[:alnum:]_-]*
[^*/\n]* continue;
"/"[^*\n]* continue;
"*"+[^*/\n]* continue;
"\n"+ yylloc->end.column = 1; yylloc->lines(yyleng);
{eol} yylloc->lines(yyleng); yylloc->end.column = 1;
{eol2} yylloc->lines(yyleng / 2); yylloc->end.column = 1;
"*"+"/" if (--comment_level == 0) BEGIN(orig_cond);
<<EOF>> {
BEGIN(orig_cond);
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"unclosed comment"));
@ -165,26 +167,36 @@ identifier [[:alpha:]_][[:alnum:]_-]*
yylval->str = new std::string(s);
return token::STRING;
}
{eol} {
s.append(yytext, yyleng);
yylloc->lines(yyleng); yylloc->end.column = 1;
}
{eol2} {
s.append(yytext, yyleng);
yylloc->lines(yyleng / 2); yylloc->end.column = 1;
}
\\. s += yytext[1];
[^\\\"]+ s.append(yytext, yyleng);
[^\\\"\n\r]+ s.append(yytext, yyleng);
<<EOF>> {
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"unclosed string"));
return 0;
BEGIN(orig_cond);
yylval->str = new std::string(s);
return token::STRING;
}
}
<in_NEVER_PAR>{
"(" {
"(" {
++parent_level;
yylval->str->append(yytext, yyleng);
}
/* if we match ")&&(" or ")||(", stay in <in_NEVER_PAR> mode */
")"[ \t]*("&&"|"||")[ \t!]*"(" {
/* if we match ")&&(" or ")||(", stay in <in_NEVER_PAR> mode */
")"[ \t]*("&&"|"||")[ \t!]*"(" {
yylval->str->append(yytext, yyleng);
}
")" {
")" {
yylval->str->append(yytext, yyleng);
if (!--parent_level)
{
@ -193,14 +205,23 @@ identifier [[:alpha:]_][[:alnum:]_-]*
return token::FORMULA;
}
}
[^()]+ yylval->str->append(yytext, yyleng);
<<EOF>> {
unput(')');
if (!missing_parent)
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"missing closing parenthese"));
missing_parent = true;
{eol} {
yylval->str->append(yytext, yyleng);
yylloc->lines(yyleng); yylloc->end.column = 1;
}
{eol2} {
yylval->str->append(yytext, yyleng);
yylloc->lines(yyleng / 2); yylloc->end.column = 1;
}
[^()\n\r]+ yylval->str->append(yytext, yyleng);
<<EOF>> {
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"missing closing parenthese"));
yylval->str->append(parent_level, ')');
BEGIN(in_NEVER);
spot::trim(*yylval->str);
return token::FORMULA;
}
}