bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]