[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: Fix leaked lookahead after nondeterministic parse syntax error
From: |
Joel E. Denny |
Subject: |
FYI: Fix leaked lookahead after nondeterministic parse syntax error |
Date: |
Fri, 3 Mar 2006 22:30:46 -0500 (EST) |
2006-03-04 Joel E. Denny <address@hidden>
* 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.
Index: data/glr.c
===================================================================
RCS file: /sources/bison/bison/data/glr.c,v
retrieving revision 1.166
diff -p -u -r1.166 glr.c
--- data/glr.c 2 Mar 2006 06:18:09 -0000 1.166
+++ data/glr.c 4 Mar 2006 03:23:00 -0000
@@ -2338,9 +2338,8 @@ b4_syncline(address@hidden@], address@hidden@])])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(address@hidden@], address@hidden@])])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(address@hidden@], address@hidden@])])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(address@hidden@], address@hidden@])])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"));
Index: tests/glr-regression.at
===================================================================
RCS file: /sources/bison/bison/tests/glr-regression.at,v
retrieving revision 1.31
diff -p -u -r1.31 glr-regression.at
--- tests/glr-regression.at 2 Mar 2006 06:18:09 -0000 1.31
+++ tests/glr-regression.at 4 Mar 2006 03:23:00 -0000
@@ -1431,8 +1431,6 @@ AT_SETUP([Leaked semantic values when re
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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: Fix leaked lookahead after nondeterministic parse syntax error,
Joel E. Denny <=