]> git.saurik.com Git - bison.git/commitdiff
Improve tests for stack overflow in GLR parser.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 18 Jul 2005 18:09:40 +0000 (18:09 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 18 Jul 2005 18:09:40 +0000 (18:09 +0000)
Problem reported by twlevo@xs4all.nl.
* 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).

ChangeLog
data/glr.c
tests/actions.at
tests/calc.at
tests/cxx-type.at
tests/glr-regression.at

index 0f8d338d88ca192d4ba406cdf523e491341ce29b..a93c813cebbbab14c11705e1d813781b016e456c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2005-07-18  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Improve tests for stack overflow in GLR parser.
+       Problem reported by twlevo@xs4all.nl.
+       * 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).
+
 2005-07-17  Paul Eggert  <eggert@cs.ucla.edu>
 
        * tests/conflicts.at (%nonassoc and eof):  Don't exit with status
index f1cf4dc90c2833d02554bb7665bb41e4ed0bfda0..23f5669f3cd4f3c6ec12cede02e7e618f7d7304e 100644 (file)
@@ -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* yystack]b4_pure_formals[);
 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_formals[, const char* yymsg)
 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 (yyGLRStateSet* yyset)
 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* yystack,
     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* yystack,
 
 ]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([@oline@], [@ofile@])])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([@oline@], [@ofile@])])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([@oline@], [@ofile@])])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 7231e7e63df700a5e7a7f3128cd95ef97a0fa069..55e51c6f5f929b160bb958be99de151fb913e7f4 100644 (file)
@@ -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: '(' (0@0-9)
 sending: 'x' (1@10-19)
 thing (1@10-19): 'x' (1@10-19)
@@ -493,7 +495,7 @@ Freeing nterm line (9@90-119)
 Freeing nterm line (6@60-89)
 Freeing nterm line (3@30-59)
 Freeing nterm line (0@0-29)
-Parsing FAILED.
+Parsing FAILED (status 2).
 ]])
 ])
 
index db92f70019ec79b2c68e33087010e51d58be2cf8..65148fc90af9999633d2321090fb052819644063 100644 (file)
@@ -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 f9c093c55581fa3b867fec49471590b80ed0b503..0fcdfdb691c77b4bff33ec258e9e2d46676a5a00 100644 (file)
@@ -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 bcb7773b728d1990e91f4d45480e58e51fcc6c26..e65346247f2b083abd5f09023c610de676550485 100644 (file)
@@ -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 ();
 }
 ]])