On Mon, Sep 25, 2006 at 10:28:23AM -0400, Bob Rossi wrote:
> On Thu, Sep 21, 2006 at 07:03:47AM -0400, Bob Rossi wrote:
> > On Wed, Sep 20, 2006 at 09:58:30PM -0700, Paul Eggert wrote:
> > > >> One way to address this issue would be to have two entry points:
> > > >>
> > > >> status = yypushparse (ctx, ch, yylloc);
> > > >>
> > > >> for tokens that have no semantic value, and
> > > >>
> > > >> status = yypushparseval (ctx, ch, yylval, yylloc);
> > > >>
> > > >> for tokens that do.
> > > >>
> > > >> Another possibility, which will avoid a copy in some cases if semantic
> > > >> values are large, is to pass a pointer:
> > > >>
> > > >> status = yypushparse (ctx, ch, &yylval, yylloc);
> > > >>
> > > >> where you pass a NULL pointer if the token has no semantic value. If
> > > >> the copying issue is of concern, it may also make sense to pass
> > > >> yylloc's
> > > >> address too:
> > > >>
> > > >> status = yypushparse (ctx, ch, &yylval, &yylloc);
> > > >>
> > > >> I don't know whether the copying concern is enough to affect
> > > >> performance, though.
> > > >
> > > > I'm not decided on how to modify the yypushparse function parameters.
> > > > Have you made up your mind?
> > >
> > > If it doesn't matter to you, let's use the second method (passing
> > > the addresses). We can always change it later if it turns
> > > out to have a problem.
> >
> > OK, I liked the second approach better myself. I'll look into it.
>
> I have a small patch that get's me this far:
> status = yypushparse (ctx, ch, &yylval);
>
> What should I do about yylval?
>
> I can attempt to make yypushparse have an extra parameter when locations
> are enabled. Does that sound correct?
Here, is a patch I'm posting just for you to tell me if this is the
appropriate solution. If it is, I'll clean it up and add the ChangeLog.
This removes all set/get accessor functions, and has a single
yypushparse function that takes 3 parameters when locations are off, and
4 parameters when locations are on.
Thanks,
Bob Rossi
Index: push.c
===================================================================
RCS file: /sources/bison/bison/data/push.c,v
retrieving revision 1.3
diff -u -r1.3 push.c
--- push.c 21 Sep 2006 17:45:21 -0000 1.3
+++ push.c 25 Sep 2006 14:45:51 -0000
@@ -161,11 +161,7 @@
#define yychar b4_prefix[]char
#define yydebug b4_prefix[]debug
#define yynerrs b4_prefix[]nerrs
-b4_locations_if([#define yylloc b4_prefix[]lloc])
-b4_push_if([
-#define yychar_set b4_prefix[]char_set
-#define yylval_set b4_prefix[]lval_set
-#define yylloc_set b4_prefix[]lloc_set])])[
+b4_locations_if([#define yylloc b4_prefix[]lloc])])[
/* Copy the first part of user declarations. */
]b4_pre_prologue[
@@ -974,14 +970,12 @@
]b4_push_if([
struct yypvars;
enum { YYPUSH_MORE = 4 };
-]b4_c_function_decl([yychar_set], [void], [[struct yypvars *YYPVARS],
[YYPVARS]], [[int yychar], [yychar]])[
-]b4_c_function_decl([yylval_set], [void], [[struct yypvars *YYPVARS],
[YYPVARS]], [[YYSTYPE yylval], [yylval]])[
-#ifdef YYLTYPE_IS_TRIVIAL
-]b4_c_function_decl([yylloc_set], [void], [[struct yypvars *YYPVARS],
[YYPVARS]], [[YYLTYPE yylloc], [yylloc]])[
-#endif
]b4_c_function_decl([yypvarsinit], [void *], [[void], []])[
]b4_c_function_decl([yypushparse], [int],
- [[struct yypvars *YYPVARS], [YYPVARS]])[
+ [[struct yypvars *YYPVARS], [YYPVARS]],
+ [[int YYCHAR], [YYCHAR]],
+ [[YYSTYPE *YYLVAL], [YYLVAL]]
+ b4_locations_if([,[[YYLTYPE *YYLLOC], [YYLLOC]]]))[
])[
]m4_divert_push([KILL])# ======================== M4 code.
@@ -1098,30 +1092,7 @@
]b4_locations_if([ pv->yylsp = pv->yyls;])[
return (void *) pv;
-}
-
-void
-yychar_set (struct yypvars *YYPVARS, int yychar)
-{
- if (YYPVARS)
- YYPVARS->yychar = yychar;
-}
-
-void
-yylval_set (struct yypvars *YYPVARS, YYSTYPE yylval)
-{
- if (YYPVARS)
- YYPVARS->yylval = yylval;
-}
-
-#ifdef YYLTYPE_IS_TRIVIAL
-void
-yylloc_set (struct yypvars *YYPVARS, YYLTYPE yylloc)
-{
- if (YYPVARS)
- YYPVARS->yylloc = yylloc;
-}
-#endif])
+}])
m4_divert_pop([KILL])dnl# ====================== End of M4 code.
b4_pure_if([],
@@ -1134,7 +1105,10 @@
`-------------------------*/
b4_push_if([
-b4_c_function_def([yypushparse], [int], [[struct yypvars *YYPVARS],
[YYPVARS]])],[
+b4_c_function_def([yypushparse], [int], [[struct yypvars *YYPVARS],
[YYPVARS]],
+ [[int YYCHAR], [YYCHAR]],
+ [[YYSTYPE *YYLVAL], [YYLVAL]]
+ b4_locations_if([,[[YYLTYPE *YYLLOC],
[YYLLOC]]]))],[
#ifdef YYPARSE_PARAM
b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
#else /* ! YYPARSE_PARAM */
@@ -1202,7 +1176,15 @@
YYDPRINTF ((stderr, "Starting parse\n"));
- ]b4_push_if([pv = YYPVARS;])[
+ ]b4_push_if([pv = YYPVARS;
+ pv->yychar = YYCHAR;
+ if (YYLVAL)
+ pv->yylval = *YYLVAL;
+ ]b4_locations_if([
+#if YYLTYPE_IS_TRIVIAL
+ if (YYLLOC)
+ pv->yylloc = *YYLLOC;
+#endif]))[
yystate = 0;
yyerrstatus = 0;
@@ -1722,13 +1704,14 @@
{[
struct yypvars *ctx = yypvarsinit ();
int status;
+ int ch;
do {
- yychar_set (ctx, yylex ());
- yylval_set (ctx, yylval);
+ ch = yylex ();
#ifdef YYLTYPE_IS_TRIVIAL
- yylloc_set (ctx, yylloc);
+ status = yypushparse (ctx, ch, &yylval, &yylloc);
+#else
+ status = yypushparse (ctx, ch, &yylval);
#endif
- status = yypushparse (ctx);
} while (status == YYPUSH_MORE);
free (ctx);
return status;
Index: yacc.c
===================================================================
RCS file: /sources/bison/bison/data/yacc.c,v
retrieving revision 1.153
diff -u -r1.153 yacc.c
--- yacc.c 11 Aug 2006 19:50:14 -0000 1.153
+++ yacc.c 25 Sep 2006 14:45:52 -0000
@@ -152,13 +152,18 @@
m4_if(b4_prefix, [yy], [],
[/* Substitute the variable and function names. */
#define yyparse b4_prefix[]parse
+#define yypushparse b4_prefix[]pushparse
+#define yypvarsinit b4_prefix[]pvarsinit
+#define yypvars b4_prefix[]pvars
#define yylex b4_prefix[]lex
#define yyerror b4_prefix[]error
#define yylval b4_prefix[]lval
#define yychar b4_prefix[]char
#define yydebug b4_prefix[]debug
#define yynerrs b4_prefix[]nerrs
-b4_locations_if([#define yylloc b4_prefix[]lloc])])[
+b4_locations_if([#define yylloc b4_prefix[]lloc])
+b4_push_if([
+#define yylloc_set b4_prefix[]lloc_set])])[
/* Copy the first part of user declarations. */
]b4_pre_prologue[
@@ -964,6 +969,18 @@
]b4_c_function_decl([yyparse], [int], b4_parse_param)[
#endif /* ! YYPARSE_PARAM */
+]b4_push_if([
+struct yypvars;
+enum { YYPUSH_MORE = 4 };
+#ifdef YYLTYPE_IS_TRIVIAL
+]b4_c_function_decl([yylloc_set], [void], [[struct yypvars *YYPVARS],
[YYPVARS]], [[YYLTYPE yylloc], [yylloc]])[
+#endif
+]b4_c_function_decl([yypvarsinit], [void *], [[void], []])[
+]b4_c_function_decl([yypushparse], [int],
+ [[struct yypvars *YYPVARS], [YYPVARS]],
+ [[int YYCHAR], [YYCHAR]],
+ [[YYSTYPE *YYLVAL], [YYLVAL]])[
+])[
]m4_divert_push([KILL])# ======================== M4 code.
# b4_declare_parser_variables
@@ -982,23 +999,136 @@
/* Location data for the lookahead symbol. */
YYLTYPE yylloc;])
])
+
+# b4_declare_yyparse_variables
+# ----------------------------
+# Declare all the variables that are needed local to YYPARSE
+m4_define([b4_declare_yyparse_variables],
+[[struct yypvars
+ {
+]]b4_declare_parser_variables[[
+ 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 *yymsgbuf_ptr;
+ 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 *yyssa_ptr;
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;]]b4_locations_if([[[
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[2];
+ YYLTYPE *yyerror_range_ptr;]]])[
+ YYSIZE_T yystacksize;
+ int yylen;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ /* Used to determine if this is the first time this instance has
+ been used. */
+ int yynew;]b4_locations_if([YYLTYPE yyloc;])[
+ };
+
+/* Initialize the parser data structure. */
+void *
+yypvarsinit (void)
+{
+ struct yypvars *pv = (struct yypvars *) malloc (sizeof *pv);
+ pv->yystate = 0;
+ pv->yyresult = -1;
+ pv->yyerrstatus = 0;
+ pv->yytoken = 0;
+
+#if YYERROR_VERBOSE
+ pv->yymsgbuf_ptr = pv->yymsgbuf;
+ pv->yymsg = pv->yymsgbuf;
+ pv->yymsg_alloc = sizeof pv->yymsgbuf;
+#endif
+
+ pv->yyssa_ptr = pv->yyssa;
+ pv->yyss = pv->yyssa;
+ pv->yyvs = pv->yyvsa;
+
+ ]b4_locations_if([
+ pv->yyls = pv->yylsa;])[
+ pv->yystacksize = YYINITDEPTH;
+
+ pv->yyssp = pv->yyss;
+ pv->yyvsp = pv->yyvs;
+
+#if YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ pv->yylloc.first_line = pv->yylloc.last_line =
]b4_location_initial_line[;
+ pv->yylloc.first_column = pv->yylloc.last_column =
]b4_location_initial_column[;
+#endif
+
+ pv->yynew = 1;
+
+]b4_locations_if([ pv->yylsp = pv->yyls;])[
+
+ return (void *) pv;
+}
+
+#ifdef YYLTYPE_IS_TRIVIAL
+void
+yylloc_set (struct yypvars *YYPVARS, YYLTYPE yylloc)
+{
+ if (YYPVARS)
+ YYPVARS->yylloc = yylloc;
+}
+#endif])
m4_divert_pop([KILL])dnl# ====================== End of M4 code.
b4_pure_if([],
[b4_declare_parser_variables])
+b4_push_if([b4_declare_yyparse_variables])
-/*----------.
-| yyparse. |
-`----------*/
-
+/*-------------------------.
+| yyparse or yypushparse. |
+`-------------------------*/
+
+b4_push_if([
+b4_c_function_def([yypushparse], [int], [[struct yypvars *YYPVARS],
[YYPVARS]],
+ [[int YYCHAR], [YYCHAR]],
+ [[YYSTYPE *YYLVAL], [YYLVAL]])],[
#ifdef YYPARSE_PARAM
b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
#else /* ! YYPARSE_PARAM */
b4_c_function_def([yyparse], [int], b4_parse_param)
-#endif
+#endif])
{[
]b4_pure_if([b4_declare_parser_variables])[
+ ]b4_push_if([struct yypvars *pv;])[
int yystate;
int yyn;
int yyresult;
@@ -1009,6 +1139,7 @@
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
+ char *yymsgbuf_ptr = yymsgbuf;
char *yymsg = yymsgbuf;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
@@ -1023,6 +1154,7 @@
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyssa_ptr = yyssa;
yytype_int16 *yyss = yyssa;
yytype_int16 *yyssp;
@@ -1037,7 +1169,9 @@
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
/* The locations where the error started and ended. */
- YYLTYPE yyerror_range[2];]])[
+ YYLTYPE yyerror_range[2];
+ YYLTYPE *yyerror_range_ptr = yyerror_range;
+ ]])[
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp
-= (N)])[)
@@ -1054,6 +1188,11 @@
YYDPRINTF ((stderr, "Starting parse\n"));
+ ]b4_push_if([pv = YYPVARS;
+ pv->yychar = YYCHAR;
+ if (YYLVAL)
+ pv->yylval = *YYLVAL;])[
+
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
@@ -1067,24 +1206,65 @@
yyssp = yyss;
yyvsp = yyvs;
]b4_locations_if([[ yylsp = yyls;
+]b4_push_if([],[
#if YYLTYPE_IS_TRIVIAL
/* Initialize the default location before parsing starts. */
yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[;
yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
-#endif
+#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
/* User initialization code. */
- b4_user_initial_action
+b4_user_initial_action
m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl
m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
]])dnl
m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc;
]])dnl
-[ goto yysetstate;
+[ ]b4_push_if([
+ /* Initialize the locals to the current context. */
+ yychar = pv->yychar;
+ yylval = pv->yylval;
+ yynerrs = pv->yynerrs;
+ ]b4_locations_if([
+ yylloc = pv->yylloc;])[
+
+ yystate = pv->yystate;
+ yyn = pv->yyn;
+ yyresult = pv->yyresult;
+ yyerrstatus = pv->yyerrstatus;
+ yytoken = pv->yytoken;
+#if YYERROR_VERBOSE
+ yymsgbuf_ptr = pv->yymsgbuf_ptr;
+ yymsg = pv->yymsg;;
+ yymsg_alloc = pv->yymsg_alloc;
+#endif
+ yyssa_ptr = pv->yyssa_ptr;
+ yyss = pv->yyss;
+ yyssp = pv->yyssp;
+
+ yyvs = pv->yyvs;
+ yyvsp = pv->yyvsp;
+
+ ]b4_locations_if([[ /* The location stack. */
+ yyls = pv->yyls;
+ yylsp = pv->yylsp;
+
+ yyerror_range_ptr = pv->yyerror_range_ptr;]])[
+
+ yystacksize = pv->yystacksize;
+ yylen = pv->yylen;
+ yyval = pv->yyval;
+ ]b4_locations_if([yyloc = pv->yyloc;])[
+ if (pv->yynew == 0)
+ {
+ goto gottoken;
+ }
+ pv->yynew= 0;])[
+ goto yysetstate;
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. |
@@ -1145,7 +1325,7 @@
YYSTACK_RELOCATE (yyvs);
]b4_locations_if([ YYSTACK_RELOCATE (yyls);])[
# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
+ if (yyss1 != yyssa_ptr)
YYSTACK_FREE (yyss1);
}
# endif
@@ -1187,8 +1367,47 @@
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
+ ]b4_push_if([
+ YYDPRINTF ((stderr, "Return for a new token:\n"));
+ yyresult = YYPUSH_MORE;
+ /* Initialize the locals to the current context. */
+ pv->yychar = yychar;
+ pv->yylval = yylval;
+ pv->yynerrs = yynerrs;
+ ]b4_locations_if([
+ pv->yylloc = yylloc;])[
+
+ pv->yystate = yystate;
+ pv->yyn = yyn;
+ pv->yyresult = yyresult;
+ pv->yyerrstatus = yyerrstatus;
+ pv->yytoken = yytoken;
+#if YYERROR_VERBOSE
+ pv->yymsgbuf_ptr = yymsgbuf_ptr;
+ pv->yymsg = yymsg;;
+ pv->yymsg_alloc = yymsg_alloc;
+#endif
+ pv->yyssa_ptr = yyssa_ptr;
+ pv->yyss = yyss;
+ pv->yyssp = yyssp;
+
+ pv->yyvs = yyvs;
+ pv->yyvsp = yyvsp;
+
+ ]b4_locations_if([[ /* The location stack. */
+ pv->yyls = yyls;
+ pv->yylsp = yylsp;
+ pv->yyerror_range_ptr = yyerror_range_ptr;]])[
+
+ pv->yystacksize = yystacksize;
+ pv->yylen = yylen;
+ pv->yyval = yyval;
+ ]b4_locations_if([pv->yyloc = yyloc;])[
+ return yyresult;
+gottoken:
+ YYDPRINTF((stderr, "Reading a token: "));],[
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;])[
}
if (yychar <= YYEOF)
@@ -1311,14 +1530,14 @@
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
+ if (yymsg != yymsgbuf_ptr)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
- yymsg = yymsgbuf;
+ yymsg = yymsgbuf_ptr;
yymsg_alloc = sizeof yymsgbuf;
}
}
@@ -1422,7 +1641,7 @@
yyerror_range[1] = yylloc;
/* Using YYLLOC is tempting, but would change the location of
the lookahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+ YYLLOC_DEFAULT (yyloc, (yyerror_range- 1), 2);
*++yylsp = yyloc;]])[
/* Shift the error token. */
@@ -1471,17 +1690,39 @@
YYPOPSTACK (1);
}
#ifndef yyoverflow
- if (yyss != yyssa)
+ if (yyss != yyssa_ptr)
YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
+ if (yymsg != yymsgbuf_ptr)
YYSTACK_FREE (yymsg);
#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
+ ]b4_push_if([pv->yyresult = YYID (yyresult);])[
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
]}
+b4_push_if([
+#ifdef YYPARSE_PARAM
+b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
+#else /* ! YYPARSE_PARAM */
+b4_c_function_def([yyparse], [int], b4_parse_param)
+#endif
+{[
+ struct yypvars *ctx = yypvarsinit ();
+ int status;
+ int ch;
+ do {
+ ch = yylex ();
+#ifdef YYLTYPE_IS_TRIVIAL
+ yylloc_set (ctx, yylloc);
+#endif
+ status = yypushparse (ctx, ch, &yylval);
+ } while (status == YYPUSH_MORE);
+ free (ctx);
+ return status;
+]}])
+
b4_epilogue
b4_defines_if(
@@ -1525,6 +1766,8 @@
# define YYLTYPE_IS_TRIVIAL 1
#endif
+]b4_push_if([struct ]b4_prefix[pvars;
+enum { YYPUSH_MORE = 4 };])[
]b4_pure_if([],
[extern YYLTYPE b4_prefix[]lloc;])
)dnl b4_locations_if