mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
* tests/glr-regression.at (Leaked semantic values when reporting
ambiguity): Remove unnecessary union and type declarations. (Leaked lookahead after nondeterministic parse syntax error): New test case. * data/glr.c (yyparse): Check for zero stacks remaining before attempting to shift the lookahead so that you don't lose it.
This commit is contained in:
11
ChangeLog
11
ChangeLog
@@ -1,3 +1,12 @@
|
||||
2006-03-04 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||
|
||||
* tests/glr-regression.at (Leaked semantic values when reporting
|
||||
ambiguity): Remove unnecessary union and type declarations.
|
||||
(Leaked lookahead after nondeterministic parse syntax error): New test
|
||||
case.
|
||||
* data/glr.c (yyparse): Check for zero stacks remaining before
|
||||
attempting to shift the lookahead so that you don't lose it.
|
||||
|
||||
2006-03-02 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||
|
||||
Avoid memory leaks by not invoking longjmp in yyreportAmbiguity.
|
||||
@@ -23,7 +32,7 @@
|
||||
* data/glr.c (yydestroyGLRState): In debugging output, distinguish
|
||||
between an unresolved state (non-empty chain of semantic options) and
|
||||
an incomplete one (signaled by an empty chain).
|
||||
(yyresolveStates): Document the interface. Move all manipulation of an
|
||||
(yyresolveStates): Document the interface. Move all manipulation of a
|
||||
successfully or unsuccessfully resolved yyGLRState to...
|
||||
(yyresolveValue): ... here so that yyresolveValue always leaves a
|
||||
yyGLRState with consistent data and thus is easier to understand.
|
||||
|
||||
35
data/glr.c
35
data/glr.c
@@ -2338,9 +2338,8 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
||||
{
|
||||
yySymbol yytoken_to_shift;
|
||||
size_t yys;
|
||||
size_t yyn = yystack.yytops.yysize;
|
||||
|
||||
for (yys = 0; yys < yyn; yys += 1)
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
|
||||
|
||||
/* yyprocessOneStack returns one of three things:
|
||||
@@ -2359,13 +2358,23 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
||||
Except in the first case, yyparse will invoke yyremoveDeletes and
|
||||
then shift the next token onto all remaining stacks. This
|
||||
synchronization of the shift (that is, after all preceding
|
||||
reductions on all stacks) helps prevents double destructor calls
|
||||
reductions on all stacks) helps prevent double destructor calls
|
||||
on yylval in the event of memory exhaustion. */
|
||||
|
||||
for (yys = 0; yys < yyn; yys += 1)
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn]b4_lpure_args[));
|
||||
yyremoveDeletes (&yystack);
|
||||
yyn = yystack.yytops.yysize;
|
||||
if (yystack.yytops.yysize == 0)
|
||||
{
|
||||
yyundeleteLastStack (&yystack);
|
||||
if (yystack.yytops.yysize == 0)
|
||||
yyFail (&yystack][]b4_lpure_args[, YY_("syntax error"));
|
||||
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
||||
]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
|
||||
yyreportSyntaxError (&yystack]b4_user_args[);
|
||||
goto yyuser_error;
|
||||
}
|
||||
|
||||
/* If any yyglrShift call fails, it will fail after shifting. Thus,
|
||||
a copy of yylval will already be on stack 0 in the event of a
|
||||
@@ -2375,7 +2384,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
||||
yytoken_to_shift = YYTRANSLATE (yychar);
|
||||
yychar = YYEMPTY;
|
||||
yyposn += 1;
|
||||
for (yys = 0; yys < yyn; yys += 1)
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
{
|
||||
int yyaction;
|
||||
const short int* yyconflicts;
|
||||
@@ -2391,18 +2400,8 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
||||
(unsigned long int) yys,
|
||||
yystack.yytops.yystates[yys]->yylrState));
|
||||
}
|
||||
if (yystack.yytops.yysize == 0)
|
||||
{
|
||||
yyundeleteLastStack (&yystack);
|
||||
if (yystack.yytops.yysize == 0)
|
||||
yyFail (&yystack][]b4_lpure_args[, YY_("syntax error"));
|
||||
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
||||
]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
|
||||
yyreportSyntaxError (&yystack]b4_user_args[);
|
||||
goto yyuser_error;
|
||||
}
|
||||
else if (yystack.yytops.yysize == 1)
|
||||
|
||||
if (yystack.yytops.yysize == 1)
|
||||
{
|
||||
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
||||
|
||||
@@ -1431,8 +1431,6 @@ AT_SETUP([Leaked semantic values when reporting ambiguity])
|
||||
AT_DATA_GRAMMAR([glr-regr15.y],
|
||||
[[
|
||||
%glr-parser
|
||||
%union { int dummy; }
|
||||
%type <dummy> parent_rhs_before
|
||||
%destructor { parent_rhs_before_value = 0; } parent_rhs_before
|
||||
|
||||
%{
|
||||
@@ -1512,3 +1510,69 @@ AT_CHECK([[./glr-regr15]], 0, [],
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------------------------------------------------------- ##
|
||||
## Leaked lookahead after nondeterministic parse syntax error. ##
|
||||
## ------------------------------------------------------------------------- ##
|
||||
|
||||
AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
|
||||
AT_DATA_GRAMMAR([glr-regr16.y],
|
||||
[[
|
||||
%glr-parser
|
||||
%destructor { lookahead_value = 0; } 'b'
|
||||
|
||||
%{
|
||||
# include <stdlib.h>
|
||||
static void yyerror (char const *);
|
||||
static int yylex (void);
|
||||
static int lookahead_value = 0;
|
||||
# define USE(val)
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
start: alt1 'a' | alt2 'a' ;
|
||||
alt1: ;
|
||||
alt2: ;
|
||||
|
||||
%%
|
||||
|
||||
static void
|
||||
yyerror (char const *msg)
|
||||
{
|
||||
fprintf (stderr, "%s\n", msg);
|
||||
}
|
||||
|
||||
static int
|
||||
yylex (void)
|
||||
{
|
||||
static const char *input = "ab";
|
||||
if (*input == 'b')
|
||||
lookahead_value = 1;
|
||||
return *input++;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int exit_status = yyparse () != 1;
|
||||
if (lookahead_value)
|
||||
{
|
||||
fprintf (stderr, "Lookahead destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
return exit_status;
|
||||
}
|
||||
]])
|
||||
|
||||
AT_CHECK([[bison -o glr-regr16.c glr-regr16.y]], 0, [],
|
||||
[glr-regr16.y: conflicts: 1 reduce/reduce
|
||||
])
|
||||
AT_COMPILE([glr-regr16])
|
||||
|
||||
AT_CHECK([[./glr-regr16]], 0, [],
|
||||
[syntax error
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
Reference in New Issue
Block a user