bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] master: lalr1.cc: destroy $$ when YYERROR is called.


From: Akim Demaille
Subject: [PATCH] master: lalr1.cc: destroy $$ when YYERROR is called.
Date: Wed, 12 Aug 2009 18:00:40 +0200

        * 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 d201948..39575a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-08-19  Akim Demaille  <address@hidden>
+
+       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  <address@hidden>
 
        maint: update for gnulib's recent update-copyright changes
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 39167f9..365a384 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(address@hidden@}]], [yylhs.value], [build]),[
+    b4_symbol_variant(address@hidden@}]], [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 c7359d5..beffb1c 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
 ])
 
-- 
1.6.4





reply via email to

[Prev in Thread] Current Thread [Next in Thread]