* 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:
Joel E. Denny
2006-03-04 03:29:03 +00:00
parent 35ee866a32
commit ae952af227
3 changed files with 93 additions and 21 deletions

View File

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

View File

@@ -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"));

View File

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