]> git.saurik.com Git - bison.git/commitdiff
Destructor cleanups and regularization among the three skeletons.
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 19 Jul 2005 06:56:44 +0000 (06:56 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 19 Jul 2005 06:56:44 +0000 (06:56 +0000)
* NEWS: Document the behavior changes.
* data/glr.c (yyrecoverSyntaxError): Don't bother to pop the
stack before failing, as the cleanup code will do it for us now.
* data/lalr1.cc (yyerrlab): Likewise.
* data/glr.c (yyparse): Pop everything off the stack before
freeing it, so that destructors get called properly.
* data/lalr1.cc (yyreturn): Likewise.
* data/yacc.c (yyreturn): Pop and destroy the start symbol, too.
This is more consistent.
* doc/bison.texinfo (Destructor Decl): Mention more reasons
why destructors might be called.  1.875 -> 2.1.
(Destructor Decl, Decl Summary, Table of Symbols):
Some English-language cleanups for %destructor.
* tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR):
Add output line for destructor of start symbol.
* tests/calc.at (AT_CHECK_CALC): Add one to line counts,
because of that same extra output line.

ChangeLog
NEWS
data/glr.c
data/lalr1.cc
data/yacc.c
doc/bison.texinfo
tests/actions.at
tests/calc.at

index fca000221368bd7a6c1a0826ff9c1575ab6224bb..65d48d6464c2ac193ff868b3c2c67b90d5477c38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2005-07-18  Paul Eggert  <eggert@cs.ucla.edu>
 
 2005-07-18  Paul Eggert  <eggert@cs.ucla.edu>
 
+       Destructor cleanups and regularization among the three skeletons.
+       * NEWS: Document the behavior changes.
+       * data/glr.c (yyrecoverSyntaxError): Don't bother to pop the
+       stack before failing, as the cleanup code will do it for us now.
+       * data/lalr1.cc (yyerrlab): Likewise.
+       * data/glr.c (yyparse): Pop everything off the stack before
+       freeing it, so that destructors get called properly.
+       * data/lalr1.cc (yyreturn): Likewise.
+       * data/yacc.c (yyreturn): Pop and destroy the start symbol, too.
+       This is more consistent.
+       * doc/bison.texinfo (Destructor Decl): Mention more reasons
+       why destructors might be called.  1.875 -> 2.1.
+       (Destructor Decl, Decl Summary, Table of Symbols):
+       Some English-language cleanups for %destructor.
+       * tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR):
+       Add output line for destructor of start symbol.
+       * tests/calc.at (AT_CHECK_CALC): Add one to line counts,
+       because of that same extra output line.
+
        * NEWS: Document minor wording changes in diagnostics of
        Bison-generated parsers.
        * data/glr.c (yyMemoryExhausted): Renamed from yyStackOverflow.
        * NEWS: Document minor wording changes in diagnostics of
        Bison-generated parsers.
        * data/glr.c (yyMemoryExhausted): Renamed from yyStackOverflow.
diff --git a/NEWS b/NEWS
index 52064e7f22c21b0dd56c36220b489e8674cb9a47..ac3587ebf4a0fcda0dfeda0a7c43c57e50379afd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@ Changes in the next version (not yet released):
   has replaced "parser stack overflow", as the old message was not
   always accurate for modern Bison-generated parsers.
 
   has replaced "parser stack overflow", as the old message was not
   always accurate for modern Bison-generated parsers.
 
+* Destructors are now called when the parser aborts, for all symbols left
+  behind on the stack.  Also, the start symbol is now destroyed after a
+  successful parse.  In both cases, the behavior was formerly inconsistent.
+
 The following change was also in version 2.0a, 2005-05-22:
 
 * When generating verbose diagnostics, Bison-generated parsers no longer
 The following change was also in version 2.0a, 2005-05-22:
 
 * When generating verbose diagnostics, Bison-generated parsers no longer
index a137bbf779e5bd26429d662bc17f13ba3ee04713..9cfaba6c681223bd9093fdd0a6d9bacc5a1309bf 100644 (file)
@@ -1846,21 +1846,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
     while (yytrue)
       {
        if (*yytokenp == YYEOF)
     while (yytrue)
       {
        if (*yytokenp == YYEOF)
-         {
-           /* Now pop stack until empty and fail. */
-           while (yystack->yytops.yystates[0] != NULL)
-             {
-               yyGLRState *yys = yystack->yytops.yystates[0];
-]b4_location_if([[             yystack->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
-               yydestruct ("Error: popping",
-                            yystos[yys->yylrState],
-                           &yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[);
-               yystack->yytops.yystates[0] = yys->yypred;
-               yystack->yynextFree -= 1;
-               yystack->yyspaceLeft += 1;
-             }
-           yyFail (yystack][]b4_lpure_args[, NULL);
-         }
+         yyFail (yystack][]b4_lpure_args[, NULL);
        if (*yytokenp != YYEMPTY)
          {]b4_location_if([[
            /* We throw away the lookahead, but the error range
        if (*yytokenp != YYEMPTY)
          {]b4_location_if([[
            /* We throw away the lookahead, but the error range
@@ -2122,6 +2108,19 @@ b4_syncline([@oline@], [@ofile@])])dnl
     yydestruct ("Error: discarding lookahead",
                 yytoken, yylvalp]b4_location_if([, yyllocp])[);
 
     yydestruct ("Error: discarding lookahead",
                 yytoken, yylvalp]b4_location_if([, yyllocp])[);
 
+  /* Now pop stack until empty, destroying its entries as we go.  */
+  while (yystack.yytops.yystates[0] != NULL)
+    {
+      yyGLRState *yys = yystack.yytops.yystates[0];
+]b4_location_if([[      yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
+      yydestruct ("Error: popping",
+                 yystos[yys->yylrState],
+                 &yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[);
+      yystack.yytops.yystates[0] = yys->yypred;
+      yystack.yynextFree -= 1;
+      yystack.yyspaceLeft += 1;
+    }
+
   yyfreeGLRStack (&yystack);
   return yyresult;
 }
   yyfreeGLRStack (&yystack);
   return yyresult;
 }
index e42a2e5da9a2148ecbd5acf8d754d5d1cb6d9a15..26fb920c264e050b6deef33f8cc3aee9c09617e4 100644 (file)
@@ -729,23 +729,11 @@ yyerrlab:
       /* If just tried and failed to reuse look-ahead token after an
         error, discard it.  */
 
       /* If just tried and failed to reuse look-ahead token after an
         error, discard it.  */
 
-      /* Return failure if at end of input.  */
       if (yylooka_ <= yyeof_)
         {
       if (yylooka_ <= yyeof_)
         {
-          /* If at end of input, pop the error token,
-            then the rest of the stack, then return failure.  */
+         /* Return failure if at end of input.  */
          if (yylooka_ == yyeof_)
          if (yylooka_ == yyeof_)
-            for (;;)
-              {
-                 yyerror_range_[0] = yylocation_stack_[0];
-                 yypop_ ();
-                if (yystate_stack_.height () == 1)
-                  YYABORT;
-                 yydestruct_ ("Error: popping",
-                              yystos_[yystate_stack_[0]],
-                              &yysemantic_stack_[0],
-                              &yylocation_stack_[0]);
-              }
+           YYABORT;
         }
       else
         {
         }
       else
         {
@@ -768,7 +756,7 @@ yyerrorlab:
      YYERROR and the label yyerrorlab therefore never appears in user
      code.  */
   if (false)
      YYERROR and the label yyerrorlab therefore never appears in user
      code.  */
   if (false)
-     goto yyerrorlab;
+    goto yyerrorlab;
 
   yyerror_range_[0] = yylocation_stack_[yylen_ - 1];
   yypop_ (yylen_);
 
   yyerror_range_[0] = yylocation_stack_[yylen_ - 1];
   yypop_ (yylen_);
@@ -838,6 +826,16 @@ yyabortlab:
 yyreturn:
   if (yylooka_ != yyeof_ && yylooka_ != yyempty_)
     yydestruct_ ("Error: discarding lookahead", yyilooka_, &yylval, &yylloc);
 yyreturn:
   if (yylooka_ != yyeof_ && yylooka_ != yyempty_)
     yydestruct_ ("Error: discarding lookahead", yyilooka_, &yylval, &yylloc);
+
+  while (yystate_stack_.height () != 1)
+    {
+      yydestruct_ ("Error: popping",
+                  yystos_[yystate_stack_[0]],
+                  &yysemantic_stack_[0],
+                  &yylocation_stack_[0]);
+      yypop_ ();
+    }
+
   return yyresult_;
 }
 
   return yyresult_;
 }
 
index a9c3cf0ef6756b3d5907d6ce32785b759a12beb3..c046e5e20c354f0c166625672f81ece30d512f92 100644 (file)
@@ -1220,8 +1220,7 @@ yyerrlab:
 
       if (yychar <= YYEOF)
         {
 
       if (yychar <= YYEOF)
         {
-          /* If at end of input, pop the error token,
-            then the rest of the stack, then return failure.  */
+         /* Return failure if at end of input.  */
          if (yychar == YYEOF)
            YYABORT;
         }
          if (yychar == YYEOF)
            YYABORT;
         }
@@ -1333,16 +1332,12 @@ yyreturn:
   if (yychar != YYEOF && yychar != YYEMPTY)
      yydestruct ("Error: discarding lookahead",
                 yytoken, &yylval]b4_location_if([, &yylloc])[);
   if (yychar != YYEOF && yychar != YYEMPTY)
      yydestruct ("Error: discarding lookahead",
                 yytoken, &yylval]b4_location_if([, &yylloc])[);
-  if (yyssp != yyss)
-    for (;;)
-      {
-]b4_location_if([[     yyerror_range[0] = *yylsp;]])[
-       YYPOPSTACK;
-       if (yyssp == yyss)
-         break;
-       yydestruct ("Error: popping",
-                   yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
-      }
+  while (yyssp != yyss)
+    {
+      yydestruct ("Error: popping",
+                 yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
+      YYPOPSTACK;
+    }
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
index 5f6f597a81e0d78497da093d89eae6797a8f3ceb..6198c280468a3de932122bfefedecee2439996e2 100644 (file)
@@ -3792,28 +3792,31 @@ For instance, if your locations use a file name, you may use
 @cindex freeing discarded symbols
 @findex %destructor
 
 @cindex freeing discarded symbols
 @findex %destructor
 
-Some symbols can be discarded by the parser.  For instance, during error
-recovery (@pxref{Error Recovery}), embarrassing symbols already pushed
-on the stack, and embarrassing tokens coming from the rest of the file
-are thrown away until the parser falls on its feet.  If these symbols
-convey heap based information, this memory is lost.  While this behavior
-can be tolerable for batch parsers, such as in compilers, it is not for
-possibly ``never ending'' parsers such as shells, or implementations of
-communication protocols.
-
-The @code{%destructor} directive allows for the definition of code that
-is called when a symbol is thrown away.
+Some symbols can be discarded by the parser.  During error
+recovery (@pxref{Error Recovery}), symbols already pushed
+on the stack and tokens coming from the rest of the file
+are discarded until the parser falls on its feet.  If the parser
+runs out of memory, all the symbols on the stack must be discarded.
+Even if the parser succeeds, it must discard the start symbol.
+
+When discarded symbols convey heap based information, this memory is
+lost.  While this behavior can be tolerable for batch parsers, such as
+in traditional compilers, it is unacceptable for programs like shells
+or protocol implementations that may parse and execute indefinitely.
+
+The @code{%destructor} directive defines code that
+is called when a symbol is discarded.
 
 @deffn {Directive} %destructor @{ @var{code} @} @var{symbols}
 @findex %destructor
 
 @deffn {Directive} %destructor @{ @var{code} @} @var{symbols}
 @findex %destructor
-Declare that the @var{code} must be invoked for each of the
-@var{symbols} that will be discarded by the parser.  The @var{code}
-should use @code{$$} to designate the semantic value associated to the
-@var{symbols}.  The additional parser parameters are also available
+Invoke @var{code} whenever the parser discards one of the
+@var{symbols}.  Within @var{code}, @code{$$} designates the semantic
+value associated with the discarded symbol.  The additional
+parser parameters are also available
 (@pxref{Parser Function, , The Parser Function @code{yyparse}}).
 
 (@pxref{Parser Function, , The Parser Function @code{yyparse}}).
 
-@strong{Warning:} as of Bison 1.875, this feature is still considered as
-experimental, as there was not enough user feedback.  In particular,
+@strong{Warning:} as of Bison 2.1, this feature is still
+experimental, as there has not been enough user feedback.  In particular,
 the syntax might still change.
 @end deffn
 
 the syntax might still change.
 @end deffn
 
@@ -3830,7 +3833,7 @@ For instance:
 @end smallexample
 
 @noindent
 @end smallexample
 
 @noindent
-guarantees that when a @code{STRING} or a @code{string} will be discarded,
+guarantees that when a @code{STRING} or a @code{string} is discarded,
 its associated memory will be freed.
 
 Note that in the future, Bison might also consider that right hand side
 its associated memory will be freed.
 
 Note that in the future, Bison might also consider that right hand side
@@ -3862,8 +3865,11 @@ stacked symbols popped during the first phase of error recovery,
 @item
 incoming terminals during the second phase of error recovery,
 @item
 @item
 incoming terminals during the second phase of error recovery,
 @item
-the current look-ahead when the parser aborts (either via an explicit
-call to @code{YYABORT}, or as a consequence of a failed error recovery).
+the current look-ahead and the entire stack when the parser aborts
+(either via an explicit call to @code{YYABORT}, or as a consequence of
+a failed error recovery or of memory exhaustion), and
+@item
+the start symbol, when the parser succeeds.
 @end itemize
 
 
 @end itemize
 
 
@@ -4085,7 +4091,7 @@ above-mentioned declarations and to the token type codes.
 @end deffn
 
 @deffn {Directive} %destructor
 @end deffn
 
 @deffn {Directive} %destructor
-Specifying how the parser should reclaim the memory associated to
+Specify how the parser should reclaim the memory associated to
 discarded symbols.  @xref{Destructor Decl, , Freeing Discarded Symbols}.
 @end deffn
 
 discarded symbols.  @xref{Destructor Decl, , Freeing Discarded Symbols}.
 @end deffn
 
@@ -7821,7 +7827,7 @@ Bison declaration to create a header file meant for the scanner.
 @end deffn
 
 @deffn {Directive} %destructor
 @end deffn
 
 @deffn {Directive} %destructor
-Specifying how the parser should reclaim the memory associated to
+Specify how the parser should reclaim the memory associated to
 discarded symbols.  @xref{Destructor Decl, , Freeing Discarded Symbols}.
 @end deffn
 
 discarded symbols.  @xref{Destructor Decl, , Freeing Discarded Symbols}.
 @end deffn
 
index 8ca7966982ed2c5a85db3e013bd7b217ca4ba232..7d7109f97dfbad4405faa827d631d49f298c45a8 100644 (file)
@@ -373,6 +373,7 @@ line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
 sending: EOF (3@30-39)
 input (0@29-29): /* Nothing */
 input (2@0-29): line (0@0-29) input (0@29-29)
 sending: EOF (3@30-39)
 input (0@29-29): /* Nothing */
 input (2@0-29): line (0@0-29) input (0@29-29)
+Freeing nterm input (2@0-29)
 Successful parse.
 ]])
 
 Successful parse.
 ]])
 
@@ -391,6 +392,7 @@ line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29)
 sending: EOF (3@30-39)
 input (0@29-29): /* Nothing */
 input (2@0-29): line (-1@0-29) input (0@29-29)
 sending: EOF (3@30-39)
 input (0@29-29): /* Nothing */
 input (2@0-29): line (-1@0-29) input (0@29-29)
+Freeing nterm input (2@0-29)
 Successful parse.
 ]])
 
 Successful parse.
 ]])
 
index 65148fc90af9999633d2321090fb052819644063..69b919643ae393657c672ab7f04c484bbf0af104 100644 (file)
@@ -463,7 +463,7 @@ _AT_CHECK_CALC([$1],
 
 2^2^3 = 256
 (2^2)^3 = 64],
 
 2^2^3 = 256
 (2^2)^3 = 64],
-               [570])
+               [571])
 
 # Some syntax errors.
 _AT_CHECK_CALC_ERROR([$1], [1], [0 0], [13],
 
 # Some syntax errors.
 _AT_CHECK_CALC_ERROR([$1], [1], [0 0], [13],
@@ -501,7 +501,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
 #
 _AT_CHECK_CALC_ERROR([$1], [0],
                      [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
 #
 _AT_CHECK_CALC_ERROR([$1], [0],
                      [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
-                     [188],
+                     [189],
 [1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 [1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
@@ -510,10 +510,10 @@ calc: error: 4444 != 1])
 
 # The same, but this time exercising explicitly triggered syntax errors.
 # POSIX says the look-ahead causing the error should not be discarded.
 
 # The same, but this time exercising explicitly triggered syntax errors.
 # POSIX says the look-ahead causing the error should not be discarded.
-_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [75],
+_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [76],
 [1.9: syntax error, unexpected number
 calc: error: 2222 != 1])
 [1.9: syntax error, unexpected number
 calc: error: 2222 != 1])
-_AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (0 0) = 1], [85],
+_AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (0 0) = 1], [86],
 [1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 1.11: syntax error, unexpected number
 calc: error: 2222 != 1])
 [1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 1.11: syntax error, unexpected number
 calc: error: 2222 != 1])