mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
yysyntax_error: fix for consistent error with lookahead.
* NEWS (2.5): Document. * data/yacc.c (yysyntax_error): In a verbose syntax error message while in a consistent state with a default action (which must be an error action given that yysyntax_error is being invoked), continue to drop the expected token list, but don't drop the unexpected token unless there actually is no lookahead. Moreover, handle that internally instead of returning 1 to tell the caller to do it. With that meaning of 1 gone, renumber return codes more usefully. (yyparse, yypush_parse): Update yysyntax_error usage. Most importantly, set yytoken to YYEMPTY when there's no lookahead. * data/glr.c (yyreportSyntaxError): As in yacc.c, don't drop the unexpected token unless there actually is no lookahead. * data/lalr1.cc (yy::parser::parse): If there's no lookahead, pass yyempty_ not yyla.type to yysyntax_error_. (yy::parser::yysyntax_error_): Again, don't drop the unexpected token unless there actually is no lookahead. * data/lalr1.java (YYParser::parse): If there's no lookahead, set yytoken to yyempty_ before invoking yysyntax_error. (YYParser::yysyntax_error): Again, don't drop the unexpected token unless there actually is no lookahead. * tests/conflicts.at (parse.error=verbose and consistent errors): Extend test group to further reveal how the previous use of the simple "syntax error" message was too general. Test yacc.c, glr.c, lalr1.cc, and lalr1.java. No longer an expected failure. * tests/java.at (AT_JAVA_COMPILE, AT_JAVA_PARSER_CHECK): Move to... * tests/local.at: ... here. (_AT_BISON_OPTION_PUSHDEFS): Push AT_SKEL_JAVA_IF definition. (AT_BISON_OPTION_POPDEFS): Pop it. (AT_FULL_COMPILE): Extend to handle Java.
This commit is contained in:
@@ -627,6 +627,8 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
if (yyerrstatus_ == 0)
|
||||
{
|
||||
++yynerrs_;
|
||||
if (yychar == yyempty_)
|
||||
yytoken = yyempty_;
|
||||
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
|
||||
}
|
||||
|
||||
@@ -727,17 +729,52 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
{]b4_error_verbose_if([[
|
||||
if (yyErrorVerbose)
|
||||
{
|
||||
int yyn = yypact_[yystate];
|
||||
if (yypact_ninf_ < yyn && yyn <= yylast_)
|
||||
/* There are many possibilities here to consider:
|
||||
- Assume YYFAIL is not used. It's too flawed to consider.
|
||||
See
|
||||
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
|
||||
for details. YYERROR is fine as it does not invoke this
|
||||
function.
|
||||
- If this state is a consistent state with a default action,
|
||||
then the only way this function was invoked is if the
|
||||
default action is an error action. In that case, don't
|
||||
check for expected tokens because there are none.
|
||||
- The only way there can be no lookahead present (in tok) is
|
||||
if this state is a consistent state with a default action.
|
||||
Thus, detecting the absence of a lookahead is sufficient to
|
||||
determine that there is no unexpected or expected token to
|
||||
report. In that case, just report a simple "syntax error".
|
||||
- Don't assume there isn't a lookahead just because this
|
||||
state is a consistent state with a default action. There
|
||||
might have been a previous inconsistent state, consistent
|
||||
state with a non-default action, or user semantic action
|
||||
that manipulated yychar. (However, yychar is currently out
|
||||
of scope during semantic actions.)
|
||||
- Of course, the expected token list depends on states to
|
||||
have correct lookahead information, and it depends on the
|
||||
parser not to perform extra reductions after fetching a
|
||||
lookahead from the scanner and before detecting a syntax
|
||||
error. Thus, state merging (from LALR or IELR) and default
|
||||
reductions corrupt the expected token list. However, the
|
||||
list is correct for canonical LR with one exception: it
|
||||
will still contain any token that will not be accepted due
|
||||
to an error action in a later state.
|
||||
*/
|
||||
if (tok != yyempty_)
|
||||
{
|
||||
StringBuffer res;
|
||||
|
||||
// FIXME: This method of building the message is not compatible
|
||||
// with internationalization.
|
||||
StringBuffer res =
|
||||
new StringBuffer ("syntax error, unexpected ");
|
||||
res.append (yytnamerr_ (yytname_[tok]));
|
||||
int yyn = yypact_[yystate];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
{
|
||||
/* Start YYX at -YYN if negative to avoid negative
|
||||
indexes in YYCHECK. In other words, skip the first
|
||||
-YYN actions for this state because they are default
|
||||
actions. */
|
||||
int yyxbegin = yyn < 0 ? -yyn : 0;
|
||||
|
||||
/* Stay within bounds of both yycheck and yytname. */
|
||||
int yychecklim = yylast_ - yyn + 1;
|
||||
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
|
||||
@@ -746,11 +783,6 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
if (yycheck_[x + yyn] == x && x != yyterror_
|
||||
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||
++count;
|
||||
|
||||
// FIXME: This method of building the message is not compatible
|
||||
// with internationalization.
|
||||
res = new StringBuffer ("syntax error, unexpected ");
|
||||
res.append (yytnamerr_ (yytname_[tok]));
|
||||
if (count < 5)
|
||||
{
|
||||
count = 0;
|
||||
@@ -762,6 +794,7 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
res.append (yytnamerr_ (yytname_[x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.toString ();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user