bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Re_ data_glr.c yyinitGLRStack() (fix)


From: Paul Eggert
Subject: Re: Re_ data_glr.c yyinitGLRStack() (fix)
Date: Mon, 18 Jul 2005 11:13:27 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

address@hidden writes:

> Re_ data_glr.c yyinitGLRStack() (fix)
>
> When doing this in glr.c it appears the
> ` yyStackOverflow (&yystack]b4_lpure_args[); '
> line is perfectly fine but testsuite.log does
> not show the yyparse() status expected to be 2.
>
> fix?

Thanks for reporting that.  I installed this fix.

By the way, it appears to me that there can be memory leaks in the GLR
parser if the stack overflows or the user invokes YYABORT, because
yyfreeGLRStack does not invoke yydestruct on the items remaining in
the parser stack.  Paul Hilfinger, does this diagnosis make sense to
you?


2005-07-18  Paul Eggert  <address@hidden>

        Improve tests for stack overflow in GLR parser.
        Problem reported by address@hidden
        * data/glr.c (struct yyGLRStack): Remove yyerrflag member.
        All uses removed.
        (yyStackOverflow): Just longjmp, but with value 2 so that caller
        can handle the problem.
        (YYCHK1): Use goto (a la yacc.c) rather than setting a flag.
        (yyparse): New local variable yyresult to record the result.
        Use result of setjmp to set it, rather than storing itinto
        struct.
        (yyDone): Remove label.
        (yyacceptlab, yyabortlab, yyoverflowlab, yyreturn): New labels,
        to mimic yacc.c.  Do not discard lookahead if it's EOF (possible
        if YYABORT is used).
        * tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR): Exit with
        yyparse status; put status > 1 into diagnostic.
        Check that status==2 works.
        * tests/calc.at, tests/cxx-type.at, tests/glr-regression.at:
        Use exit status 3 for failure to open (which shouldn't happen).

Index: data/glr.c
===================================================================
RCS file: /cvsroot/bison/bison/data/glr.c,v
retrieving revision 1.100
diff -p -u -r1.100 glr.c
--- data/glr.c  17 Jul 2005 07:30:38 -0000      1.100
+++ data/glr.c  18 Jul 2005 18:00:23 -0000
@@ -657,7 +657,6 @@ union yyGLRStackItem {
 };
 
 struct yyGLRStack {
-  int yyerrflag;
   int yyerrState;
 ]b4_location_if([[  /* To compute the location of the error token.  */
   yyGLRStackItem yyerror_range[3];]])[
@@ -681,7 +680,6 @@ static void yyexpandGLRStack (yyGLRStack
 static void
 yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yymsg)
 {
-  yystack->yyerrflag = 1;
   if (yymsg != NULL)
     yyerror (]b4_yyerror_args[yymsg);
   longjmp (yystack->yyexception_buffer, 1);
@@ -690,7 +688,7 @@ yyFail (yyGLRStack* yystack]b4_pure_form
 static void
 yyStackOverflow (yyGLRStack* yystack]b4_pure_formals[)
 {
-  yyFail (yystack]b4_pure_args[, "parser stack overflow");
+  longjmp (yystack->yyexception_buffer, 2);
 }
 
 #if YYDEBUG || YYERROR_VERBOSE
@@ -957,7 +955,6 @@ static void yyfreeStateSet (yyGLRStateSe
 static yybool
 yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
 {
-  yystack->yyerrflag = 0;
   yystack->yyerrState = 0;
   yynerrs = 0;
   yystack->yyspaceLeft = yysize;
@@ -1933,11 +1930,9 @@ yyrecoverSyntaxError (yyGLRStack* yystac
     default:                                                                \
       break;                                                                \
     case yyabort:                                                           \
-      yystack.yyerrflag = 1;                                                \
-      goto yyDone;                                                          \
+      goto yyabortlab;                                                      \
     case yyaccept:                                                          \
-      yystack.yyerrflag = 0;                                                \
-      goto yyDone;                                                          \
+      goto yyacceptlab;                                                        
     \
     case yyerr:                                                                
     \
       goto yyuser_error;                                                    \
     }                                                                       \
@@ -1950,6 +1945,7 @@ yyrecoverSyntaxError (yyGLRStack* yystac
 
 ]b4_c_ansi_function_def([yyparse], [int], b4_parse_param)[
 {
+  int yyresult;
   yySymbol yytoken;
   yyGLRStack yystack;
   size_t yyposn;
@@ -1984,10 +1980,13 @@ m4_popdef([b4_at_dollar])dnl
 /* Line __line__ of glr.c.  */
 b4_syncline(address@hidden@], address@hidden@])])dnl
 [
-  if (setjmp (yystack.yyexception_buffer) != 0)
-    goto yyDone;
   if (! yyinitGLRStack (&yystack, YYINITDEPTH))
-    yyStackOverflow (&yystack]b4_lpure_args[);
+    goto yyoverflowlab;
+  switch (setjmp (yystack.yyexception_buffer))
+    {
+    case 1: goto yyabortlab;
+    case 2: goto yyoverflowlab;
+    }
   yystack.yytokenp = &yytoken;
   yyglrShift (&yystack, 0, 0, 0, yylval, &yylloc]b4_user_args[);
   yyposn = 0;
@@ -2007,7 +2006,7 @@ b4_syncline(address@hidden@], address@hidden@])])dnl
          yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
           YYDPRINTF ((stderr, "Entering state %d\n", yystate));
          if (yystate == YYFINAL)
-           goto yyDone;
+           goto yyacceptlab;
          if (yyisDefaultedState (yystate))
            {
              yyrule = yydefaultAction (yystate);
@@ -2089,14 +2088,27 @@ b4_syncline(address@hidden@], address@hidden@])])dnl
       yyrecoverSyntaxError (&yystack, yylvalp, yyllocp]b4_user_args[);
       yyposn = yystack.yytops.yystates[0]->yyposn;
     }
- yyDone:
-  /* On YYABORT, free the lookahead. */
-  if (yystack.yyerrflag == 1 && yytoken != YYEMPTY)
+
+ yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+ yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+ yyoverflowlab:
+  yyerror (]b4_lyyerror_args["parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+
+ yyreturn:
+  if (yytoken != YYEOF && yytoken != YYEMPTY)
     yydestruct ("Error: discarding lookahead",
                 yytoken, yylvalp]b4_location_if([, yyllocp])[);
 
   yyfreeGLRStack (&yystack);
-  return yystack.yyerrflag;
+  return yyresult;
 }
 
 /* DEBUGGING ONLY */
Index: tests/actions.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/actions.at,v
retrieving revision 1.49
diff -p -u -r1.49 actions.at
--- tests/actions.at    14 May 2005 06:49:48 -0000      1.49
+++ tests/actions.at    18 Jul 2005 18:00:23 -0000
@@ -337,16 +337,18 @@ yyerror (const char *msg)
 int
 main (int argc, const char *argv[])
 {
+  int status;
   yydebug = !!getenv ("YYDEBUG");
   assert (argc == 2);
   yysource = argv[1];
-  if (yyparse ())
+  status = yyparse ();
+  switch (status)
     {
-      printf ("Parsing FAILED.\n");
-      exit (1);
+      case 0: printf ("Successful parse.\n"); break;
+      case 1: printf ("Parsing FAILED.\n"); break;
+      default: printf ("Parsing FAILED (status %d).\n", status); break;
     }
-  printf ("Successful parse.\n");
-  return 0;
+  return status;
 }
 ]])
 
@@ -450,7 +452,7 @@ Parsing FAILED.
 # Upon stack overflow, all symbols on the stack should be destroyed.
 # Only check for yacc.c.
 AT_YACC_IF([
-AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 1,
+AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 2,
 [[sending: '(' (address@hidden)
 sending: 'x' (address@hidden)
 thing (address@hidden): 'x' (address@hidden)
@@ -493,7 +495,7 @@ Freeing nterm line (address@hidden)
 Freeing nterm line (address@hidden)
 Freeing nterm line (address@hidden)
 Freeing nterm line (address@hidden)
-Parsing FAILED.
+Parsing FAILED (status 2).
 ]])
 ])
 
Index: tests/calc.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/calc.at,v
retrieving revision 1.74
diff -p -u -r1.74 calc.at
--- tests/calc.at       22 May 2005 05:20:01 -0000      1.74
+++ tests/calc.at       18 Jul 2005 18:00:23 -0000
@@ -288,7 +288,7 @@ power (int base, int exponent)
 {
   int res = 1;
   if (exponent < 0)
-    exit (1);
+    exit (3);
   for (/* Niente */; exponent; --exponent)
     res *= base;
   return res;
@@ -315,7 +315,7 @@ main (int argc, const char **argv)
   if (!yyin)
     {
       perror (argv[1]);
-      exit (1);
+      return 3;
     }
 
 ]AT_LALR1_CC_IF([], [m4_bmatch([$4], [%debug],
Index: tests/cxx-type.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/cxx-type.at,v
retrieving revision 1.21
diff -p -u -r1.21 cxx-type.at
--- tests/cxx-type.at   14 Jul 2005 23:15:47 -0000      1.21
+++ tests/cxx-type.at   18 Jul 2005 18:00:23 -0000
@@ -115,8 +115,8 @@ main (int argc, char **argv)
   if (argc != 2)
     abort ();
   if (!freopen (argv[1], "r", stdin))
-    abort ();
-  exit (yyparse ());
+    return 3;
+  return yyparse ();
 }
 
 int
Index: tests/glr-regression.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/glr-regression.at,v
retrieving revision 1.10
diff -p -u -r1.10 glr-regression.at
--- tests/glr-regression.at     18 Jul 2005 06:14:16 -0000      1.10
+++ tests/glr-regression.at     18 Jul 2005 18:00:23 -0000
@@ -202,7 +202,7 @@ int
 main (int argc, char **argv)
 {
   yyin = stdin;
-  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 1;
+  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3;
   return yyparse ();
 }
 ]])
@@ -312,7 +312,7 @@ int yylex (void)
 
 int main(int argc, char* argv[]) {
   yyin = stdin;
-  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 1;
+  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3;
   return yyparse ();
 }
 ]])




reply via email to

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