[Top][All Lists]
[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
- Re: push parser documentation, (continued)
- Re: push parser documentation, Bob Rossi, 2007/08/06
- Re: push parser documentation, Bob Rossi, 2007/08/06
- Re: push parser documentation, Joel E. Denny, 2007/08/11
- Re: push parser documentation, Joel E. Denny, 2007/08/11
- Re: push parser documentation, Bob Rossi, 2007/08/12
- Re: push parser documentation, Joel E. Denny, 2007/08/17
- Re: push parser documentation, Bob Rossi, 2007/08/22
- Re: push parser documentation, Joel E. Denny, 2007/08/22
- Re: push parser documentation, Bob Rossi, 2007/08/22
multiple impure push parsers (was: Re: push parser documentation), Joel E. Denny, 2007/08/11