bison-patches
[Top][All Lists]
Advanced

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

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


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

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?

Index: ChangeLog
===================================================================
RCS file: /sources/bison/bison/ChangeLog,v
retrieving revision 1.1718
diff -p -u -r1.1718 ChangeLog
--- ChangeLog   11 Aug 2007 23:08:04 -0000      1.1718
+++ ChangeLog   12 Aug 2007 00:39:25 -0000
@@ -1,5 +1,17 @@
 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.
+       (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>
+
        * tests/push.at (Push Parsing: Memory Leak for Early Deletion): Do not
        name user variables starting with `yy'.  Just pass NULL instead of a
        dummy local &yylval to yypush_parse.
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 00:39:25 -0000
@@ -1110,14 +1110,23 @@ b4_push_if(
     yypstate_delete (yyps_local);
   return yystatus;
 }
+]])b4_pure_if([], [[
+static char yypstate_allocated = 0;
 ]])[
 /* 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 +1139,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 00:39:29 -0000
@@ -78,3 +78,64 @@ 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);
+%}
+
+%push-parser
+
+%%
+
+start: ;
+
+%%
+
+void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+main (void)
+{
+  yypstate *ps;
+  int i;
+
+  for (i = 0; i < 2; ++i)
+    {
+      ps = yypstate_new ();
+      assert (ps);
+      assert (yypstate_new() == NULL);
+      yychar = 0;
+      assert (yypush_parse (ps) == 0);
+      assert (yypstate_new() == NULL);
+      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
+]])
+
+AT_CLEANUP




reply via email to

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