From c4dc4c4671556643de16417a12130da93440087f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 12 Aug 2009 18:00:40 +0200 Subject: [PATCH] lalr1.cc: destroy $$ when YYERROR is called. * data/lalr1.cc (yyreduce): Compute the resulting state before running the user action so that yylhs is a valid symbol. (yyerrorlab): Since yylhs is complete (it knows its type), we can simply call yy_destroy_ to destroy $$ on YYERROR invocations. * tests/c++.at (AT_CHECK_VARIANTS): Test YYERROR with variants. --- ChangeLog | 9 +++++++++ data/lalr1.cc | 29 ++++++++++++++--------------- tests/c++.at | 4 ++-- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2019480..39575a35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-08-19 Akim Demaille + + lalr1.cc: destroy $$ when YYERROR is called. + * data/lalr1.cc (yyreduce): Compute the resulting state before + running the user action so that yylhs is a valid symbol. + (yyerrorlab): Since yylhs is complete (it knows its type), we can + simply call yy_destroy_ to destroy $$ on YYERROR invocations. + * tests/c++.at (AT_CHECK_VARIANTS): Test YYERROR with variants. + 2009-08-18 Joel E. Denny maint: update for gnulib's recent update-copyright changes diff --git a/data/lalr1.cc b/data/lalr1.cc index 39167f94..365a3845 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -757,11 +757,19 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: - yylen = yyr2_[yyn];]b4_variant_if([ + yylen = yyr2_[yyn]; + // Compute post-reduction state. + yystate = yypgoto_[yyr1_[yyn] - yyntokens_] + yystack_[yylen].state; + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystack_[yylen].state) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyr1_[yyn] - yyntokens_]; + yylhs.state = yystate;]b4_variant_if([ /* Variants are always initialized to an empty instance of the correct type. The default $$=$1 action is NOT applied when using variants. */ - ]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build]),[ + b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[ /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, use the top of the stack. @@ -788,15 +796,6 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ default: break; } - // Compute post-reduction state. - yyn = yyr1_[yyn]; - yystate = yypgoto_[yyn - yyntokens_] + yystack_[yylen].state; - if (0 <= yystate && yystate <= yylast_ - && yycheck_[yystate] == yystack_[yylen].state) - yystate = yytable_[yystate]; - else - yystate = yydefgoto_[yyn - yyntokens_]; - yylhs.state = yystate; YY_SYMBOL_PRINT ("-> $$ =", yylhs); ]b4_variant_if([[ // Destroy the rhs symbols. @@ -864,10 +863,10 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ YYERROR and the label yyerrorlab therefore never appears in user code. */ if (false) - goto yyerrorlab; - -]b4_locations_if([[ - yyerror_range[0].location = yystack_[yylen - 1].location;]])[ + goto yyerrorlab;]b4_locations_if([[ + yyerror_range[0].location = yystack_[yylen - 1].location;]])b4_variant_if([[ + /* $$ was initialized before running the user action. */ + yy_destroy_ ("Error: discarding", yylhs);]])[ /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ yypop_ (yylen); diff --git a/tests/c++.at b/tests/c++.at index c7359d57..beffb1c6 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -105,11 +105,12 @@ result: list: /* nothing */ { /* Generates an empty string list */ } | list item { std::swap($][$,$][1); $$.push_back($][2); } +| list error { std::swap($][$,$][1); } ; item: TEXT { std::swap($][$,$][1); } -| NUMBER { $][$ = string_cast($][1); } +| NUMBER { if ($][1 == 3) YYERROR; else $][$ = string_cast($][1); } ; %% @@ -188,7 +189,6 @@ AT_CHECK([./list], 0, [0 1 2 -3 4 ]) -- 2.45.2