On Tue, Feb 07, 2006 at 08:54:55AM +0100, Akim Demaille wrote:
> >>> "Bob" == Bob Rossi <[EMAIL PROTECTED]> writes:
>
> > Hi All,
> > I found here: http://savannah.gnu.org/mail/?group=bison,
> > that this list is the appropriately place to post proposed changes to
> > bison. Well, did this simply mean patches only?
>
> > I'm interested in added support for bison to act asynchronously.
> > However, I've received no good response from the bison developers in
> > what the best way to do this would be. I could really use some help in
> > deciding what approach would be the best to take.
>
> > That is, have an entirely new skeleton, or modify either yacc.c or glr.c
> > to support this functionality. Any ideas?
>
> I would the first step would be to have some means to measure the
> performance of our parsers, especially yacc.c. Then I would try to
> modify yacc.c so that the traditional yyparse is provided in terms of
> a push parser. If there is no notable performance loss, then that's
> the way to go IMHO. Otherwise, it will be m4 fun time.
Hi Akim,
OK, I've got much more experience working with bison, although I'm sure
I still have further to go. Here's what I've accomplished.
I added the %push-parser option, so that a bison input grammar file can
ask for itself to be a push-parser. This simple enhancement to bison
already raises questions. A %push-parse and %pure-parser don't make
sense together. The local variables store in %pure-parser are already
stored in the context that is used when %push-parser is used. Is it OK
to have to competing options like this? They make sense by themselves,
but not together. Is there a precedent in bison that I can simply
follow? Possibly it should be an error to declare both of these?
Next, I'm going down the path of using Odd's patch, and trying to generate
what he had from yacc.c. This is going well, but, it really does seem kind
of ugly. There are several options:
- Take all locals in yacc.c and put them into a data structure. Then
have yypushparse (and all of yacc.c) operate on the data structure.
Build the traditional yyparse function on top of yypushparse by
declaring the data structure once, and then calling yypushparse
over and over. This would be pretty clean. However, there would be
no such thing as a non pure parser. Are non-pure parsers valuable
in any way?
- Add lot's of m4 into yacc.c which would allow me to generate what we
have now, but conditionally generate the yyparse function that would
be acceptable in push mode. This is currently what I'm doing, but
quickly get's ugly with lots of m4_push_if([..
What do you think of these 2 solutions? Am I missing a possible
solution? Basically, I'm working on the second approach now. I think
it's ugly and would prefer the first approach.
I'll show you an very unfinished patch that demonstrates the second
approach, just so you can get the feel of what I'm doing.
Thanks,
Bob Rossi
Index: data/c.m4
===================================================================
RCS file: /sources/bison/bison/data/c.m4,v
retrieving revision 1.53
diff -w -u -r1.53 c.m4
--- data/c.m4 22 Jan 2006 07:38:49 -0000 1.53
+++ data/c.m4 14 Feb 2006 01:45:07 -0000
@@ -62,6 +62,9 @@
/* Pure parsers. */
[#]define YYPURE b4_pure
+/* Push parsers. */
+[#]define YYPUSH b4_push
+
/* Using locations. */
[#]define YYLSP_NEEDED b4_locations_flag
])
@@ -185,6 +188,15 @@
[$2])])
+# b4_push_if(IF-TRUE, IF-FALSE)
+# -----------------------------
+# Expand IF-TRUE, if %push-parser, IF-FALSE otherwise.
+m4_define([b4_push_if],
+[m4_if(b4_push, [1],
+ [$1],
+ [$2])])
+
+
## ------------------------- ##
## Assigning token numbers. ##
Index: data/yacc.c
===================================================================
RCS file: /sources/bison/bison/data/yacc.c,v
retrieving revision 1.133
diff -w -u -r1.133 yacc.c
--- data/yacc.c 23 Jan 2006 08:39:52 -0000 1.133
+++ data/yacc.c 14 Feb 2006 01:45:07 -0000
@@ -115,7 +115,7 @@
# -----------------
# Expansion of @$.
m4_define([b4_lhs_location],
-[(yyloc)])
+[(]b4_yyloc()[)])
# b4_rhs_location(RULE-LENGTH, NUM)
@@ -163,6 +163,35 @@
#define yychar b4_prefix[]char
#define yydebug b4_prefix[]debug
#define yynerrs b4_prefix[]nerrs
+m4_define([b4_yystate],[b4_push_if([(pv->yystate)],yystate)])
+m4_define([b4_yyn],[b4_push_if([(pv->yyn)],yyn)])
+m4_define([b4_yyresult],[b4_push_if([(pv->yyresult)],yyresult)])
+m4_define([b4_yyerrstatus],[b4_push_if([(pv->yyerrstatus)],yyerrstatus)])
+m4_define([b4_yytoken],[b4_push_if([(pv->yytoken)],yytoken)])
+m4_define([b4_yymsgbuf],[b4_push_if([(pv->yymsgbuf)],yymsgbuf)])
+m4_define([b4_yymsg],[b4_push_if([(pv->yymsg)],yymsg)])
+m4_define([b4_yymsg_alloc],[b4_push_if([(pv->yymsg_alloc)],yymsg_alloc)])
+m4_define([b4_yyssa],[b4_push_if([(pv->yyssa)],yyssa)])
+m4_define([b4_yyss],[b4_push_if([(pv->yyss)],yyss)])
+m4_define([b4_yyssp],[b4_push_if([(pv->yyssp)],yyssp)])
+m4_define([b4_yyssa],[b4_push_if([(pv->yyssa)],yyssa)])
+m4_define([b4_yyvs],[b4_push_if([(pv->yyvs)],yyvs)])
+m4_define([b4_yyvsp],[b4_push_if([(pv->yyvsp)],yyvsp)])
+m4_define([b4_yylsa],[b4_push_if([(pv->yylsa)],yylsa)])
+m4_define([b4_yyls],[b4_push_if([(pv->yyls)],yyls)])
+m4_define([b4_yylsp],[b4_push_if([(pv->yylsp)],yylsp)])
+m4_define([b4_yyloc],[b4_push_if([(pv->yyloc)],yyloc)])
+m4_define([b4_yyerror_range],[b4_push_if([(pv->yyerror_range)],yyerror_range)])
+m4_define([b4_yystacksize],[b4_push_if([(pv->yystacksize)],yystacksize)])
+m4_define([b4_yyval],[b4_push_if([(pv->yyval)],yyval)])
+m4_define([b4_yylen],[b4_push_if([(pv->yylen)],yylen)])
+m4_define([b4_yychar],[b4_push_if([(pv->yychar)],yychar)])
+m4_define([b4_yynew],[b4_push_if([(pv->yynew)],yynew)])
+m4_define([b4_yylval],[b4_push_if([(pv->yylval)],yylval)])
+m4_define([b4_yynerrs],[b4_push_if([(pv->yynerrs)],yynerrs)])
+m4_define([b4_yylloc],[b4_push_if([(pv->yylloc)],yylloc)])
+m4_define([b4_yyinstance],[b4_push_if([(pv->yyinstance)],instance)])
+m4_define([b4_yytoken],[b4_push_if([(pv->yytoken)],yytoken)])
b4_location_if([#define yylloc b4_prefix[]lloc])])[
]b4_token_enums_defines(b4_tokens)[
@@ -322,6 +351,7 @@
# endif
# endif
+
# ifdef YYSTACK_ALLOC
/* Pacify GCC's `empty if-body' warning. */
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
@@ -416,7 +446,7 @@
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yynewbytes = ]b4_yystacksize()[ * sizeof (*Stack) +
YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
}
\
while (YYID (0))
@@ -551,8 +581,8 @@
]b4_stos[
};
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
+#define yyerrok (]b4_yyerrstatus()[ = 0)
+#define yyclearin (]b4_yychar()[ = YYEMPTY)
#define YYEMPTY (-2)
#define YYEOF 0
@@ -567,15 +597,15 @@
#define YYFAIL goto yyerrlab
-#define YYRECOVERING() (!!yyerrstatus)
+#define YYRECOVERING() (!!]b4_yyerrstatus()[)
#define YYBACKUP(Token, Value) \
do \
- if (yychar == YYEMPTY && yylen == 1) \
+ if (]b4_yychar()[ == YYEMPTY && yylen == 1) \
{ \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
+ ]b4_yychar()[ = (Token); \
+ ]b4_yylval()[ = (Value); \
+ ]b4_yytoken()[ = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -956,7 +986,10 @@
#ifdef YYPARSE_PARAM
]b4_c_function_decl([yyparse], [int],
[[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
-#else /* ! YYPARSE_PARAM */
+#elif YYPUSH/* ! YYPARSE_PARAM */
+]b4_c_function_decl([yyparse], [void],
+ [[void *pvvoid], [pvvoid]])[
+#else
]b4_c_function_decl([yyparse], [int], b4_parse_param)[
#endif /* ! YYPARSE_PARAM */
@@ -967,34 +1000,133 @@
# Declare the variables that are global, or local to YYPARSE if
# pure-parser.
m4_define([b4_declare_parser_variables],
-[/* The look-ahead symbol. */
+[b4_push_if([/* The push parser variables */
+struct yyuvars
+ {
+ int instance;
+ int yyresult;
+ int token;
+ YYSTYPE yylval;
+ ]b4_location_if([[YYLTYPE yylloc;]])[
+ };
+
+struct yypvars
+ {
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg;
+ YYSIZE_T yymsg_alloc;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[[YYINITDEPTH]];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[[YYINITDEPTH]];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+]b4_location_if(
+[[ /* The location stack. */
+ YYLTYPE yylsa[[YYINITDEPTH]];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+ YYLTYPE *yyloc;
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[[2]];]])[
+
+#define YYPOPSTACK(N) (]b4_yyvsp()[ -= (N), ]b4_yyssp()[ -=
(N)]b4_location_if([, ]b4_yylsp()[ -= (N)])[)
+
+ YYSIZE_T yystacksize;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+ int yylen;
+ /* Number of syntax errors so far. */
+ int yynerrs;
+ /* The look-ahead symbol. */
+ int yychar;
+ /* used to flag a new parser instance */
+ int yynew;
+ };],[/* The look-ahead symbol. */
int yychar;
/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
-int yynerrs;b4_location_if([
+int yynerrs;]b4_location_if([
/* Location data for the look-ahead symbol. */
YYLTYPE yylloc;])
-])
+)])
+b4_push_if([/* Init the parser data structure. Use malloc, should perhaps use a
+ system dependent equivalent function.
+ */
+void*
+yypvarsinit(void)
+{
+ struct yypvars *pv;
+ pv= (struct yypvars *) malloc(sizeof(struct yypvars));
+ pv->yytoken = 0;
+ pv->yyss = pv->yyssa;
+ pv->yyvs = pv->yyvsa;
+ ]b4_location_if([pv->yyls = pv->yylsa;])[
+ pv->yystacksize = YYINITDEPTH;
+ pv->yystate = 0;
+ pv->yyerrstatus = 0;
+ pv->yynerrs = 0;
+ pv->yychar = YYEMPTY;
+ pv->yyssp = pv->yyss;
+ pv->yyvsp = pv->yyvs;
+ pv->yynew= 1; /* this is a new instance */
+]b4_location_if([ pv->yylsp = pv->yyls;])[
+ return (void*) pv;
+}])
m4_divert_pop([KILL])dnl# ====================== End of M4 code.
b4_pure_if([],
[b4_declare_parser_variables])
-
/*----------.
| yyparse. |
`----------*/
#ifdef YYPARSE_PARAM
b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
+#elif YYPUSH/* ! YYPARSE_PARAM */
+b4_c_function_def([yyparse], [void], [[void *pvvoid], [pvvoid]])
#else /* ! YYPARSE_PARAM */
b4_c_function_def([yyparse], [int], b4_parse_param)
#endif
{[
- ]b4_pure_if([b4_declare_parser_variables])[
+ ]b4_pure_if([b4_declare_parser_variables])b4_push_if([
+ struct yypvars * pv= (struct yypvars*) pvvoid;
+
+ /* pv->yynew must be != 0 at the first call for each
+ parser instance to properly set the parser going.
+ */
+ if (pv->yynew == 0) goto gottoken;
+ pv->yynew= 0;],[
int yystate;
int yyn;
int yyresult;
@@ -1068,7 +1200,7 @@
yylloc.first_line = yylloc.last_line = 1;
yylloc.first_column = yylloc.last_column = 0;
#endif
-]])
+]])])
m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [m4_define([b4_at_dollar_used])yylloc])dnl
m4_pushdef([b4_dollar_dollar], [m4_define([b4_dollar_dollar_used])yylval])dnl
@@ -1091,77 +1223,87 @@
yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
+ ]b4_yyssp()[++;
yysetstate:
- *yyssp = yystate;
+ *]b4_yyssp()[ = ]b4_yystate()[;
- if (yyss + yystacksize - 1 <= yyssp)
+ if (]b4_yyss()[ + ]b4_yystacksize()[ - 1 <= ]b4_yyssp()[)
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = ]b4_yyssp()[ - ]b4_yyss()[ + 1;
#ifdef yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
-]b4_location_if([ YYLTYPE *yyls1 = yyls;])[
+ YYSTYPE *yyvs1 = ]b4_yyvs()[;
+ yytype_int16 *yyss1 = ]b4_yyss()[;
+]b4_location_if([ YYLTYPE *yyls1 = ]b4_yyls()[;])[
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
-]b4_location_if([ &yyls1, yysize * sizeof (*yylsp),])[
- &yystacksize);
-]b4_location_if([ yyls = yyls1;])[
- yyss = yyss1;
- yyvs = yyvs1;
+ &yyss1, yysize * sizeof (*]b4_yyssp()[),
+ &yyvs1, yysize * sizeof (*]b4_yyvsp()[),
+]b4_location_if([ &yyls1, yysize * sizeof (*]b4_yylsp()[),])[
+ &]b4_yystacksize()[);
+]b4_location_if([ ]b4_yyls()[ = yyls1;])[
+ ]b4_yyss()[ = yyss1;
+ ]b4_yyvs()[ = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
goto yyexhaustedlab;
# else
/* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
+ if (YYMAXDEPTH <= ]b4_yystacksize()[)
goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
+ ]b4_yystacksize()[ *= 2;
+ if (YYMAXDEPTH < ]b4_yystacksize()[)
+ ]b4_yystacksize()[ = YYMAXDEPTH;
{
- yytype_int16 *yyss1 = yyss;
+ yytype_int16 *yyss1 = ]b4_yyss()[;
+ ]b4_push_if([short *yyss = yyss1;
+ YYSTYPE *yyvs;
+ YYSIZE_T yystacksize;
+ yystacksize = pv->yystacksize;])[
union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (]b4_yystacksize()[));
if (! yyptr)
goto yyexhaustedlab;
+ ]b4_push_if([yyss= pv->yyss;])[
YYSTACK_RELOCATE (yyss);
+ ]b4_push_if([yyvs= pv->yyvs;])[
YYSTACK_RELOCATE (yyvs);
-]b4_location_if([ YYSTACK_RELOCATE (yyls);])[
+]b4_location_if([
+ b4_push_if([
+ YYLTYPE *yyls;
+ yyls= pv->yyls;])
+ YYSTACK_RELOCATE (yyls);])[
# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
+ if (yyss1 != ]b4_yyssa()[)
YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
+ ]b4_yyssp()[ = ]b4_yyss()[ + yysize - 1;
+ ]b4_yyvsp()[ = ]b4_yyvs()[ + yysize - 1;
]b4_location_if([ yylsp = yyls + yysize - 1;])[
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
- if (yyss + yystacksize - 1 <= yyssp)
+ if (]b4_yyss()[ + ]b4_yystacksize()[ - 1 <= ]b4_yyssp()[)
YYABORT;
}
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YYDPRINTF ((stderr, "Entering state %d\n", ]b4_yystate()[));
goto yybackup;
@@ -1174,62 +1316,69 @@
look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
+ #define YYFOOBAR ]b4_yystate()[
+ ]b4_yyn()[ = yypact[YYFOOBAR];
+ ]#undef YYFOOBAR[
+ if (]b4_yyn()[ == YYPACT_NINF)
goto yydefault;
/* Not known => get a look-ahead token if don't already have one. */
/* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
- if (yychar == YYEMPTY)
+ if (]b4_yychar()[ == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
+ ]b4_yychar()[ = YYLEX;
+gottoken:
+ ]b4_yychar()[ = ]b4_yytoken()[;
+ YYDPRINTF((stderr, "\nGot token %d", ]b4_yychar()[));
}
- if (yychar <= YYEOF)
+ if (]b4_yychar()[ <= YYEOF)
{
- yychar = yytoken = YYEOF;
+ ]b4_yychar()[ = ]b4_yytoken()[ = YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ ]b4_yytoken()[ = YYTRANSLATE (]b4_yychar()[);
+ YY_SYMBOL_PRINT ("Next token is", ]b4_yytoken()[, &yylval,
&]b4_yylloc()[);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ ]b4_yyn()[ += ]b4_yytoken()[;
+ #define YYFOOBAR ]b4_yyn()[
+ if (]b4_yyn()[ < 0 || YYLAST < ]b4_yyn()[ || yycheck[YYFOOBAR] !=
]b4_yytoken()[)
goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
+ ]b4_yyn()[ = yytable[YYFOOBAR];
+ #undef YYFOOBAR
+ if (]b4_yyn()[ <= 0)
{
- if (yyn == 0 || yyn == YYTABLE_NINF)
+ if (]b4_yyn()[ == 0 || ]b4_yyn()[ == YYTABLE_NINF)
goto yyerrlab;
- yyn = -yyn;
+ ]b4_yyn()[ = -]b4_yyn()[;
goto yyreduce;
}
- if (yyn == YYFINAL)
+ if (]b4_yyn()[ == YYFINAL)
YYACCEPT;
/* Count tokens shifted since error; after three, turn off error
status. */
- if (yyerrstatus)
- yyerrstatus--;
+ if (]b4_yyerrstatus()[)
+ ]b4_yyerrstatus()[--;
/* Shift the look-ahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+ YY_SYMBOL_PRINT ("Shifting", ]b4_yytoken()[, &yylval, &]b4_yylloc()[);
/* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
+ if (]b4_yychar()[ != YYEOF)
+ ]b4_yychar()[ = YYEMPTY;
- yystate = yyn;
- *++yyvsp = yylval;
-]b4_location_if([ *++yylsp = yylloc;])[
+ ]b4_yystate()[ = ]b4_yyn()[;
+ *++]b4_yyvsp()[ = ]b4_yylval()[;
+]b4_location_if([ *++]b4_yylsp()[ = ]b4_yylloc()[;])[
goto yynewstate;
@@ -1237,8 +1386,11 @@
| yydefault -- do the default action for the current state. |
`-----------------------------------------------------------*/
yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
+
+#define YYFOOBAR ]b4_yystate()[
+ ]b4_yyn()[ = yydefact[YYFOOBAR];
+#undef YYFOOBAR
+ if (]b4_yyn()[ == 0)
goto yyerrlab;
goto yyreduce;
@@ -1248,7 +1400,9 @@
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
+#define YYFOOBAR ]b4_yyn()[
+ ]b4_yylen()[ = yyr2[YYFOOBAR];
+#undef YYFOOBAR
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
@@ -1258,39 +1412,49 @@
users should not rely upon it. Assigning to YYVAL
unconditionally makes the parser a bit smaller, and it avoids a
GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
+#define YYFOOBAR ]b4_yylen()[
+ ]b4_yyval()[ = ]b4_yyvsp()[[1-YYFOOBAR];
+#undef YYFOOBAR
]b4_location_if(
[[ /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);]])[
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
+ YYLLOC_DEFAULT (]b4_yyloc()[, (]b4_yylsp()[ - ]b4_yylen()[),
]b4_yylen()[);]])[
+ YY_REDUCE_PRINT (]b4_yyn()[);
+ switch (]b4_yyn()[)
{
]b4_actions
/* Line __line__ of yacc.c. */
b4_syncline([EMAIL PROTECTED]@], [EMAIL PROTECTED]@])[
default: break;
}
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+#define YYFOOBAR ]b4_yyn()[
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[YYFOOBAR], &]b4_yyval()[, &]b4_yyloc()[);
+#undef YYFOOBAR
+
+ YYPOPSTACK (]b4_yylen()[);
+ ]b4_yylen()[ = 0;
+ YY_STACK_PRINT (]b4_yyss()[, ]b4_yyssp()[);
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-]b4_location_if([ *++yylsp = yyloc;])[
+ *++]b4_yyvsp()[ = ]b4_yyval()[;
+]b4_location_if([ *++]b4_yylsp()[ = ]b4_yyloc()[;])[
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
- yyn = yyr1[yyn];
+#define YYFOOBAR ]b4_yyn()[
+ ]b4_yyn()[ = yyr1[YYFOOBAR];
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
+ ]b4_yystate()[ = yypgoto[YYFOOBAR - YYNTOKENS] + *]b4_yyssp()[;
+#undef YYFOOBAR
+#define YYFOOBAR ]b4_yystate()[
+ if (0 <= ]b4_yystate()[ && ]b4_yystate()[ <= YYLAST && yycheck[YYFOOBAR] ==
*]b4_yyssp()[)
+ ]b4_yystate()[ = yytable[YYFOOBAR];
+#undef YYFOOBAR
else
- yystate = yydefgoto[yyn - YYNTOKENS];
+#define YYFOOBAR ]b4_yyn()[
+ ]b4_yystate()[ = yydefgoto[YYFOOBAR - YYNTOKENS];
+#undef YYFOOBAR
goto yynewstate;
@@ -1300,64 +1464,68 @@
`------------------------------------*/
yyerrlab:
/* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
+ if (!]b4_yyerrstatus()[)
{
- ++yynerrs;
+ ++]b4_yynerrs()[;
#if ! YYERROR_VERBOSE
yyerror (]b4_yyerror_args[YY_("syntax error"));
#else
{
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ YYSIZE_T yysize = yysyntax_error (0, ]b4_yystate()[, ]b4_yychar()[);
+ if (]b4_yymsg_alloc()[ < yysize && ]b4_yymsg_alloc()[ <
YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
+ if (]b4_yymsg()[ != ]b4_yymsgbuf()[)
+ YYSTACK_FREE (]b4_yymsg()[);
+ ]b4_yymsg()[ = (char *) YYSTACK_ALLOC (yyalloc);
+ if (]b4_yymsg()[)
+ ]b4_yymsg_alloc()[ = yyalloc;
else
{
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
+ ]b4_yymsg()[ = ]b4_yymsgbuf()[;
+ ]b4_yymsg_alloc()[ = sizeof (]b4_yymsgbuf()[);
}
}
- if (0 < yysize && yysize <= yymsg_alloc)
+ if (0 < ]b4_yysize()[ && ]b4_yysize()[ <= ]b4_yymsg_alloc()[)
{
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (]b4_yyerror_args[yymsg);
+ (void) yysyntax_error (]b4_yymsg()[, ]b4_yystate()[, ]b4_yychar()[);
+#define YYFOOBAR ]b4_yymmsg()[
+ yyerror (]b4_yyerror_args[YYFOOBAR);
+#undef YYFOOBAR
}
else
{
yyerror (]b4_yyerror_args[YY_("syntax error"));
- if (yysize != 0)
+ if (]b4_yysize()[ != 0)
goto yyexhaustedlab;
}
}
#endif
}
-]b4_location_if([[ yyerror_range[0] = yylloc;]])[
+]b4_location_if([[ yyerror_range[0] = ]b4_yylloc()[;]])[
- if (yyerrstatus == 3)
+ if (]b4_yyerrstatus()[ == 3)
{
/* If just tried and failed to reuse look-ahead token after an
error, discard it. */
- if (yychar <= YYEOF)
+ if (]b4_yychar()[ <= YYEOF)
{
/* Return failure if at end of input. */
- if (yychar == YYEOF)
+ if (]b4_yychar()[ == YYEOF)
YYABORT;
}
else
{
+#define YYFOOBAR ]b4_yylloc()[
yydestruct ("Error: discarding",
- yytoken, &yylval]b4_location_if([,
&yylloc])[]b4_user_args[);
- yychar = YYEMPTY;
+ ]b4_yytoken()[, &]b4_yylval()[]b4_location_if([,
&YYFOOBAR])[]b4_user_args[);
+#undef YYFOOBAR
+ ]b4_yychar()[ = YYEMPTY;
}
}
@@ -1380,10 +1548,10 @@
]b4_location_if([[ yyerror_range[0] = yylsp[1-yylen];
]])[ /* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
+ YYPOPSTACK (]b4_yylen()[);
+ ]b4_yylen()[ = 0;
+ YY_STACK_PRINT (]b4_yyss()[, ]b4_yyssp()[);
+ ]b4_yystate()[ = *]b4_yyssp()[;
goto yyerrlab1;
@@ -1391,49 +1559,57 @@
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
+ ]b4_yyerrstatus()[ = 3; /* Each real token shifted decrements this. */
for (;;)
{
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+#define YYFOOBAR ]b4_yystate()[
+ ]b4_yyn()[ = yypact[YYFOOBAR];
+#undef YYFOOBAR
+ if (]b4_yyn()[ != YYPACT_NINF)
+ {
+ ]b4_yyn()[ += YYTERROR;
+#define YYFOOBAR ]b4_yyn()[
+ if (0 <= ]b4_yyn()[ && ]b4_yyn()[ <= YYLAST && yycheck[YYFOOBAR] ==
YYTERROR)
{
- yyn = yytable[yyn];
- if (0 < yyn)
+ ]b4_yyn()[ = yytable[YYFOOBAR];
+ if (0 < ]b4_yyn()[)
break;
}
+#undef YYFOOBAR
}
/* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
+ if (]b4_yyssp()[ == ]b4_yyss()[)
YYABORT;
-]b4_location_if([[ yyerror_range[0] = *yylsp;]])[
+]b4_location_if([[ yyerror_range[0] = *]b4_yylsp()[;]])[
+#define YYFOOBAR ]b4_yystate()[
yydestruct ("Error: popping",
- yystos[yystate], yyvsp]b4_location_if([,
yylsp])[]b4_user_args[);
+ yystos[YYFOOBAR], ]b4_yyvsp()[]b4_location_if([,
]b4_yylsp()[])[]b4_user_args[);
+#undef YYFOOBAR
YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
+ ]b4_yystate()[ = *]b4_yyssp()[;
+ YY_STACK_PRINT (]b4_yyss()[, ]b4_yyssp()[);
}
- if (yyn == YYFINAL)
+ if (]b4_yyn()[ == YYFINAL)
YYACCEPT;
- *++yyvsp = yylval;
+ *++]b4_yyvsp()[ = ]b4_yylval()[;
]b4_location_if([[
- yyerror_range[1] = yylloc;
+ yyerror_range[1] = ]b4_yylloc()[;
/* Using YYLLOC is tempting, but would change the location of
the look-ahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
- *++yylsp = yyloc;]])[
+ YYLLOC_DEFAULT (]b4_yyloc()[, (yyerror_range - 1), 2);
+ *++]b4_yylsp()[ = ]b4_yyloc()[;]])[
/* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+#define YYFOOBAR ]b4_yyn()[
+ YY_SYMBOL_PRINT ("Shifting", yystos[YYFOOBAR], ]b4_yyvsp()[, ]b4_yylsp()[);
+#undef YYFOOBAR
- yystate = yyn;
+ ]b4_yystate()[ = ]b4_yyn()[;
goto yynewstate;
@@ -1441,14 +1617,14 @@
| yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/
yyacceptlab:
- yyresult = 0;
+ ]b4_yyresult()[ = 0;
goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
- yyresult = 1;
+ ]b4_yyresult()[ = 1;
goto yyreturn;
#ifndef yyoverflow
@@ -1457,33 +1633,37 @@
`-------------------------------------------------*/
yyexhaustedlab:
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
- yyresult = 2;
+ ]b4_yyresult()[ = 2;
/* Fall through. */
#endif
yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
+ if (]b4_yychar()[ != YYEOF && ]b4_yychar()[ != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval]b4_location_if([, &yylloc])[]b4_user_args[);
+ ]b4_yytoken()[, &]b4_yylval()[]b4_location_if([,
&]b4_yylloc()[])[]b4_user_args[);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
+ YYPOPSTACK (]b4_yylen()[);
+ YY_STACK_PRINT (]b4_yyss()[, ]b4_yyssp()[);
+ while (]b4_yyssp()[ != ]b4_yyss()[)
{
+#define YYFOOBAR ]b4_yyssp()[
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp]b4_location_if([,
yylsp])[]b4_user_args[);
+ yystos[*YYFOOBAR], ]b4_yyvsp()[]b4_location_if([,
]b4_yylsp()[])[]b4_user_args[);
+#undef YYFOOBAR
YYPOPSTACK (1);
}
#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
+ if (]b4_yyss()[ != ]b4_yyssa()[)
+ YYSTACK_FREE (]b4_yyss()[);
#endif
#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
+ if (]b4_yymsg()[ != ]b4_yymsgbuf()[)
+ YYSTACK_FREE (]b4_yymsg()[);
#endif
- return yyresult;
+
+]b4_push_if([return;],[
+ return yyresult;])[
]}
Index: src/getargs.c
===================================================================
RCS file: /sources/bison/bison/src/getargs.c,v
retrieving revision 1.66
diff -w -u -r1.66 getargs.c
--- src/getargs.c 3 Jan 2006 19:12:55 -0000 1.66
+++ src/getargs.c 14 Feb 2006 01:45:08 -0000
@@ -58,6 +58,7 @@
bool nondeterministic_parser = false;
bool glr_parser = false;
bool pure_parser = false;
+bool push_parser = false;
const char *skeleton = NULL;
const char *include = NULL;
Index: src/getargs.h
===================================================================
RCS file: /sources/bison/bison/src/getargs.h,v
retrieving revision 1.28
diff -w -u -r1.28 getargs.h
--- src/getargs.h 24 Jul 2005 07:24:22 -0000 1.28
+++ src/getargs.h 14 Feb 2006 01:45:08 -0000
@@ -50,6 +50,11 @@
extern bool pure_parser;
+/* PUSH_PARSER is true if should generate a parser that is capble of being
+ called asynchronously. Is must be pure and reentrant. */
+
+extern bool push_parser;
+
/* NONDETERMINISTIC_PARSER is true iff conflicts are accepted. This
is used by the GLR parser, and might be used in BackTracking
parsers too. */
Index: src/output.c
===================================================================
RCS file: /sources/bison/bison/src/output.c,v
retrieving revision 1.245
diff -w -u -r1.245 output.c
--- src/output.c 21 Jan 2006 04:35:09 -0000 1.245
+++ src/output.c 14 Feb 2006 01:45:08 -0000
@@ -502,7 +502,7 @@
output_skeleton (void)
{
FILE *in;
- FILE *out;
+ FILE *out, *outfile;
int filter_fd[2];
char const *argv[5];
pid_t pid;
@@ -550,23 +550,36 @@
out = fdopen (filter_fd[0], "w");
if (! out)
- error (EXIT_FAILURE, get_errno (),
- "fdopen");
+ error (EXIT_FAILURE, get_errno (), "fdopen");
+
+ outfile = fopen ("bisonm4.txt", "w");
+ if (!outfile)
+ error (EXIT_FAILURE, get_errno (), "fopen");
/* Output the definitions of all the muscles. */
fputs ("m4_init()\n", out);
+ fputs ("m4_init()\n", outfile);
user_actions_output (out);
+ user_actions_output (outfile);
merger_output (out);
+ merger_output (outfile);
token_definitions_output (out);
+ token_definitions_output (outfile);
symbol_destructors_output (out);
+ symbol_destructors_output (outfile);
symbol_printers_output (out);
+ symbol_printers_output (outfile);
muscles_m4_output (out);
+ muscles_m4_output (outfile);
fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
+ fputs ("m4_wrap([m4_divert_pop(0)])\n", outfile);
fputs ("m4_divert_push(0)dnl\n", out);
+ fputs ("m4_divert_push(0)dnl\n", outfile);
xfclose (out);
+ xfclose (outfile);
/* Read and process m4's output. */
timevar_push (TV_M4);
@@ -590,6 +603,7 @@
MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
MUSCLE_INSERT_BOOL ("pure", pure_parser);
+ MUSCLE_INSERT_BOOL ("push", push_parser);
MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
/* File names. */
Index: src/parse-gram.h
===================================================================
RCS file: /sources/bison/bison/src/parse-gram.h,v
retrieving revision 1.89
diff -w -u -r1.89 parse-gram.h
--- src/parse-gram.h 30 Jan 2006 11:15:15 -0000 1.89
+++ src/parse-gram.h 14 Feb 2006 01:45:08 -0000
@@ -63,22 +63,23 @@
PERCENT_OUTPUT = 288,
PERCENT_PARSE_PARAM = 289,
PERCENT_PURE_PARSER = 290,
- PERCENT_REQUIRE = 291,
- PERCENT_SKELETON = 292,
- PERCENT_START = 293,
- PERCENT_TOKEN_TABLE = 294,
- PERCENT_VERBOSE = 295,
- PERCENT_YACC = 296,
- TYPE = 297,
- EQUAL = 298,
- SEMICOLON = 299,
- PIPE = 300,
- ID = 301,
- ID_COLON = 302,
- PERCENT_PERCENT = 303,
- PROLOGUE = 304,
- EPILOGUE = 305,
- BRACED_CODE = 306
+ PERCENT_PUSH_PARSER = 291,
+ PERCENT_REQUIRE = 292,
+ PERCENT_SKELETON = 293,
+ PERCENT_START = 294,
+ PERCENT_TOKEN_TABLE = 295,
+ PERCENT_VERBOSE = 296,
+ PERCENT_YACC = 297,
+ TYPE = 298,
+ EQUAL = 299,
+ SEMICOLON = 300,
+ PIPE = 301,
+ ID = 302,
+ ID_COLON = 303,
+ PERCENT_PERCENT = 304,
+ PROLOGUE = 305,
+ EPILOGUE = 306,
+ BRACED_CODE = 307
};
#endif
/* Tokens. */
@@ -116,29 +117,30 @@
#define PERCENT_OUTPUT 288
#define PERCENT_PARSE_PARAM 289
#define PERCENT_PURE_PARSER 290
-#define PERCENT_REQUIRE 291
-#define PERCENT_SKELETON 292
-#define PERCENT_START 293
-#define PERCENT_TOKEN_TABLE 294
-#define PERCENT_VERBOSE 295
-#define PERCENT_YACC 296
-#define TYPE 297
-#define EQUAL 298
-#define SEMICOLON 299
-#define PIPE 300
-#define ID 301
-#define ID_COLON 302
-#define PERCENT_PERCENT 303
-#define PROLOGUE 304
-#define EPILOGUE 305
-#define BRACED_CODE 306
+#define PERCENT_PUSH_PARSER 291
+#define PERCENT_REQUIRE 292
+#define PERCENT_SKELETON 293
+#define PERCENT_START 294
+#define PERCENT_TOKEN_TABLE 295
+#define PERCENT_VERBOSE 296
+#define PERCENT_YACC 297
+#define TYPE 298
+#define EQUAL 299
+#define SEMICOLON 300
+#define PIPE 301
+#define ID 302
+#define ID_COLON 303
+#define PERCENT_PERCENT 304
+#define PROLOGUE 305
+#define EPILOGUE 306
+#define BRACED_CODE 307
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 95 "parse-gram.y"
+#line 95 "../../bison/src/parse-gram.y"
{
symbol *symbol;
symbol_list *list;
@@ -148,7 +150,7 @@
uniqstr uniqstr;
}
/* Line 1536 of yacc.c. */
-#line 152 "y.tab.h"
+#line 154 "../../bison/src/parse-gram.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
Index: src/parse-gram.y
===================================================================
RCS file: /sources/bison/bison/src/parse-gram.y,v
retrieving revision 1.73
diff -w -u -r1.73 parse-gram.y
--- src/parse-gram.y 30 Jan 2006 09:00:40 -0000 1.73
+++ src/parse-gram.y 14 Feb 2006 01:45:08 -0000
@@ -149,6 +149,7 @@
PERCENT_OUTPUT "%output"
PERCENT_PARSE_PARAM "%parse-param {...}"
PERCENT_PURE_PARSER "%pure-parser"
+ PERCENT_PUSH_PARSER "%push-parser"
PERCENT_REQUIRE "%require"
PERCENT_SKELETON "%skeleton"
PERCENT_START "%start"
@@ -245,6 +246,7 @@
| "%output" "=" string_content { spec_outfile = $3; }
| "%parse-param {...}" { add_param ("parse_param", $1, @1);
}
| "%pure-parser" { pure_parser = true; }
+| "%push-parser" { push_parser = true; }
| "%require" string_content { version_check (&@2, $2); }
| "%skeleton" string_content { skeleton = $2; }
| "%token-table" { token_table_flag = true; }
Index: src/scan-gram.l
===================================================================
RCS file: /sources/bison/bison/src/scan-gram.l,v
retrieving revision 1.85
diff -w -u -r1.85 scan-gram.l
--- src/scan-gram.l 30 Jan 2006 07:25:59 -0000 1.85
+++ src/scan-gram.l 14 Feb 2006 01:45:08 -0000
@@ -245,6 +245,7 @@
"%prec" rule_length--; return PERCENT_PREC;
"%printer" token_type = PERCENT_PRINTER; BEGIN SC_PRE_CODE;
"%pure"[-_]"parser" return PERCENT_PURE_PARSER;
+ "%push"[-_]"parser" return PERCENT_PUSH_PARSER;
"%require" return PERCENT_REQUIRE;
"%right" return PERCENT_RIGHT;
"%skeleton" return PERCENT_SKELETON;