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.
This commit is contained in:
Paul Eggert
2005-07-19 06:56:44 +00:00
parent 6088a2a04d
commit 258b75caaa
8 changed files with 90 additions and 67 deletions

View File

@@ -1,5 +1,24 @@
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.

4
NEWS
View File

@@ -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.
* 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

View File

@@ -1846,21 +1846,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
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
@@ -2122,6 +2108,19 @@ b4_syncline([@oline@], [@ofile@])])dnl
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;
}

View File

@@ -729,23 +729,11 @@ yyerrlab:
/* 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
{
@@ -768,7 +756,7 @@ yyerrorlab:
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_);
@@ -838,6 +826,16 @@ yyabortlab:
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_;
}

View File

@@ -1220,8 +1220,7 @@ yyerrlab:
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;
}
@@ -1333,16 +1332,12 @@ yyreturn:
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);

View File

@@ -3792,28 +3792,31 @@ For instance, if your locations use a file name, you may use
@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.
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.
The @code{%destructor} directive allows for the definition of code that
is called when a symbol is thrown away.
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
@@ -3830,7 +3833,7 @@ For instance:
@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
@@ -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
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
@@ -4085,7 +4091,7 @@ above-mentioned declarations and to the token type codes.
@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
@@ -7821,7 +7827,7 @@ Bison declaration to create a header file meant for the scanner.
@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

View 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)
Freeing nterm input (2@0-29)
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)
Freeing nterm input (2@0-29)
Successful parse.
]])

View File

@@ -463,7 +463,7 @@ _AT_CHECK_CALC([$1],
2^2^3 = 256
(2^2)^3 = 64],
[570])
[571])
# 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],
[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 '!'
@@ -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.
_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])