mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-11 05:13:04 +00:00
For push mode, convert yyparse from a macro to a function, invoke yylex
instead of passing a yylexp argument to yypull_parse, and don't generate yypull_parse or yyparse unless %push-pull-parser is declared. Discussed starting at <http://lists.gnu.org/archive/html/bison-patches/2006-12/msg00163.html>. * data/bison.m4 (b4_pull_if): New. * data/c.m4 (b4_identification): Define YYPULL similar to YYPUSH. * data/push.c: Improve M4 quoting a little. (b4_generate_macro_args, b4_parenthesize): Remove. (yyparse): If there's a b4_prefix, #define this to b4_prefix[parse] any time a pull parser is requested. Don't #define this as a wrapper around yypull_parse. Instead, when both push and pull are requested, make it a function that does that same thing. (yypull_parse): If there's a b4_prefix, #define this to b4_prefix[pull_parse] when both push and pull are requested. Don't define this as a function unless both push and pull are requested. Remove the yylexp argument and hard-code yylex invocation instead. * etc/bench.pl.in (bench_grammar): Use %push-pull-parser instead of %push-parser. * src/getargs.c (pull_parser): New global initialized to true. * getargs.h (pull_parser): extern it. * src/output.c (prepare): Insert pull_flag muscle. * src/parse-gram.y (PERCENT_PUSH_PULL_PARSER): New token. (prologue_declaration): Set both push_parser and pull_parser = true for %push-pull-parser. Set push_parser = true and pull_parser = false for %push-parser. * src/scan-gram.l: Don't accept %push_parser as an alternative to %push-parser since there's no backward-compatibility concern here. Scan %push-pull-parser. * tests/calc.at (Simple LALR(1) Calculator): Use %push-pull-parser instead of %push-parser. * tests/headers.at (export YYLTYPE): Make yylex static, and don't prototype it in the module that calls yyparse. * tests/input.at (Torturing the Scanner): Likewise. * tests/local.at (AT_PUSH_IF): Check for %push-pull-parser as well.
This commit is contained in:
@@ -127,8 +127,9 @@ b4_define_flag_if([error_verbose]) # Whether error are verbose.
|
||||
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
|
||||
b4_define_flag_if([locations]) # Whether locations are tracked.
|
||||
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
|
||||
b4_define_flag_if([pull]) # Whether pull parsing is requested.
|
||||
b4_define_flag_if([pure]) # Whether the interface is pure.
|
||||
b4_define_flag_if([push]) # Whether push parsing is supported.
|
||||
b4_define_flag_if([push]) # Whether push parsing is requested.
|
||||
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ m4_define([b4_identification],
|
||||
/* Push parsers. */
|
||||
[#]define YYPUSH b4_push_flag
|
||||
|
||||
/* Pull parsers. */
|
||||
[#]define YYPULL b4_pull_flag
|
||||
|
||||
/* Using locations. */
|
||||
[#]define YYLSP_NEEDED b4_locations_flag
|
||||
])
|
||||
|
||||
104
data/push.c
104
data/push.c
@@ -63,32 +63,6 @@ b4_locations_if([, [[YYLTYPE *], [&yylloc]]])m4_ifdef([b4_lex_param], [, ])])dnl
|
||||
m4_ifdef([b4_lex_param], b4_lex_param)))
|
||||
|
||||
|
||||
# b4_generate_macro_args([A], [B], [C], ...)
|
||||
# ---------------------------------------------------
|
||||
# Generate a comma-delimited list whose size is equal to the number of input
|
||||
# arguments and whose form is:
|
||||
#
|
||||
# YYARG1, YYARG2, YYARG3, ...
|
||||
#
|
||||
# No argument should be the empty string except A in the special invocation
|
||||
# b4_generate_macro_args(), which generates an empty string.
|
||||
m4_define([b4_generate_macro_args],
|
||||
[m4_if([$1], [], [], [$#], [1], [[YYARG1]],
|
||||
[b4_generate_macro_args(m4_shift($@)), [YYARG$#]])])
|
||||
|
||||
|
||||
# b4_parenthesize([A], [B], [C], ...)
|
||||
# ---------------------------------------------------
|
||||
# Convert arguments to the form:
|
||||
#
|
||||
# (A), (B), (C), ...
|
||||
#
|
||||
# No argument should be the empty string except A in the special invocation
|
||||
# b4_parenthesize(), which generates an empty string.
|
||||
m4_define([b4_parenthesize],
|
||||
[m4_if([$1], [], [], [$#], [1], [[($1)]],
|
||||
[($1), b4_parenthesize(m4_shift($@))])])
|
||||
|
||||
## ------------ ##
|
||||
## Data Types. ##
|
||||
## ------------ ##
|
||||
@@ -175,20 +149,20 @@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl '
|
||||
|
||||
]b4_identification
|
||||
m4_if(b4_prefix, [yy], [],
|
||||
[/* Substitute the variable and function names. */
|
||||
]b4_push_if([#define yypush_parse b4_prefix[]push_parse
|
||||
#define yypull_parse b4_prefix[]pull_parse
|
||||
#define yypstate_new b4_prefix[]pstate_new
|
||||
#define yypstate_delete b4_prefix[]pstate_delete
|
||||
#define yypstate b4_prefix[]pstate],
|
||||
[#define yyparse b4_prefix[]parse])[
|
||||
#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])])[
|
||||
[[/* Substitute the variable and function names. */
|
||||
]b4_pull_if([[#define yyparse ]b4_prefix[parse
|
||||
]])b4_push_if([[#define yypush_parse ]b4_prefix[push_parse
|
||||
]b4_pull_if([[#define yypull_parse ]b4_prefix[pull_parse
|
||||
]])[#define yypstate_new ]b4_prefix[pstate_new
|
||||
#define yypstate_delete ]b4_prefix[pstate_delete
|
||||
#define yypstate ]b4_prefix[pstate
|
||||
]])[#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]])])[
|
||||
|
||||
/* Copy the first part of user declarations. */
|
||||
]b4_user_pre_prologue[
|
||||
@@ -248,20 +222,20 @@ b4_push_if([[#ifndef YYPUSH_DECLS
|
||||
struct yypstate;
|
||||
typedef struct yypstate yypstate;
|
||||
enum { YYPUSH_MORE = 4 };
|
||||
# define yyparse(]b4_generate_macro_args(b4_parse_param))[ yypull_parse (0, &yylex]m4_ifset([b4_parse_param], [, b4_parenthesize(b4_generate_macro_args(b4_parse_param))])[)
|
||||
]b4_c_function_decl([[yypstate_new]], [[yypstate *]], [[[void]], []])
|
||||
b4_c_function_decl([[yypstate_delete]], [[void]],
|
||||
[[[yypstate *yyps]], [[yyps]]])
|
||||
b4_c_function_decl([[yypush_parse]], [[int]],
|
||||
|
||||
]b4_pull_if([b4_c_function_decl([[yyparse]], [[int]], b4_parse_param)
|
||||
])b4_c_function_decl([[yypush_parse]], [[int]],
|
||||
[[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
|
||||
[[[int yypushed_char]], [[yypushed_char]]],
|
||||
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
|
||||
[[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))
|
||||
b4_c_function_decl([[yypull_parse]], [[int]],
|
||||
[[[yypstate *yyps]], [[yyps]]],
|
||||
[[[int (*yylexp)(]b4_c_ansi_formals(b4_lex_param)[)]], [[yylexp]]]m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))[
|
||||
b4_pull_if([b4_c_function_decl([[yypull_parse]], [[int]],
|
||||
[[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))])
|
||||
b4_c_function_decl([[yypstate_new]], [[yypstate *]], [[[void]], []])
|
||||
b4_c_function_decl([[yypstate_delete]], [[void]],
|
||||
[[[yypstate *yyps]], [[yyps]]])[
|
||||
#endif
|
||||
]])
|
||||
m4_ifdef([b4_provides],
|
||||
@@ -1087,9 +1061,14 @@ b4_push_if(
|
||||
int yynew;
|
||||
};
|
||||
|
||||
]b4_pull_if([b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
|
||||
{
|
||||
return yypull_parse (0]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_c_args(b4_parse_param)])[);
|
||||
}
|
||||
|
||||
]b4_c_function_def([[yypull_parse]], [[int]],
|
||||
[[[yypstate *yyps]], [[yyps]]],
|
||||
[[[int (*yylexp)(]b4_c_ansi_formals(b4_lex_param)[)]], [[yylexp]]]m4_ifset([b4_parse_param], [,
|
||||
[[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))[
|
||||
{
|
||||
int yystatus;
|
||||
@@ -1103,7 +1082,7 @@ b4_push_if(
|
||||
else
|
||||
yyps_local = yyps;
|
||||
do {
|
||||
yychar = ]b4_c_function_call([yylexp], [int], b4_lex_param)[;
|
||||
yychar = YYLEX;
|
||||
yystatus =
|
||||
yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[);
|
||||
} while (yystatus == YYPUSH_MORE);
|
||||
@@ -1111,7 +1090,7 @@ b4_push_if(
|
||||
yypstate_delete (yyps_local);
|
||||
return yystatus;
|
||||
}
|
||||
|
||||
]])[
|
||||
/* Initialize the parser data structure. */
|
||||
]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
|
||||
{
|
||||
@@ -1703,21 +1682,20 @@ b4_push_if([[#ifndef YYPUSH_DECLS
|
||||
struct ]b4_prefix[pstate;
|
||||
typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
|
||||
enum { YYPUSH_MORE = 4 };
|
||||
# define ]b4_prefix[parse(]b4_generate_macro_args(b4_parse_param)) b4_prefix[pull_parse (0, &]b4_prefix[lex]m4_ifset([b4_parse_param], [, b4_parenthesize(b4_generate_macro_args(b4_parse_param))])[)
|
||||
]b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
|
||||
[[[void]], []])
|
||||
b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
|
||||
[[b4_prefix[pstate *yyps]], [[yyps]]])
|
||||
b4_c_function_decl([b4_prefix[push_parse]], [[int]],
|
||||
]b4_pull_if([b4_c_function_decl([b4_prefix[parse]], [[int]], b4_parse_param)
|
||||
])b4_c_function_decl([b4_prefix[push_parse]], [[int]],
|
||||
[[b4_prefix[pstate *yyps]], [[yyps]]]b4_pure_if([,
|
||||
[[[int yypushed_char]], [[yypushed_char]]],
|
||||
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
|
||||
[[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))
|
||||
b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
|
||||
[[b4_prefix[pstate *yyps]], [[yyps]]],
|
||||
[[[int (*yylexp)(]b4_c_ansi_formals(b4_lex_param)[)]], [[yylexp]]]m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))[
|
||||
b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
|
||||
[[b4_prefix[pstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
|
||||
b4_parse_param]))])
|
||||
b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
|
||||
[[[void]], []])
|
||||
b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
|
||||
[[b4_prefix[pstate *yyps]], [[yyps]]])[
|
||||
#endif
|
||||
]])
|
||||
m4_ifdef([b4_provides],
|
||||
|
||||
Reference in New Issue
Block a user