Encapsulate the push parser state variables into an M4 macro so the

push skeleton doesn't have to list them again for pull mode's yyparse.
For push mode, remove yypush_parse's local equivalents of these
variables to eliminate unnecessary copying between the two sets at
run-time.  This patch also fixes at least a bug related to multiple
%initial-action invocations in push mode.
* data/push.c (b4_declare_parser_variables): Rename to...
(b4_declare_scanner_communication_variables): ... this for clarity and
update both uses.
(b4_declare_yyparse_variables): Remove and move its contents to the one
spot where it was invoked.
(b4_declare_parser_state_variables): New macro containing the parser
state variables required by push mode.
(struct yypstate): Replace all fields but yynew with
b4_declare_parser_state_variables.
(yystate, yyn, yyresult, yyerrstatus, yytoken, yyss, yyssp, yyvs,
yyvsp, yyls, yylsp, yystacksize, yyval, yyloc): For push mode, #define
each NAME in this list to yyps->NAME so it can be used in yypush_parse.
(yyparse or yypush_parse): For yyparse in pull mode, replace local
parser state variable declarations with
b4_declare_parser_state_variables.
Don't initialize parser state variables when calling yypush_parse since
yypstate_new already does that.
Invoke the user's initial action only upon the first yypush_parse
invocation.
Remove all code that copies between the local parser state variables
and the yypstate.
This commit is contained in:
Joel E. Denny
2006-12-20 00:59:18 +00:00
parent 2d212f8ca6
commit bb010fe51a
2 changed files with 93 additions and 119 deletions

View File

@@ -1,3 +1,33 @@
2006-12-19 Joel E. Denny <jdenny@ces.clemson.edu>
Encapsulate the push parser state variables into an M4 macro so the
push skeleton doesn't have to list them again for pull mode's yyparse.
For push mode, remove yypush_parse's local equivalents of these
variables to eliminate unnecessary copying between the two sets at
run-time. This patch also fixes at least a bug related to multiple
%initial-action invocations in push mode.
* data/push.c (b4_declare_parser_variables): Rename to...
(b4_declare_scanner_communication_variables): ... this for clarity and
update both uses.
(b4_declare_yyparse_variables): Remove and move its contents to the one
spot where it was invoked.
(b4_declare_parser_state_variables): New macro containing the parser
state variables required by push mode.
(struct yypstate): Replace all fields but yynew with
b4_declare_parser_state_variables.
(yystate, yyn, yyresult, yyerrstatus, yytoken, yyss, yyssp, yyvs,
yyvsp, yyls, yylsp, yystacksize, yyval, yyloc): For push mode, #define
each NAME in this list to yyps->NAME so it can be used in yypush_parse.
(yyparse or yypush_parse): For yyparse in pull mode, replace local
parser state variable declarations with
b4_declare_parser_state_variables.
Don't initialize parser state variables when calling yypush_parse since
yypstate_new already does that.
Invoke the user's initial action only upon the first yypush_parse
invocation.
Remove all code that copies between the local parser state variables
and the yypstate.
2006-12-19 Joel E. Denny <jdenny@ces.clemson.edu> 2006-12-19 Joel E. Denny <jdenny@ces.clemson.edu>
* data/push.c (union yyalloc): Rename yyss, yyvs, and yyls fields to * data/push.c (union yyalloc): Rename yyss, yyvs, and yyls fields to

View File

@@ -981,11 +981,11 @@ enum { YYPUSH_MORE = 4 };
#endif /* ! YYPARSE_PARAM */])[ #endif /* ! YYPARSE_PARAM */])[
]m4_divert_push([KILL])# ======================== M4 code. ]m4_divert_push([KILL])# ======================== M4 code.
# b4_declare_parser_variables # b4_declare_scanner_communication_variables
# --------------------------- # ------------------------------------------
# Declare the variables that are global, or local to YYPARSE if # Declare the variables that are global, or local to YYPARSE if
# pure-parser. # pure-parser.
m4_define([b4_declare_parser_variables], m4_define([b4_declare_scanner_communication_variables],
[/* The lookahead symbol. */ [/* The lookahead symbol. */
int yychar; int yychar;
@@ -1002,19 +1002,19 @@ YYLTYPE yylloc;])
m4_define([b4_yyssa],b4_push_if([yyps->yyssa],[yyssa])) m4_define([b4_yyssa],b4_push_if([yyps->yyssa],[yyssa]))
m4_define([b4_yyerror_range],b4_push_if([yyps->yyerror_range],[yyerror_range])) m4_define([b4_yyerror_range],b4_push_if([yyps->yyerror_range],[yyerror_range]))
# b4_declare_yyparse_variables # b4_declare_parser_state_variables
# ---------------------------- # ---------------------------------
# Declare all the variables that are needed local to YYPARSE # Declare all the variables that are needed to maintain the parser state
m4_define([b4_declare_yyparse_variables], # between calls to yypush_parse.
[[struct yypstate m4_define([b4_declare_parser_state_variables],
{ [[
int yystate; int yystate;
int yyn; int yyn;
int yyresult; int yyresult;
/* Number of tokens to shift before error messages enabled. */ /* Number of tokens to shift before error messages enabled. */
int yyerrstatus; int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */ /* Look-ahead token as an internal (translated) token number. */
int yytoken; int yytoken]b4_push_if([], [[ = 0]])[;
/* Three stacks and their tools: /* Three stacks and their tools:
`yyss': related to states, `yyss': related to states,
@@ -1026,26 +1026,37 @@ m4_define([b4_declare_yyparse_variables],
/* The state stack. */ /* The state stack. */
yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss; yytype_int16 *yyss]b4_push_if([], [[ = yyssa]])[;
yytype_int16 *yyssp; yytype_int16 *yyssp;
/* The semantic value stack. */ /* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs; YYSTYPE *yyvs]b4_push_if([], [[ = yyvsa]])[;
YYSTYPE *yyvsp;]]b4_locations_if([[[ YYSTYPE *yyvsp;]b4_locations_if([[
/* The location stack. */ /* The location stack. */
YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls; YYLTYPE *yyls]b4_push_if([], [[ = yylsa]])[;
YYLTYPE *yylsp; YYLTYPE *yylsp;
/* The locations where the error started and ended. */ /* The locations where the error started and ended. */
YYLTYPE yyerror_range[2];]]])[ YYLTYPE yyerror_range[2];]])[
YYSIZE_T yystacksize; YYSIZE_T yystacksize]b4_push_if([], [[ = YYINITDEPTH]])[;
/* The variables used to return semantic value and location from the /* The variables used to return semantic value and location from the
action routines. */ action routines. */
YYSTYPE yyval; YYSTYPE yyval;]b4_locations_if([[
YYLTYPE yyloc;]])
])
m4_divert_pop([KILL])dnl# ====================== End of M4 code.
b4_pure_if([], [b4_declare_scanner_communication_variables])
b4_push_if(
[[struct yypstate
{
]b4_declare_parser_state_variables[
/* Used to determine if this is the first time this instance has /* Used to determine if this is the first time this instance has
been used. */ been used. */
int yynew;]b4_locations_if([YYLTYPE yyloc;])[ int yynew;
}; };
/* Initialize the parser data structure. */ /* Initialize the parser data structure. */
@@ -1079,18 +1090,28 @@ m4_define([b4_declare_yyparse_variables],
{ {
free (yyps); free (yyps);
} }
])
m4_divert_pop([KILL])dnl# ====================== End of M4 code.
b4_pure_if([], [b4_declare_parser_variables]) #define yystate yyps->yystate
#define yyn yyps->yyn
b4_push_if([b4_declare_yyparse_variables]) #define yyresult yyps->yyresult
#define yyerrstatus yyps->yyerrstatus
#define yytoken yyps->yytoken
#define yyss yyps->yyss
#define yyssp yyps->yyssp
#define yyvs yyps->yyvs
#define yyvsp yyps->yyvsp
]b4_locations_if([[#define yyls yyps->yyls
#define yylsp yyps->yylsp
]])[#define yystacksize yyps->yystacksize
#define yyval yyps->yyval
]b4_locations_if([[#define yyloc yyps->yyloc
]])])[
/*-------------------------. /*-------------------------.
| yyparse or yypush_parse. | | yyparse or yypush_parse. |
`-------------------------*/ `-------------------------*/
b4_push_if([ ]b4_push_if([
b4_c_function_def([yypush_parse], [int], [[yypstate *yyps], [yyps]], b4_c_function_def([yypush_parse], [int], [[yypstate *yyps], [yyps]],
[[int yynchar], [yynchar]], [[int yynchar], [yynchar]],
[[YYSTYPE const *yynlval], [yynlval]] [[YYSTYPE const *yynlval], [yynlval]]
@@ -1100,16 +1121,11 @@ b4_c_function_def([yypush_parse], [int], [[yypstate *yyps], [yyps]],
b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]]) b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
#else /* ! YYPARSE_PARAM */ #else /* ! YYPARSE_PARAM */
b4_c_function_def([yyparse], [int], b4_parse_param) b4_c_function_def([yyparse], [int], b4_parse_param)
#endif]) #endif])[
{[ {
]b4_pure_if([b4_declare_parser_variables])[ ]b4_pure_if([b4_declare_scanner_communication_variables])
int yystate; b4_push_if([], [b4_declare_parser_state_variables])[
int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Lookahead token as an internal (translated) token number. */
int yytoken = 0;
#if YYERROR_VERBOSE #if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */ /* Buffer for error messages, and its allocated size. */
char yymsgbuf[128]; char yymsgbuf[128];
@@ -1117,50 +1133,14 @@ b4_c_function_def([yyparse], [int], b4_parse_param)
YYSIZE_T yymsg_alloc = sizeof yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif #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 = yyssa;
yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
YYSTYPE *yyvsp;
]b4_locations_if(
[[ /* The location stack. */
YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
/* The locations where the error started and ended. */
]b4_push_if([],[YYLTYPE yyerror_range[[2]]])[;
]])[
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[) #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
]b4_locations_if([ YYLTYPE yyloc;])[
/* The number of symbols on the RHS of the reduced rule. /* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */ Keep to zero when no symbol should be popped. */
int yylen = 0; int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n")); YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
]b4_push_if([ yychar = yynchar; ]b4_push_if([ yychar = yynchar;
if (yynlval) if (yynlval)
yylval = *yynlval; yylval = *yynlval;
@@ -1168,6 +1148,10 @@ b4_c_function_def([yyparse], [int], b4_parse_param)
yylloc = *yynlloc;])[],[yynerrs = 0; yylloc = *yynlloc;])[],[yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */])[ yychar = YYEMPTY; /* Cause a token to be read. */])[
]b4_push_if([],[[
yystate = 0;
yyerrstatus = 0;
/* Initialize stack pointers. /* Initialize stack pointers.
Waste one element of value and location stack Waste one element of value and location stack
so that they stay on the same level as the state stack. so that they stay on the same level as the state stack.
@@ -1176,13 +1160,18 @@ b4_c_function_def([yyparse], [int], b4_parse_param)
yyssp = yyss; yyssp = yyss;
yyvsp = yyvs; yyvsp = yyvs;
]b4_locations_if([[ yylsp = yyls; ]b4_locations_if([[ yylsp = yyls;
]b4_push_if([],[
#if YYLTYPE_IS_TRIVIAL #if YYLTYPE_IS_TRIVIAL
/* Initialize the default location before parsing starts. */ /* Initialize the default location before parsing starts. */
yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[; yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[;
yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[; yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
#endif])[ #endif]])
]]) ])
[ ]b4_push_if([
if (yyps->yynew == 0)
{
goto gottoken;
}
yyps->yynew= 0;])
m4_ifdef([b4_initial_action], [ m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [m4_define([b4_at_dollar_used])yylloc])dnl 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 m4_pushdef([b4_dollar_dollar], [m4_define([b4_dollar_dollar_used])yylval])dnl
@@ -1194,32 +1183,7 @@ m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
]])dnl ]])dnl
m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc; m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc;
]])dnl ]])dnl
[ ]b4_push_if([ [
/* Initialize the locals to the current context. */
yystate = yyps->yystate;
yyn = yyps->yyn;
yyresult = yyps->yyresult;
yyerrstatus = yyps->yyerrstatus;
yytoken = yyps->yytoken;
yyss = yyps->yyss;
yyssp = yyps->yyssp;
yyvs = yyps->yyvs;
yyvsp = yyps->yyvsp;
]b4_locations_if([[ /* The location stack. */
yyls = yyps->yyls;
yylsp = yyps->yylsp;]])[
yystacksize = yyps->yystacksize;
yyval = yyps->yyval;
]b4_locations_if([yyloc = yyps->yyloc;])[
if (yyps->yynew == 0)
{
goto gottoken;
}
yyps->yynew= 0;])[
goto yysetstate; goto yysetstate;
/*------------------------------------------------------------. /*------------------------------------------------------------.
@@ -1326,25 +1290,6 @@ yybackup:
]b4_push_if([ ]b4_push_if([
YYDPRINTF ((stderr, "Return for a new token:\n")); YYDPRINTF ((stderr, "Return for a new token:\n"));
yyresult = YYPUSH_MORE; yyresult = YYPUSH_MORE;
/* Initialize the locals to the current context. */
yyps->yystate = yystate;
yyps->yyn = yyn;
yyps->yyerrstatus = yyerrstatus;
yyps->yytoken = yytoken;
yyps->yyss = yyss;
yyps->yyssp = yyssp;
yyps->yyvs = yyvs;
yyps->yyvsp = yyvsp;
]b4_locations_if([[ /* The location stack. */
yyps->yyls = yyls;
yyps->yylsp = yylsp;]])[
yyps->yystacksize = yystacksize;
yyps->yyval = yyval;
]b4_locations_if([yyps->yyloc = yyloc;])[
goto yypushreturn; goto yypushreturn;
gottoken:])[ gottoken:])[
YYDPRINTF ((stderr, "Reading a token: ")); YYDPRINTF ((stderr, "Reading a token: "));
@@ -1639,7 +1584,6 @@ yyreturn:
if (yymsg != yymsgbuf) if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg); YYSTACK_FREE (yymsg);
#endif #endif
]b4_push_if([yyps->yyresult = YYID (yyresult);])[
/* Make sure YYID is used. */ /* Make sure YYID is used. */
return YYID (yyresult); return YYID (yyresult);
]} ]}