* 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.
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.
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
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
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;
}
/* 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 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_)
- 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
{
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_);
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_;
}
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 && 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);
@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
-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}}).
-@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
@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
@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 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
@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
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.
]])
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.
]])
2^2^3 = 256
(2^2)^3 = 64],
- [570])
+ [571])
# Some syntax errors.
_AT_CHECK_CALC_ERROR([$1], [1], [0 0], [13],
#
_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 '!'
# 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])
-_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])