mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-17 08:13:02 +00:00
glr.cc: don't issue two error messages when syntax_error is thrown
Reported by Askar Safin. https://lists.gnu.org/archive/html/bison-patches/2019-01/msg00000.html * data/skeletons/glr.c (yygetToken): Return YYEMPTY when an exception is thrown. * data/skeletons/lalr1.cc: Log when an exception is caught. * tests/c++.at (Syntax error as exception): Be sure to recover from error before triggering another error.
This commit is contained in:
@@ -778,11 +778,12 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
|
|||||||
#if YY_EXCEPTIONS
|
#if YY_EXCEPTIONS
|
||||||
}
|
}
|
||||||
catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
|
catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
|
||||||
{]b4_locations_if([
|
{
|
||||||
|
YYDPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([
|
||||||
yylloc = yyexc.location;])[
|
yylloc = yyexc.location;])[
|
||||||
yyerror (]b4_lyyerror_args[yyexc.what ());
|
yyerror (]b4_lyyerror_args[yyexc.what ());
|
||||||
// Map to the undef token.
|
// Leave yytoken/yychar to YYEMPTY.
|
||||||
*yycharp = YYMAXUTOK + 1;
|
return YYEMPTY;
|
||||||
}
|
}
|
||||||
#endif // YY_EXCEPTIONS]], [[
|
#endif // YY_EXCEPTIONS]], [[
|
||||||
*yycharp = ]b4_lex[;]])[
|
*yycharp = ]b4_lex[;]])[
|
||||||
@@ -871,7 +872,8 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
|||||||
#if YY_EXCEPTIONS
|
#if YY_EXCEPTIONS
|
||||||
}
|
}
|
||||||
catch (const syntax_error& yyexc)
|
catch (const syntax_error& yyexc)
|
||||||
{]b4_locations_if([
|
{
|
||||||
|
YYDPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([
|
||||||
*yylocp = yyexc.location;])[
|
*yylocp = yyexc.location;])[
|
||||||
yyerror (]b4_yyerror_args[yyexc.what ());
|
yyerror (]b4_yyerror_args[yyexc.what ());
|
||||||
YYERROR;
|
YYERROR;
|
||||||
@@ -2353,7 +2355,10 @@ b4_dollar_popdef])[]dnl
|
|||||||
else if (yyisErrorAction (yyaction))
|
else if (yyisErrorAction (yyaction))
|
||||||
{]b4_locations_if([[
|
{]b4_locations_if([[
|
||||||
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
|
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
|
||||||
yyreportSyntaxError (&yystack]b4_user_args[);
|
/* If yylex returned no token (YYEMPTY), it already
|
||||||
|
issued an error message. */
|
||||||
|
if (yytoken != YYEMPTY)
|
||||||
|
yyreportSyntaxError (&yystack]b4_user_args[);
|
||||||
goto yyuser_error;
|
goto yyuser_error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -827,6 +827,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
#if YY_EXCEPTIONS
|
#if YY_EXCEPTIONS
|
||||||
catch (const syntax_error& yyexc)
|
catch (const syntax_error& yyexc)
|
||||||
{
|
{
|
||||||
|
YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
|
||||||
error (yyexc);
|
error (yyexc);
|
||||||
goto yyerrlab1;
|
goto yyerrlab1;
|
||||||
}
|
}
|
||||||
@@ -916,6 +917,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
#if YY_EXCEPTIONS
|
#if YY_EXCEPTIONS
|
||||||
catch (const syntax_error& yyexc)
|
catch (const syntax_error& yyexc)
|
||||||
{
|
{
|
||||||
|
YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
|
||||||
error (yyexc);
|
error (yyexc);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -941,7 +941,7 @@ AT_CLEANUP
|
|||||||
m4_pushdef([AT_TEST],
|
m4_pushdef([AT_TEST],
|
||||||
[AT_SETUP([[Syntax error as exception: $1]])
|
[AT_SETUP([[Syntax error as exception: $1]])
|
||||||
|
|
||||||
AT_BISON_OPTION_PUSHDEFS([$1])
|
AT_BISON_OPTION_PUSHDEFS([$1 %debug])
|
||||||
|
|
||||||
AT_DATA_GRAMMAR([[input.yy]],
|
AT_DATA_GRAMMAR([[input.yy]],
|
||||||
[[$1
|
[[$1
|
||||||
@@ -984,6 +984,7 @@ yy::parser::error (const std::string &m)
|
|||||||
]AT_MAIN_DEFINE[
|
]AT_MAIN_DEFINE[
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
# Another file to check syntax_error's linkage.
|
||||||
AT_DATA_SOURCE([scan.cc],
|
AT_DATA_SOURCE([scan.cc],
|
||||||
[[#include "input.hh"
|
[[#include "input.hh"
|
||||||
|
|
||||||
@@ -991,7 +992,11 @@ int
|
|||||||
yylex (yy::parser::semantic_type *)
|
yylex (yy::parser::semantic_type *)
|
||||||
{
|
{
|
||||||
// 's': syntax error, 'l': lexical error.
|
// 's': syntax error, 'l': lexical error.
|
||||||
static char const *input = "asal";
|
//
|
||||||
|
// Leave enough valid tokens to make sure we recovered from the
|
||||||
|
// previous error, otherwise we might hide some error messages
|
||||||
|
// (discarded during error recovery).
|
||||||
|
static char const *input = "asaaalaa";
|
||||||
switch (int res = *input++)
|
switch (int res = *input++)
|
||||||
{
|
{
|
||||||
case 'l':
|
case 'l':
|
||||||
|
|||||||
Reference in New Issue
Block a user