bison-patches
[Top][All Lists]
Advanced

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

Re: multiple impure push parsers (was: Re: push parser documentation)


From: Joel E. Denny
Subject: Re: multiple impure push parsers (was: Re: push parser documentation)
Date: Sat, 11 Aug 2007 22:53:51 -0400 (EDT)

On Sat, 11 Aug 2007, Joel E. Denny wrote:

> On Fri, 3 Aug 2007, Joel E. Denny wrote:
> 
> > Moreover, to keep users safe, I wonder if impure push mode should have a 
> > global variable that counts yypstate instances.  If yypstate_new detects 
> > more than 1 instance, it should invoke yyerror with a message about 
> > %pure-parser and then return NULL.
> 
> I implemented something like this in the uncommitted patch below.  Any 
> thoughts on it from anyone?

I forgot yypull_parse.  Here's a corrected version, uncommitted.

Index: ChangeLog
===================================================================
RCS file: /sources/bison/bison/ChangeLog,v
retrieving revision 1.1719
diff -p -u -r1.1719 ChangeLog
--- ChangeLog   12 Aug 2007 02:12:29 -0000      1.1719
+++ ChangeLog   12 Aug 2007 02:47:01 -0000
@@ -1,5 +1,19 @@
 2007-08-11  Joel E. Denny  <address@hidden>
 
+       In impure push mode, don't allow more than one yypstate to be allocated
+       since multiple impure parsers would corrupt yynerrs.
+       * data/push.c (yypstate_allocated): New static global variable
+       initialized to 0.
+       (yypull_parse): If yypstate_new returns 0, don't report it as memory
+       exhaustion if yypstate_allocated is 1, but still return 2.
+       (yypstate_new): Invoke yyerror and return 0 if yypstate_allocated is
+       already 1.  Otherwise, set it to 1.
+       (yypstate_delete): Set it to 0.
+       * tests/push.at (Push Parsing: Multiple impure instances): New test
+       case.
+
+2007-08-11  Joel E. Denny  <address@hidden>
+
        Get rid of broken %no-parser, -n, and --no-parser implementation and
        documentation.
        * TODO: Don't mention them.
Index: data/push.c
===================================================================
RCS file: /sources/bison/bison/data/push.c,v
retrieving revision 1.39
diff -p -u -r1.39 push.c
--- data/push.c 28 Jul 2007 04:27:32 -0000      1.39
+++ data/push.c 12 Aug 2007 02:47:01 -0000
@@ -1078,7 +1078,9 @@ b4_push_if(
 {
   return yypull_parse (0]m4_ifset([b4_parse_param],
                                   [[, ]b4_c_args(b4_parse_param)])[);
-}
+}]b4_pure_if([], [[
+
+static char yypstate_allocated = 0;]])[
 
 ]b4_c_function_def([[yypull_parse]], [[int]],
   [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
@@ -1094,8 +1096,10 @@ b4_push_if(
     {
       yyps_local = yypstate_new ();
       if (!yyps_local)
-        {
-          yyerror (]b4_yyerror_args[YY_("memory exhausted"));
+        {]b4_pure_if([[
+          yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
+          if (!yypstate_allocated)
+            yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
           return 2;
         }
     }
@@ -1114,10 +1118,17 @@ b4_push_if(
 /* Initialize the parser data structure.  */
 ]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
 {
-  yypstate *yyps = (yypstate *) malloc (sizeof *yyps);
+  yypstate *yyps;]b4_pure_if([], [[
+  if (yypstate_allocated)
+    {
+      yyerror (]b4_yyerror_args[YY_("cannot allocate multiple impure 
push-parser instances"));
+      return 0;
+    }]])[
+  yyps = (yypstate *) malloc (sizeof *yyps);
   if (!yyps)
     return 0;
-  yyps->yynew = 1;
+  yyps->yynew = 1;]b4_pure_if([], [[
+  yypstate_allocated = 1;]])[
   return yyps;
 }
 
@@ -1130,7 +1141,8 @@ b4_push_if(
   if (!yyps->yynew && yyps->yyss != yyps->yyssa)
     YYSTACK_FREE (yyps->yyss);
 #endif
-  free (yyps);
+  free (yyps);]b4_pure_if([], [[
+  yypstate_allocated = 0;]])[
 }
 
 ]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs
Index: tests/push.at
===================================================================
RCS file: /sources/bison/bison/tests/push.at,v
retrieving revision 1.2
diff -p -u -r1.2 push.at
--- tests/push.at       11 Aug 2007 23:08:04 -0000      1.2
+++ tests/push.at       12 Aug 2007 02:47:01 -0000
@@ -78,3 +78,77 @@ AT_COMPILE([[input]])
 AT_PARSER_CHECK([[./input]])
 
 AT_CLEANUP
+
+
+## ----------------------------------------- ##
+## Push Parsing: Multiple impure instances.  ##
+## ----------------------------------------- ##
+
+AT_SETUP([[Push Parsing: Multiple impure instances]])
+
+AT_DATA_GRAMMAR([[input.y]],
+[[
+%{
+  #include <assert.h>
+  #include <stdio.h>
+  void yyerror (char const *msg);
+  int yylex (void);
+%}
+
+%push-pull-parser
+
+%%
+
+start: ;
+
+%%
+
+void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+yylex (void)
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  yypstate *ps;
+  int i;
+
+  for (i = 0; i < 2; ++i)
+    {
+      ps = yypstate_new ();
+      assert (ps);
+      assert (yypstate_new () == NULL);
+      assert (yyparse () == 2);
+      yychar = 0;
+      assert (yypush_parse (ps) == 0);
+      assert (yypstate_new () == NULL);
+      assert (yyparse () == 2);
+      yypstate_delete (ps);
+    }
+
+  return 0;
+}
+]])
+
+AT_CHECK([[bison -o input.c input.y]])
+AT_COMPILE([[input]])
+AT_PARSER_CHECK([[./input]], 0, [],
+[[cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+cannot allocate multiple impure push-parser instances
+]])
+
+AT_CLEANUP




reply via email to

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