c: don't emit an error message when the scanner returns YYERRCODE

* data/skeletons/yacc.c (yyparse): When the scanner returns YYERRCODE,
go directly to error recovery (yyerrlab1).
However, don't keep the error token as lookahead, that token is too
special.
* data/skeletons/lalr1.cc: Likewise.

* examples/c/bistromathic/parse.y (yylex): Use that feature to report
nicely invalid characters.
* examples/c/bistromathic/bistromathic.test: Check that.
* examples/test: Neutralize gratuitous differences such as rule
position.

* tests/calc.at: Check that case in C only.
The other case seem to be working, but that's an illusion that the
next commit will address (in fact, they can enter endless loops, and
report the error several times anyway).
This commit is contained in:
Akim Demaille
2020-04-15 07:38:46 +02:00
parent 60366b152b
commit 58e79539fc
6 changed files with 214 additions and 22 deletions

View File

@@ -981,6 +981,16 @@ b4_dollar_popdef])[]dnl
}
YY_SYMBOL_PRINT ("Next token is", yyla);
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yyla.type = ]symbol_kind::b4_symbol(2, kind)[;
goto yyerrlab1;
}
/* If the proper action on seeing token YYLA.TYPE is to reduce or
to detect an error, take that action. */
yyn += yyla.kind ();

View File

@@ -1770,6 +1770,17 @@ yyread_pushed_token:]])[
yytoken = ]b4_symbol(0, [kind])[;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else if (yychar == ]b4_symbol(1, [id])[)
{
/* The scanner already issued an error message, process directly
to error recovery. But do not keep the error token as
lookahead, it is too special and may lead us to an endless
loop in error recovery. */
yychar = ]b4_symbol(2, [id])[;
yytoken = ]b4_symbol(1, [kind])[;]b4_locations_if([[
yyerror_range[1] = yylloc;]])[
goto yyerrlab1;
}
else
{
yytoken = YYTRANSLATE (yychar);