on 2005-04-28, at 22:46:21 -0700, Paul Eggert wrote:

> Marcus Holland-Moritz <[EMAIL PROTECTED]> writes:
> 
> > When the parser detects a stack overflow, it should call
> > the cleanup actions defined via %destructor for all symbols
> > on the stack (and the symbol causing the overflow) before
> > it returns.
> 
> Yes, that sounds right.  Can you write and test a patch to data/yacc.c
> that does that?  Presumably it would be some code executed just after
> the "parser stack overflow" message, that would call yydestruct.

What about the attached patch against the CVS version of bison?

All tests still pass, and I've added a test to tests/actions.at that
forces a stack overflow and checks that all symbols are freed.

If especially the test part looks kludgy, it's probably because I've
never used m4/autotest before...

Marcus
--- bison/data/yacc.c	2005-04-25 05:14:22.000000000 +0200
+++ bison-mhx/data/yacc.c	2005-04-30 12:26:31.000000000 +0200
@@ -1316,6 +1316,18 @@
 `----------------------------------------------*/
 yyoverflowlab:
   yyerror (]b4_yyerror_args[_("parser stack overflow"));
+  yydestruct (_("Error: discarding lookahead"),
+	      yytoken, &yylval]b4_location_if([, &yylloc])[);
+  for (;;)
+    {
+]b4_location_if([[      yyerror_range[0] = *yylsp;]])[
+      YYPOPSTACK;
+      if (yyssp == yyss)
+        break;
+      yydestruct (_("Error: popping"),
+      yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
+    }
+  yychar = YYEMPTY;
   yyresult = 2;
   /* Fall through.  */
 #endif
--- bison/tests/actions.at	2004-12-20 14:56:38.000000000 +0100
+++ bison-mhx/tests/actions.at	2005-04-30 19:55:20.000000000 +0200
@@ -174,6 +174,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+
+#define YYINITDEPTH 10
+#define YYMAXDEPTH 10
 ]AT_LALR1_CC_IF(
   [#define RANGE(Location) (Location).begin.line, (Location).end.line],
   [#define RANGE(Location) (Location).first_line, (Location).last_line])
@@ -442,6 +445,58 @@
 Parsing FAILED.
 ]])
 
+# Check destruction upon stack overflow
+# -------------------------------------
+# 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,
+[[sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+line ([EMAIL PROTECTED]): '(' ([EMAIL PROTECTED]) thing ([EMAIL PROTECTED]) ')' ([EMAIL PROTECTED])
+sending: '(' ([EMAIL PROTECTED])
+sending: 'x' ([EMAIL PROTECTED])
+thing ([EMAIL PROTECTED]): 'x' ([EMAIL PROTECTED])
+sending: ')' ([EMAIL PROTECTED])
+200-209: parser stack overflow
+Freeing nterm thing ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Freeing nterm line ([EMAIL PROTECTED])
+Parsing FAILED.
+]])
+])
+
 ])
 
 
_______________________________________________
Help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison

Reply via email to