diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c index 20add6f7..779c1c91 100644 --- a/data/skeletons/glr.c +++ b/data/skeletons/glr.c @@ -778,11 +778,12 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals #if YY_EXCEPTIONS } 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;])[ yyerror (]b4_lyyerror_args[yyexc.what ()); - // Map to the undef token. - *yycharp = YYMAXUTOK + 1; + // Leave yytoken/yychar to YYEMPTY. + return YYEMPTY; } #endif // YY_EXCEPTIONS]], [[ *yycharp = ]b4_lex[;]])[ @@ -871,7 +872,8 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, #if YY_EXCEPTIONS } catch (const syntax_error& yyexc) - {]b4_locations_if([ + { + YYDPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([ *yylocp = yyexc.location;])[ yyerror (]b4_yyerror_args[yyexc.what ()); YYERROR; @@ -2353,7 +2355,10 @@ b4_dollar_popdef])[]dnl else if (yyisErrorAction (yyaction)) {]b4_locations_if([[ 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; } else diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc index 58e8f897..aa777ec1 100644 --- a/data/skeletons/lalr1.cc +++ b/data/skeletons/lalr1.cc @@ -827,6 +827,7 @@ b4_dollar_popdef])[]dnl #if YY_EXCEPTIONS catch (const syntax_error& yyexc) { + YYCDEBUG << "Caught exception: " << yyexc.what() << '\n'; error (yyexc); goto yyerrlab1; } @@ -916,6 +917,7 @@ b4_dollar_popdef])[]dnl #if YY_EXCEPTIONS catch (const syntax_error& yyexc) { + YYCDEBUG << "Caught exception: " << yyexc.what() << '\n'; error (yyexc); YYERROR; } diff --git a/tests/c++.at b/tests/c++.at index c2b892bc..6b6d2e41 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -941,7 +941,7 @@ AT_CLEANUP m4_pushdef([AT_TEST], [AT_SETUP([[Syntax error as exception: $1]]) -AT_BISON_OPTION_PUSHDEFS([$1]) +AT_BISON_OPTION_PUSHDEFS([$1 %debug]) AT_DATA_GRAMMAR([[input.yy]], [[$1 @@ -984,6 +984,7 @@ yy::parser::error (const std::string &m) ]AT_MAIN_DEFINE[ ]]) +# Another file to check syntax_error's linkage. AT_DATA_SOURCE([scan.cc], [[#include "input.hh" @@ -991,7 +992,11 @@ int yylex (yy::parser::semantic_type *) { // '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++) { case 'l':