From: Joel E. Denny <jdenny@ces.clemson.edu> Date: Mon, 25 Dec 2006 18:21:52 +0000 (+0000) Subject: For push mode, add pull wrappers around yypush_parse. X-Git-Tag: v2.3b~206 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/c3d503425f8014b432601a33b3398446d63b5963 For push mode, add pull wrappers around yypush_parse. * data/push.c: (b4_generate_macro_args, b4_parenthesize): New macros. (yypull_parse): New function wrapping yypush_parse. (yyparse): New #define wrapping yypull_parse. * tests/calc.at (_AT_DATA_CALC_Y): Call yyparse even when %push-parser is declared. * tests/headers.at (export YYLTYPE): Make yylex global. For push mode, prototype yylex in the module that calls yyparse, and don't prototype yyparse there. Otherwise, the yyparse expansion won't compile. * tests/input.at (Torturing the Scanner): Likewise. --- diff --git a/ChangeLog b/ChangeLog index 41bbbfed..e6fd29ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-12-25 Joel E. Denny <jdenny@ces.clemson.edu> + + For push mode, add pull wrappers around yypush_parse. + * data/push.c: (b4_generate_macro_args, b4_parenthesize): New macros. + (yypull_parse): New function wrapping yypush_parse. + (yyparse): New #define wrapping yypull_parse. + * tests/calc.at (_AT_DATA_CALC_Y): Call yyparse even when %push-parser + is declared. + * tests/headers.at (export YYLTYPE): Make yylex global. For push mode, + prototype yylex in the module that calls yyparse, and don't prototype + yyparse there. Otherwise, the yyparse expansion won't compile. + * tests/input.at (Torturing the Scanner): Likewise. + 2006-12-25 Joel E. Denny <jdenny@ces.clemson.edu> Enable push parsers to operate in impure mode. Thus, %push-parser no diff --git a/data/push.c b/data/push.c index 958d596d..8e576f28 100644 --- a/data/push.c +++ b/data/push.c @@ -63,6 +63,31 @@ 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. ## @@ -152,6 +177,7 @@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl ' 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], @@ -222,6 +248,7 @@ 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]]]) @@ -230,6 +257,10 @@ b4_c_function_decl([[yypush_parse]], [[int]], [[[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]))[ #endif ]]) @@ -1065,6 +1096,31 @@ b4_push_if( 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; +} + /* Initialize the parser data structure. */ ]b4_c_function_def([[yypstate_new]], [[yypstate *]])[ { @@ -1651,6 +1707,7 @@ 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]], @@ -1660,6 +1717,10 @@ b4_c_function_decl([b4_prefix[push_parse]], [[int]], [[[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]))[ #endif ]]) diff --git a/tests/calc.at b/tests/calc.at index 2089cd8e..70e13e25 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -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 (); diff --git a/tests/headers.at b/tests/headers.at index 4168531c..4a4a72e3 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -94,7 +94,9 @@ AT_DATA_GRAMMAR([input.y], #include <stdio.h> #include <stdlib.h> -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 YYPUSH_DECLS int my_parse (void); +#else +int my_lex (void); +#endif int main (void) diff --git a/tests/input.at b/tests/input.at index 5686caa4..fd389a58 100644 --- a/tests/input.at +++ b/tests/input.at @@ -470,7 +470,7 @@ char quote[] = "@:>@@:>@,"; %{ static void yyerror (const char *s); -static int yylex (void); +int yylex (void); %} %type <ival> '@<:@' @@ -503,7 +503,7 @@ value_as_yystype (value val) return res; } -static int +int yylex (void) { static char const input[] = "@<:@\1\2$@{@oline@__@&t@oline__\ @@ -529,7 +529,11 @@ AT_DATA([main.c], [[typedef int value; #include "input.h" +#ifndef YYPUSH_DECLS int yyparse (void); +#else +int yylex (void); +#endif int main (void)