mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +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>
|
2006-03-02 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
Avoid memory leaks by not invoking longjmp in yyreportAmbiguity.
|
Avoid memory leaks by not invoking longjmp in yyreportAmbiguity.
|
||||||
@@ -23,7 +32,7 @@
|
|||||||
* data/glr.c (yydestroyGLRState): In debugging output, distinguish
|
* data/glr.c (yydestroyGLRState): In debugging output, distinguish
|
||||||
between an unresolved state (non-empty chain of semantic options) and
|
between an unresolved state (non-empty chain of semantic options) and
|
||||||
an incomplete one (signaled by an empty chain).
|
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...
|
successfully or unsuccessfully resolved yyGLRState to...
|
||||||
(yyresolveValue): ... here so that yyresolveValue always leaves a
|
(yyresolveValue): ... here so that yyresolveValue always leaves a
|
||||||
yyGLRState with consistent data and thus is easier to understand.
|
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;
|
yySymbol yytoken_to_shift;
|
||||||
size_t yys;
|
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;
|
yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
|
||||||
|
|
||||||
/* yyprocessOneStack returns one of three things:
|
/* 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
|
Except in the first case, yyparse will invoke yyremoveDeletes and
|
||||||
then shift the next token onto all remaining stacks. This
|
then shift the next token onto all remaining stacks. This
|
||||||
synchronization of the shift (that is, after all preceding
|
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. */
|
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[));
|
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn]b4_lpure_args[));
|
||||||
yyremoveDeletes (&yystack);
|
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,
|
/* 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
|
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);
|
yytoken_to_shift = YYTRANSLATE (yychar);
|
||||||
yychar = YYEMPTY;
|
yychar = YYEMPTY;
|
||||||
yyposn += 1;
|
yyposn += 1;
|
||||||
for (yys = 0; yys < yyn; yys += 1)
|
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||||
{
|
{
|
||||||
int yyaction;
|
int yyaction;
|
||||||
const short int* yyconflicts;
|
const short int* yyconflicts;
|
||||||
@@ -2391,18 +2400,8 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
(unsigned long int) yys,
|
(unsigned long int) yys,
|
||||||
yystack.yytops.yystates[yys]->yylrState));
|
yystack.yytops.yystates[yys]->yylrState));
|
||||||
}
|
}
|
||||||
if (yystack.yytops.yysize == 0)
|
|
||||||
{
|
if (yystack.yytops.yysize == 1)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
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],
|
AT_DATA_GRAMMAR([glr-regr15.y],
|
||||||
[[
|
[[
|
||||||
%glr-parser
|
%glr-parser
|
||||||
%union { int dummy; }
|
|
||||||
%type <dummy> parent_rhs_before
|
|
||||||
%destructor { parent_rhs_before_value = 0; } parent_rhs_before
|
%destructor { parent_rhs_before_value = 0; } parent_rhs_before
|
||||||
|
|
||||||
%{
|
%{
|
||||||
@@ -1512,3 +1510,69 @@ AT_CHECK([[./glr-regr15]], 0, [],
|
|||||||
])
|
])
|
||||||
|
|
||||||
AT_CLEANUP
|
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