summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <demaille@gostai.com>2009-08-12 18:00:40 +0200
committerAkim Demaille <demaille@gostai.com>2009-08-19 10:36:53 +0200
commitc4dc4c4671556643de16417a12130da93440087f (patch)
tree24ab92c1bd8585ba51a55e2694ef3584ec0d71fa
parentc67e466f9d4f63d360d82dc23b9bfffb4d846209 (diff)
downloadbison-c4dc4c4671556643de16417a12130da93440087f.tar.gz
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.
-rw-r--r--ChangeLog9
-rw-r--r--data/lalr1.cc29
-rw-r--r--tests/c++.at4
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 <demaille@gostai.com>
+
+ 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 <jdenny@clemson.edu>
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
])