Index: ChangeLog =================================================================== RCS file: /sources/bison/bison/ChangeLog,v retrieving revision 1.1625 diff -p -u -r1.1625 ChangeLog --- ChangeLog 17 Dec 2006 01:33:31 -0000 1.1625 +++ ChangeLog 18 Dec 2006 08:12:19 -0000 @@ -1,3 +1,32 @@ +2006-12-18 Joel E. Denny + + Give push mode a yyparse wrapper, make push mode support impure mode, + and fix push mode well enough so that it passes the entire test suite + when it is substituted for yacc.c pull mode. The following description + leaves out a lot of details that are explained at + . + * data/push.c: Too much work to completely describe here. + (yypull_parse): New function wrapping yypush_parse. + (yyparse): New #define wrapping yypull_parse. + * src/parse-gram.y (prologue_declaration): Don't set pure_parser for + %push-parser since push mode now supports impure mode. + * tests/calc.at (_AT_DATA_CALC_Y): Call yyparse even when %push-parser + is declared. + (Simple LALR(1) Calculator): Always set %pure-parser along with + %push-parser since this test case was designed for pure push parsers. + * tests/headers.at (export YYLTYPE): Make yylex global. For pull mode, + prototype yylex in the module that calls yyparse, and don't prototype + yyparse there. Otherwise, the yyparse expansion in pull mode won't + compile. + * tests/input.at (Torturing the Scanner): Likewise. + * tests/local.at (AT_PURE_OR_PUSH_IF): Remove unused. + (AT_YACC_OR_PUSH_IF): New. + (AT_YYERROR_SEES_LOC_IF): Fix enough that the test suite passes, but + add a note that it's still wrong for some cases (as it has been for a + while). + (AT_PURE_LEX_IF): Use AT_PURE_IF instead of AT_PURE_OR_PUSH_IF since + %push-parser no longer implies %pure-parser. + 2006-12-16 Joel E. Denny Make %push-parser imply %pure-parser. This fixes several bugs; see Index: data/push.c =================================================================== RCS file: /sources/bison/bison/data/push.c,v retrieving revision 1.17 diff -p -u -r1.17 push.c --- data/push.c 17 Dec 2006 01:33:31 -0000 1.17 +++ data/push.c 18 Dec 2006 08:12:19 -0000 @@ -63,6 +63,31 @@ b4_locations_if([, [[YYLTYPE *], [&yyllo 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. ## @@ -152,6 +177,7 @@ b4_copyright([Skeleton implementation fo 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], @@ -217,6 +243,27 @@ typedef struct YYLTYPE # define YYLTYPE_IS_TRIVIAL 1 #endif]) +b4_push_if([[ +struct yypstate; +#ifndef YYPSTATE_DECLS +# define YYPSTATE_DECLS +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))])[) +#endif +]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], + [[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])) +]) m4_ifdef([b4_provides], [[/* Copy the %provides blocks. */ ]b4_user_provides])[]dnl @@ -373,9 +420,9 @@ void free (void *); /* INFRINGES ON USER /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - ]b4_locations_if([ YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + ]b4_locations_if([ YYLTYPE yyls_alloc; ])dnl [}; @@ -419,8 +466,8 @@ union yyalloc do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack##_alloc, Stack, yysize); \ + Stack = &yyptr->Stack##_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -961,53 +1008,37 @@ yysyntax_error (char *yyresult, int yyst /* Prevent warnings from -Wmissing-prototypes. */ -]b4_push_if([ -struct yypstate; -typedef struct yypstate yypstate; -enum { YYPUSH_MORE = 4 }; -]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], - [[yypstate *yyps], [yyps]], - [[int yynchar], [yynchar]], - [[YYSTYPE const *yynlval], [yynlval]] - b4_locations_if([,[[YYLTYPE const *yynlloc], [yynlloc]]]) - m4_ifset([b4_parse_param], [, b4_parse_param]))[ -],[#ifdef YYPARSE_PARAM +]b4_push_if([], +[[#ifdef YYPARSE_PARAM ]b4_c_function_decl([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[ #else /* ! YYPARSE_PARAM */ ]b4_c_function_decl([yyparse], [int], b4_parse_param)[ -#endif /* ! YYPARSE_PARAM */])[ +#endif /* ! YYPARSE_PARAM */]]) -]m4_divert_push([KILL])# ======================== M4 code. -# b4_declare_parser_variables -# --------------------------- +m4_divert_push([KILL])# ======================== M4 code. +# b4_declare_parser_interface_variables +# ------------------------------------- # Declare the variables that are global, or local to YYPARSE if # pure-parser. -m4_define([b4_declare_parser_variables], -[/* The lookahead symbol. */ +m4_define([b4_declare_parser_interface_variables], +[[/* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; - -/* Number of syntax errors so far. */ -]b4_push_if([],[ -int yynerrs;])[b4_locations_if([ +]b4_locations_if([[ /* Location data for the lookahead symbol. */ -YYLTYPE yylloc;]) -]) - -m4_define([b4_yyssa],b4_push_if([yyps->yyssa],[yyssa])) -m4_define([b4_yyerror_range],b4_push_if([yyps->yyerror_range],[yyerror_range])) +YYLTYPE yylloc; +]])b4_pure_if([], [[ +/* Number of syntax errors so far. */ +int yynerrs; +]])]) -# b4_declare_yyparse_variables -# ---------------------------- -# Declare all the variables that are needed local to YYPARSE -m4_define([b4_declare_yyparse_variables], -[[struct yypstate - { +m4_define([b4_declare_parser_state_variables], +[b4_pure_if([[ /* Number of syntax errors so far. */ + int yynerrs; +]])[ int yystate; int yyn; int yyresult; @@ -1032,45 +1063,89 @@ m4_define([b4_declare_yyparse_variables] /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; - YYSTYPE *yyvsp;]]b4_locations_if([[[ - /* The location stack. */ + 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[2];]])[ + YYSIZE_T yystacksize; + /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; +]b4_locations_if([[ YYLTYPE yyloc; +]])]) + +m4_divert_pop([KILL])dnl# ====================== End of M4 code. + +b4_pure_if([], [b4_declare_parser_interface_variables]) + +b4_push_if( +[[struct yypstate + { + ]b4_declare_parser_state_variables[ /* Used to determine if this is the first time this instance has been used. */ - int yynew;]b4_locations_if([YYLTYPE yyloc;])[ + int yynew; }; +]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], + [, b4_parse_param]))[ +{ + int yystatus; + yypstate *yyps_local; +]b4_pure_if([[ int yychar; + YYSTYPE yylval; +]b4_locations_if([[ YYLTYPE yylloc; +]])])[ + if (yyps == 0) + yyps_local = yypstate_new (); + else + yyps_local = yyps; + do { + yychar = ]b4_c_function_call([yylexp], [int], b4_lex_param)[; + 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); + if (yyps == 0) + yypstate_delete (yyps_local); + return yystatus; +} + +]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[ +#define yystate yyps->yystate +#define yyn yyps->yyn +#define yyresult yyps->yyresult +#define yyerrstatus yyps->yyerrstatus +#define yytoken yyps->yytoken +#define yyssa yyps->yyssa +#define yyss yyps->yyss +#define yyssp yyps->yyssp +#define yyvsa yyps->yyvsa +#define yyvs yyps->yyvs +#define yyvsp yyps->yyvsp +]b4_locations_if([[#define yylsa yyps->yylsa +#define yyls yyps->yyls +#define yylsp yyps->yylsp +#define yyerror_range yyps->yyerror_range +]])[#define yystacksize yyps->yystacksize +#define yyval yyps->yyval +]b4_locations_if([[#define yyloc yyps->yyloc +]])[ + /* Initialize the parser data structure. */ ]b4_c_function_def([yypstate_new], [yypstate *])[ { yypstate *yyps = (yypstate *) malloc (sizeof *yyps); - yyps->yystate = 0; - yyps->yyresult = -1; - yyps->yyerrstatus = 0; - yyps->yytoken = 0; - - yyps->yyss = yyps->yyssa; - yyps->yyvs = yyps->yyvsa; - - ]b4_locations_if([ - yyps->yyls = yyps->yylsa;])[ - yyps->yystacksize = YYINITDEPTH; - - yyps->yyssp = yyps->yyss; - yyps->yyvsp = yyps->yyvs; - + yyresult = -1; yyps->yynew = 1; - -]b4_locations_if([ yyps->yylsp = yyps->yyls;])[ - return yyps; } @@ -1079,37 +1154,34 @@ m4_define([b4_declare_yyparse_variables] { free (yyps); } -]) -m4_divert_pop([KILL])dnl# ====================== End of M4 code. - -b4_pure_if([], [b4_declare_parser_variables]) - -b4_push_if([b4_declare_yyparse_variables]) +]]) /*-------------------------. | yyparse or yypush_parse. | `-------------------------*/ b4_push_if([ -b4_c_function_def([yypush_parse], [int], [[yypstate *yyps], [yyps]], - [[int yynchar], [yynchar]], - [[YYSTYPE const *yynlval], [yynlval]] - b4_locations_if([,[[YYLTYPE const *yynlloc], [yynlloc]]]) - m4_ifset([b4_parse_param], [, b4_parse_param]))],[ +b4_c_function_def([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]))],[ #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]) -{[ - ]b4_pure_if([b4_declare_parser_variables])[ - int yystate; - 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; +#endif])[ +{ + ]b4_pure_if([b4_declare_parser_interface_variables]) + b4_push_if([b4_pure_if([], [[ int yypushed_char = yychar; + YYSTYPE yypushed_val_local = yylval; + YYSTYPE *yypushed_val = &yylval; + ]b4_locations_if([[YYLTYPE yypushed_loc_local = yylloc; + YYLTYPE *yypushed_loc = &yylloc; +]])])], + [b4_declare_parser_state_variables])[ + #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; @@ -1117,110 +1189,54 @@ b4_c_function_def([yyparse], [int], b4_p YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #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)])[) - 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. Keep to zero when no symbol should be popped. */ int yylen = 0; +]b4_push_if([[ + if (!yyps->yynew) + goto yyread_pushed_token; +]])[ + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; +]b4_locations_if([[ yyls = yylsa; +]])[ + yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; -]b4_push_if([ yychar = yynchar; - if (yynlval) - yylval = *yynlval; -]b4_locations_if([ if (yynlloc) - yylloc = *yynlloc;])[],[yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */])[ + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - 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 -[ ]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; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | @@ -1281,7 +1297,7 @@ m4_ifdef([b4_at_dollar_used], [[ yylsp[ YYSTACK_RELOCATE (yyvs); ]b4_locations_if([ YYSTACK_RELOCATE (yyls);])[ # undef YYSTACK_RELOCATE - if (yyss1 != ]b4_yyssa[) + if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif @@ -1323,32 +1339,29 @@ yybackup: /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { - ]b4_push_if([ - YYDPRINTF ((stderr, "Return for a new token:\n")); - 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; -gottoken:])[ - YYDPRINTF ((stderr, "Reading a token: ")); - ]b4_push_if([], [yychar = YYLEX;])[ +]b4_push_if([[ if (!yyps->yynew) + { + YYDPRINTF ((stderr, "Return for a new token:\n")); + yyresult = YYPUSH_MORE; + goto yypushreturn; + } + yyps->yynew = 0; + ]b4_pure_if([], [[ + /* Restoring the pushed token is only necessary for the first + yypush_parse invocation since subsequent invocations don't overwrite + it before jumping to yyread_pushed_token. */ + yychar = yypushed_char; + yylval = yypushed_val_local; + ]b4_locations_if([[yylloc = yypushed_loc_local; +]])])[ +yyread_pushed_token: +]])[ YYDPRINTF ((stderr, "Reading a token: ")); +]b4_push_if([[ yychar = yypushed_char; + if (yypushed_val) + yylval = *yypushed_val; +]b4_locations_if([[ if (yypushed_loc) + yylloc = *yypushed_loc;]])], +[[ yychar = YYLEX;]])[ } if (yychar <= YYEOF) @@ -1460,7 +1473,7 @@ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { -]b4_push_if([],[ ++yynerrs;])[ + ++yynerrs; #if ! YYERROR_VERBOSE yyerror (]b4_yyerror_args[YY_("syntax error")); #else @@ -1498,7 +1511,7 @@ yyerrlab: #endif } -]b4_locations_if([[ ]b4_yyerror_range[[0] = yylloc;]])[ +]b4_locations_if([[ yyerror_range[0] = yylloc;]])[ if (yyerrstatus == 3) { @@ -1535,7 +1548,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; -]b4_locations_if([[ ]b4_yyerror_range[[0] = yylsp[1-yylen]; +]b4_locations_if([[ yyerror_range[0] = yylsp[1-yylen]; ]])[ /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -1569,7 +1582,7 @@ yyerrlab1: if (yyssp == yyss) YYABORT; -]b4_locations_if([[ ]b4_yyerror_range[[0] = *yylsp;]])[ +]b4_locations_if([[ yyerror_range[0] = *yylsp;]])[ yydestruct ("Error: popping", yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); YYPOPSTACK (1); @@ -1579,10 +1592,10 @@ yyerrlab1: *++yyvsp = yylval; ]b4_locations_if([[ - ]b4_yyerror_range[[1] = yylloc; + yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (]b4_yyerror_range[- 1), 2); + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc;]])[ /* Shift the error token. */ @@ -1631,7 +1644,7 @@ yyreturn: YYPOPSTACK (1); } #ifndef yyoverflow - if (yyss != ]b4_yyssa[) + if (yyss != yyssa) YYSTACK_FREE (yyss); #endif ]b4_push_if([yypushreturn:])[ @@ -1639,7 +1652,7 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - ]b4_push_if([yyps->yyresult = YYID (yyresult);])[ + ]b4_push_if([yyresult = YYID (yyresult);])[ /* Make sure YYID is used. */ return YYID (yyresult); ]} @@ -1687,23 +1700,31 @@ typedef struct YYLTYPE #endif ]b4_pure_if([], - [extern YYLTYPE b4_prefix[]lloc;]) + [[extern YYLTYPE b4_prefix[]lloc;]]) )dnl b4_locations_if -]b4_push_if([struct ]b4_prefix[pstate; +b4_push_if([[struct ]b4_prefix[pstate; +#ifndef YYPSTATE_DECLS +# define YYPSTATE_DECLS typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; -]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_prefix[pstate *]b4_prefix[pstate], []b4_prefix[pstate]], - [[int yynchar], [yynchar]], - [[YYSTYPE const *yynlval], [yynlval]] - b4_locations_if([,[[YYLTYPE const *yynlloc], [yynlloc]]]) - m4_ifset([b4_parse_param], [, b4_parse_param]))[ -enum { YYPUSH_MORE = 4 };])[ - +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))])[) +#endif +]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_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])) +]) m4_ifdef([b4_provides], [[/* Copy the %provides blocks. */ ]b4_user_provides])[] Index: src/parse-gram.y =================================================================== RCS file: /sources/bison/bison/src/parse-gram.y,v retrieving revision 1.101 diff -p -u -r1.101 parse-gram.y --- src/parse-gram.y 17 Dec 2006 01:33:31 -0000 1.101 +++ src/parse-gram.y 18 Dec 2006 08:12:21 -0000 @@ -255,7 +255,7 @@ prologue_declaration: | "%output" "=" STRING { spec_outfile = $3; } /* deprecated */ | "%parse-param" "{...}" { add_param ("parse_param", $2, @2); } | "%pure-parser" { pure_parser = true; } -| "%push-parser" { push_parser = true; pure_parser = true; } +| "%push-parser" { push_parser = true; } | "%require" STRING { version_check (&@2, $2); } | "%skeleton" STRING { skeleton = $2; } | "%token-table" { token_table_flag = true; } Index: tests/calc.at =================================================================== RCS file: /sources/bison/bison/tests/calc.at,v retrieving revision 1.98 diff -p -u -r1.98 calc.at --- tests/calc.at 15 Dec 2006 05:31:26 -0000 1.98 +++ tests/calc.at 18 Dec 2006 08:12:21 -0000 @@ -336,17 +336,7 @@ main (int argc, const char **argv) ]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug], [ yydebug = 1;])])[ -]AT_PUSH_IF([ - { - yypstate *pstate = yypstate_new (); - YYSTYPE my_lval; - ]AT_LOCATION_IF([YYLTYPE my_lloc;])[ - do { - status = yypush_parse (pstate, yylex (&my_lval]AT_LOCATION_IF([[, &my_lloc]])[), &my_lval]AT_LOCATION_IF([[, &my_lloc]])[); - } while (status == YYPUSH_MORE); - yypstate_delete (pstate); - }],[ - status = yyparse (]AT_PARAM_IF([[&result, &count]])[);])[ + status = yyparse (]AT_PARAM_IF([[&result, &count]])[); fclose (input); if (global_result != result) abort (); @@ -572,7 +562,7 @@ AT_CHECK_CALC_LALR([%yacc]) AT_CHECK_CALC_LALR([%error-verbose]) AT_CHECK_CALC_LALR([%pure-parser %locations]) -AT_CHECK_CALC_LALR([%push-parser %locations %skeleton "push.c"]) +AT_CHECK_CALC_LALR([%push-parser %pure-parser %locations %skeleton "push.c"]) AT_CHECK_CALC_LALR([%error-verbose %locations]) AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) @@ -581,7 +571,7 @@ AT_CHECK_CALC_LALR([%debug]) AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR([%push-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %skeleton "push.c"]) +AT_CHECK_CALC_LALR([%push-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %skeleton "push.c"]) AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) Index: tests/headers.at =================================================================== RCS file: /sources/bison/bison/tests/headers.at,v retrieving revision 1.15 diff -p -u -r1.15 headers.at --- tests/headers.at 2 Dec 2006 01:52:16 -0000 1.15 +++ tests/headers.at 18 Dec 2006 08:12:21 -0000 @@ -94,7 +94,9 @@ AT_DATA_GRAMMAR([input.y], #include #include -static int +int my_lex (void); + +int my_lex (void) { return EOF; @@ -118,7 +120,11 @@ AT_DATA([caller.c], [[#include "input.h" YYLTYPE *my_llocp = &my_lloc; +#ifndef YYPSTATE_DECLS int my_parse (void); +#else +int my_lex (void); +#endif int main (void) Index: tests/input.at =================================================================== RCS file: /sources/bison/bison/tests/input.at,v retrieving revision 1.64 diff -p -u -r1.64 input.at --- tests/input.at 21 Nov 2006 07:07:35 -0000 1.64 +++ tests/input.at 18 Dec 2006 08:12:21 -0000 @@ -470,7 +470,7 @@ char quote[] = "@:>@@:>@,"; %{ static void yyerror (const char *s); -static int yylex (void); +int yylex (void); %} %type '@<:@' @@ -503,7 +503,7 @@ value_as_yystype (value val) return res; } -static int +int yylex (void) { static char const input[] = "@<:@address@hidden@address@hidden@&address@hidden @@ -529,7 +529,11 @@ AT_DATA([main.c], [[typedef int value; #include "input.h" +#ifndef YYPSTATE_DECLS int yyparse (void); +#else +int yylex (void); +#endif int main (void) Index: tests/local.at =================================================================== RCS file: /sources/bison/bison/tests/local.at,v retrieving revision 1.19 diff -p -u -r1.19 local.at --- tests/local.at 7 Dec 2006 02:21:13 -0000 1.19 +++ tests/local.at 18 Dec 2006 08:12:21 -0000 @@ -60,8 +60,8 @@ m4_pushdef([AT_PURE_IF], [m4_bmatch([$3], [%pure-parser], [$1], [$2])]) m4_pushdef([AT_PUSH_IF], [m4_bmatch([$3], [%push-parser], [$1], [$2])]) -m4_pushdef([AT_PURE_OR_PUSH_IF], -[m4_bmatch([$3], [%pure-parser\|%push-parser], [$1], [$2])]) +m4_pushdef([AT_YACC_OR_PUSH_IF], +[AT_YACC_IF([$1], [AT_PUSH_IF([$1], [$2])])]) m4_pushdef([AT_PURE_AND_LOC_IF], [m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations], [$1], [$2])]) @@ -76,17 +76,17 @@ m4_pushdef([AT_YYERROR_ARG_LOC_IF], [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])], [$2])]) # yyerror always sees the locations (when activated), except if -# push or (yacc & pure & !param). +# (yacc & pure & !param). FIXME: This is wrong. See the manual. m4_pushdef([AT_YYERROR_SEES_LOC_IF], -[AT_PUSH_IF([$2],[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])], - [$1])], - [$1])], - [$2])])]) +[AT_LOCATION_IF([AT_YACC_OR_PUSH_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])], + [$1])], + [$1])], + [$2])]) # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. m4_pushdef([AT_PURE_LEX_IF], -[AT_PURE_OR_PUSH_IF([$1], +[AT_PURE_IF([$1], [AT_SKEL_CC_IF([$1], [$2])])]) AT_PURE_LEX_IF(