diff --git a/NEWS b/NEWS index 79fdb8ef..7b75972c 100644 --- a/NEWS +++ b/NEWS @@ -8,14 +8,14 @@ GNU Bison NEWS and yyparse. The %lex-param, %parse-param, and %param directives support one or more arguments. Instead of - %lex-param {arg1_type *arg1} - %lex-param {arg2_type *arg2} - %parse-param {arg1_type *arg1} - %parse-param {arg2_type *arg2} + %lex-param {arg1_type *arg1} + %lex-param {arg2_type *arg2} + %parse-param {arg1_type *arg1} + %parse-param {arg2_type *arg2} one may now declare - %param {arg1_type *arg1} {arg2_type *arg2} + %param {arg1_type *arg1} {arg2_type *arg2} ** Java skeleton improvements @@ -38,10 +38,10 @@ GNU Bison NEWS the generated files. This is especially useful to avoid collisions with identifiers in the target language. For instance - %token FILE for ERROR - %define api.tokens.prefix "TOK_" - %% - start: FILE for ERROR; + %token FILE for ERROR + %define api.tokens.prefix "TOK_" + %% + start: FILE for ERROR; will generate the definition of the symbols TOK_FILE, TOK_for, and TOK_ERROR in the generated sources. In particular, the scanner must @@ -68,6 +68,47 @@ GNU Bison NEWS allow the programmer to prune possible parses based on the values of runtime expressions. +* Noteworthy changes in release ?.? (????-??-??) [?] + +** Future changes: + + The next major release will drop support for generating parsers in K&R C, + and remove the definition of yystype (removal announced since Bison + 1.875). + +** The generated header is included (yacc.c) + + Instead of duplicating the content of the generated header (definition of + YYSTYPE, yyltype etc.), the generated parser now includes it, as was + already the case for GLR or C++ parsers. + +** Headers (yacc.c, glr.c, glr.cc) + +*** Guards + + The generated headers are now guarded, as is already the case for C++ + parsers (lalr1.cc). For intance, with --defines=foo.h: + + #ifndef YY_FOO_H + # define YY_FOO_H + ... + #endif /* !YY_FOO_H */ + +*** New declarations + + The generated header now declares yydebug and yyparse. Both honor + --name-prefix=bar_, and yield + + int bar_parse (void); + + rather than + + #define yyparse bar_parse + int yyparse (void); + + in order to facilitate the inclusion of several parser headers inside a + single compilation unit. + * Noteworthy changes in release 2.5.1 (2012-06-05) [stable] ** Future changes: diff --git a/data/c.m4 b/data/c.m4 index 2b7e9d63..2601d561 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -604,3 +604,15 @@ typedef struct YYLTYPE # define YYLTYPE_IS_TRIVIAL 1 #endif]]) ]) + +# b4_declare_yydebug +# ------------------ +m4_define([b4_declare_yydebug], +[[/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG ]b4_parse_trace_if([1], [0])[ +#endif +#if YYDEBUG +extern int ]b4_prefix[debug; +#endif][]dnl +]) diff --git a/data/glr.c b/data/glr.c index 1463a9a7..f4efca2c 100644 --- a/data/glr.c +++ b/data/glr.c @@ -171,9 +171,11 @@ m4_define([b4_rhs_location], # Declaration that might either go into the header (if --defines) # or open coded in the parser body. m4_define([b4_shared_declarations], -[b4_percent_code_get([[requires]])[ +[b4_declare_yydebug[ +]b4_percent_code_get([[requires]])[ ]b4_token_enums(b4_tokens)[ ]b4_declare_yylstype[ +]b4_c_ansi_function_decl(b4_prefix[parse], [int], b4_parse_param)[ ]b4_percent_code_get([[provides]])[]dnl ]) @@ -213,11 +215,6 @@ m4_if(b4_prefix, [yy], [], ]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]], [b4_shared_declarations])[ -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG ]b4_parse_trace_if([1], [0])[ -#endif - /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE @@ -417,9 +414,6 @@ dnl We probably ought to introduce a type for confl. ]b4_conflicting_rules[ }; -/* Prevent warning if -Wmissing-prototypes. */ -]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[ - /* Error token number */ #define YYTERROR 1 @@ -2626,15 +2620,12 @@ m4_if(b4_skeleton, ["glr.c"], [b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison GLR parsers in C], - [2002-2012]) + [2002-2012])[ -b4_shared_declarations - -b4_pure_if([], -[[extern YYSTYPE ]b4_prefix[lval;]]) - -b4_locations_if([b4_pure_if([], -[extern YYLTYPE ]b4_prefix[lloc;]) -]) -])])[]dnl +]b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_shared_declarations[ +]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; +]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[ +]b4_cpp_guard_close([b4_spec_defines_file])[ +]])]) m4_divert_pop(0) diff --git a/data/glr.cc b/data/glr.cc index 117c7148..9a9d7764 100644 --- a/data/glr.cc +++ b/data/glr.cc @@ -226,8 +226,7 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C++], /* C++ GLR parser skeleton written by Akim Demaille. */ -#ifndef PARSER_HEADER_H -# define PARSER_HEADER_H +]b4_cpp_guard_open([b4_spec_defines_file])[ ]b4_percent_code_get([[requires]])[ @@ -333,8 +332,6 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]], #endif ]b4_namespace_close[ - -]b4_percent_code_get([[provides]])[]dnl - -[#endif /* ! defined PARSER_HEADER_H */] -m4_divert_pop(0) +]b4_percent_code_get([[provides]])[ +]b4_cpp_guard_close([b4_spec_defines_file])[ +]m4_divert_pop(0) diff --git a/data/yacc.c b/data/yacc.c index 922a4ebe..56be747a 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -226,6 +226,62 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[ yytype_int16 *yyes; YYSIZE_T yyes_capacity;]])]) + +# b4_declare_yyparse_push_ +# ------------------------ +m4_define([b4_declare_yyparse_push_], +[[typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; +enum { YYPUSH_MORE = 4 }; +]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_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]]])dnl +]) + +# b4_declare_yyparse_ +# ------------------- +# When not the push parser. +m4_define([b4_declare_yyparse_], +[[#ifdef YYPARSE_PARAM +]b4_c_function_decl(b4_prefix[parse], [int], + [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[ +#else /* ! YYPARSE_PARAM */ +]b4_c_function_decl(b4_prefix[parse], [int], b4_parse_param)[ +#endif /* ! YYPARSE_PARAM */]dnl +]) + + +# b4_declare_yyparse +# ------------------ +m4_define([b4_declare_yyparse], +[b4_push_if([b4_declare_yyparse_push_], + [b4_declare_yyparse_])[]dnl +]) + + +# b4_shared_declarations +# ---------------------- +# Declaration that might either go into the header (if --defines) +# or open coded in the parser body. +m4_define([b4_shared_declarations], +[b4_declare_yydebug[ +]b4_percent_code_get([[requires]])[ +]b4_token_enums_defines(b4_tokens)[ +]b4_declare_yylstype[ +]b4_declare_yyparse[ +]b4_percent_code_get([[provides]])[]dnl +]) + ## -------------- ## ## Output files. ## ## -------------- ## @@ -269,11 +325,6 @@ m4_if(b4_prefix, [yy], [], ]b4_null_define[ -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG ]b4_parse_trace_if([1], [0])[ -#endif - /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE @@ -287,34 +338,10 @@ m4_if(b4_prefix, [yy], [], # define YYTOKEN_TABLE ]b4_token_table[ #endif -]b4_percent_code_get([[requires]])[ -]b4_token_enums_defines(b4_tokens)[ -]b4_declare_yylstype[ -]b4_push_if([[ -#ifndef YYPUSH_DECLS -# define YYPUSH_DECLS -struct yypstate; -typedef struct yypstate yypstate; -enum { YYPUSH_MORE = 4 }; +]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]], + [b4_shared_declarations])[ -]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_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]]) - -b4_percent_code_get([[provides]])[]dnl - -[/* Copy the second part of user declarations. */ +/* Copy the second part of user declarations. */ ]b4_user_post_prologue b4_percent_code_get[]dnl @@ -1298,20 +1325,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } #endif /* YYERROR_VERBOSE */ -]b4_yydestruct_generate([b4_c_function_def])b4_push_if([], [[ +]b4_yydestruct_generate([b4_c_function_def])[ - -/* Prevent warnings from -Wmissing-prototypes. */ -#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 */]])b4_pure_if([], [ +]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 @@ -1976,37 +1995,13 @@ yypushreturn:]])[ ]b4_epilogue[]dnl b4_defines_if( [@output(b4_spec_defines_file@)@ -b4_copyright([Bison interface for Yacc-like parsers in C])dnl +b4_copyright([Bison interface for Yacc-like parsers in C])[ -b4_percent_code_get([[requires]])[]dnl - -b4_token_enums_defines(b4_tokens)[ -]b4_declare_yylstype[ +]b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_shared_declarations[ ]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; -]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])dnl -b4_push_if([[ -#ifndef YYPUSH_DECLS -# define YYPUSH_DECLS -struct ]b4_prefix[pstate; -typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; -enum { YYPUSH_MORE = 4 }; -]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_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 -]]) -b4_percent_code_get([[provides]])[]dnl -])dnl b4_defines_if +]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[ +]b4_cpp_guard_close([b4_spec_defines_file])[ +]])dnl b4_defines_if m4_divert_pop(0) m4_popdef([b4_copyright_years]) diff --git a/tests/actions.at b/tests/actions.at index 8be86f07..84529bef 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -28,14 +28,13 @@ AT_SETUP([Mid-rule actions]) # instead of being attached to the empty rule dedicated to this # action. +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%define parse.error verbose %debug %{ -# include -# include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} %% exp: { putchar ('0'); } @@ -51,28 +50,15 @@ exp: { putchar ('0'); } { putchar ('\n'); } ; %% -static int -yylex (void) -{ - static char const input[] = "123456789"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE(123456789)[ int main (void) { return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-d -v -o input.c input.y]) AT_COMPILE([input]) @@ -92,14 +78,13 @@ AT_CLEANUP AT_SETUP([Exotic Dollars]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%define parse.error verbose %debug %{ -# include -# include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(Var) %} @@ -130,21 +115,8 @@ sum_of_the_five_previous_values: ; %% -static int -yylex (void) -{ - static int called; - if (called++) - abort (); - return EOF; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([])[ int main (void) { @@ -165,8 +137,8 @@ AT_DATA_GRAMMAR([[input.y]], [[ %{ # include - static int yylex (void); - static void yyerror (char const *msg); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ typedef struct { int val; } stype; # define YYSTYPE stype %} @@ -185,12 +157,7 @@ yylex (void) return 0; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int main (void) { @@ -204,6 +171,7 @@ AT_PARSER_CHECK([[./input]], [[0]], [[6 ]]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP @@ -245,7 +213,7 @@ AT_LALR1_CC_IF([%define global_tokens_and_yystype]) m4_ifval([$6], [[%code provides {]], [[%code {]]) AT_LALR1_CC_IF([typedef yy::location YYLTYPE;]) [static int yylex (]AT_LEX_FORMALS[); -]AT_LALR1_CC_IF([], [static void yyerror (const char *msg);]) +]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE]) [} ]m4_ifval([$6], [%type '(' 'x' 'y' ')' ';' thing line input END])[ @@ -593,7 +561,8 @@ Parsing FAILED (status 2). ]]) ]) -]) +AT_BISON_OPTION_POPDEFS +])# _AT_CHECK_PRINTER_AND_DESTRUCTOR # AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG]) @@ -632,7 +601,7 @@ AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union]) # called for $end, and that $$ and @$ work correctly. AT_SETUP([Default tagless %printer and %destructor]) - +AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input.y]], [[%define parse.error verbose %debug @@ -645,8 +614,8 @@ AT_DATA_GRAMMAR([[input.y]], %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYLEX_DECLARE[ +]AT_YYERROR_DECLARE[ # define USE(SYM) %} @@ -677,25 +646,8 @@ AT_DATA_GRAMMAR([[input.y]], start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ; %% - -static int -yylex (void) -{ - static char const input[] = "abcd"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - yylval = input[toknum++]; - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = toknum; - return yylval; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([abcd], [[yylval = res]])[ int main (void) @@ -741,6 +693,7 @@ Cleanup: discarding lookahead token $end (1.5-1.5: ) Stack now 0 ]]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP @@ -750,7 +703,7 @@ AT_CLEANUP ## ------------------------------------------------------ ## AT_SETUP([Default tagged and per-type %printer and %destructor]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%define parse.error verbose %debug @@ -758,8 +711,8 @@ AT_DATA_GRAMMAR([[input.y]], %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(SYM) %} @@ -805,22 +758,8 @@ start: ; %% - -static int -yylex (void) -{ - static char const input[] = "abcdef"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([abcdef])[ int main (void) @@ -878,6 +817,7 @@ Cleanup: discarding lookahead token $end () Stack now 0 ]]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP @@ -895,6 +835,7 @@ m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN], [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])], [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])]) +AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input]]$1[[.y]], [[%define parse.error verbose %debug @@ -907,8 +848,8 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]], %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(SYM) %} @@ -950,12 +891,7 @@ yylex (void) yylloc.first_column = yylloc.last_column = 1; return 0; } - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} +]AT_YYERROR_DEFINE[ int main (void) @@ -964,6 +900,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input$1.c input$1.y]) AT_COMPILE([input$1]) @@ -1010,15 +947,15 @@ AT_SETUP([Default %printer and %destructor are not for error or $undefined]) # semantic value, which would be initialized from the lookahead, which # would be destroyed separately. # - For $undefined, who knows what the semantic value would be. - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%debug %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(SYM) %} @@ -1039,24 +976,8 @@ start: ; %% - -static int -yylex (void) -{ - static char const input[] = "abd"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - yylval = input[toknum++]; - return yylval; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([abd], [yylval = res])[ int main (void) { @@ -1064,6 +985,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input]) @@ -1125,14 +1047,15 @@ AT_SETUP([Default %printer and %destructor are not for $accept]) # true for $undefined and the error token, so there are three warnings for # %printer and three for %destructor.) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%debug /* So that %printer is actually compiled. */ %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(SYM) %} @@ -1153,28 +1076,15 @@ AT_DATA_GRAMMAR([[input.y]], start: { USE($$); } ; %% - -static int -yylex (void) -{ - static int called; - if (called++) - abort (); - return 0; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([])[ int main (void) { return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input]) @@ -1189,14 +1099,15 @@ AT_CLEANUP AT_SETUP([Default %printer and %destructor for mid-rule values]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%debug /* So that %printer is actually compiled. */ %{ # include # include - static void yyerror (const char *msg); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ # define USE(SYM) # define YYLTYPE int # define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs) @@ -1220,22 +1131,8 @@ start: ; %% - -static int -yylex (void) -{ - static int called; - if (called++) - abort (); - return 0; -} - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([])[ int main (void) { @@ -1243,6 +1140,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y], 0,, [[input.y:33.3-23: warning: unset value: $$ @@ -1296,15 +1194,15 @@ AT_CLEANUP # Bison once forgot to check for @$ in actions other than semantic actions. # AT_CHECK_ACTION_LOCATIONS(ACTION-DIRECTIVE) -# ------------------------------------------------------- +# ------------------------------------------- m4_define([AT_CHECK_ACTION_LOCATIONS], [AT_SETUP([[@$ in ]$1[ implies %locations]]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%code { #include - static int yylex (void); - static void yyerror (char const *msg); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ } %debug @@ -1325,12 +1223,7 @@ yylex (void) return 0; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int main (void) { @@ -1340,7 +1233,7 @@ main (void) AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) - +AT_BISON_OPTION_POPDEFS AT_CLEANUP]) AT_CHECK_ACTION_LOCATIONS([[%initial-action]]) @@ -1357,7 +1250,7 @@ AT_SETUP([[Fix user actions without a trailing semicolon]]) # This feature is undocumented, but we accidentally broke it in 2.3a, # and there was a complaint at: # . - +AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], [[%% start: test2 test1 test0 testc; @@ -1407,6 +1300,7 @@ no_semi []"broken\" $ @ $$ @$ [];\ string;"} ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]], [0], [], [[input.y:8.48: warning: a ';' might be needed at the end of action code @@ -1462,13 +1356,14 @@ AT_CLEANUP AT_SETUP([[Destroying lookahead assigned by semantic action]]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[ %code { #include #include - static void yyerror (char const *); - static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ #define USE(Var) } @@ -1496,27 +1391,15 @@ accept: /*empty*/ { } ; %% - -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -static int -yylex (void) -{ - static char const *input = "a"; - return *input++; -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([a])[ int main (void) { return yyparse (); } ]]) - +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]], [[0]], [], @@ -1532,6 +1415,8 @@ AT_CLEANUP AT_SETUP([[YYBACKUP]]) +AT_BISON_OPTION_PUSHDEFS([%pure-parser]) + AT_DATA_GRAMMAR([input.y], [[ %error-verbose @@ -1542,7 +1427,7 @@ AT_DATA_GRAMMAR([input.y], # include # include - static void yyerror (const char *msg); + ]AT_YYERROR_DECLARE[ static int yylex (YYSTYPE *yylval); } %% @@ -1557,6 +1442,7 @@ exp: ; %% +]AT_YYERROR_DEFINE[ static int yylex (YYSTYPE *yylval) { @@ -1567,12 +1453,6 @@ yylex (YYSTYPE *yylval) return input[toknum++]; } -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - int main (void) { @@ -1580,6 +1460,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) diff --git a/tests/calc.at b/tests/calc.at index 477c92d3..5c6c4cc1 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -33,9 +33,80 @@ # Don't call this macro directly, because it contains some occurrences # of `$1' etc. which will be interpreted by m4. So you should call it # with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does. +# +# When %defines is not passed, generate a single self-contained file. +# Otherwise, generate three: calc.y with the parser, calc-lex.c with +# the scanner, and calc-main.c with "main()". This is in order to +# stress the use of the generated parser header. To avoid code +# duplication, AT_CALC_LEX and AT_CALC_MAIN contain the body of these +# two later files. m4_define([_AT_DATA_CALC_Y], [m4_if([$1$2$3], $[1]$[2]$[3], [], [m4_fatal([$0: Invalid arguments: $@])])dnl + +m4_pushdef([AT_CALC_MAIN], +[#include /* abort */ +#if HAVE_UNISTD_H +# include +#else +# undef alarm +# define alarm(seconds) /* empty */ +#endif + +AT_SKEL_CC_IF([[ +/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */ +int +]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[ +{ + ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[; +#if YYDEBUG + parser.set_debug_level (1); +#endif + return parser.parse (); +} +]])[ + +semantic_value global_result = 0; +int global_count = 0; + +/* A C main function. */ +int +main (int argc, const char **argv) +{ + semantic_value result = 0; + int count = 0; + int status; + + /* This used to be alarm (10), but that isn't enough time for + a July 1995 vintage DEC Alphastation 200 4/100 system, + according to Nelson H. F. Beebe. 100 seconds is enough. */ + alarm (100); + + if (argc == 2) + input = fopen (argv[1], "r"); + else + input = stdin; + + if (!input) + { + perror (argv[1]); + return 3; + } + +]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug], +[ ]AT_NAME_PREFIX[debug = 1;])])[ + status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[); + if (fclose (input)) + perror ("fclose"); + if (global_result != result) + abort (); + if (global_count != count) + abort (); + return status; +} +]]) + + m4_pushdef([AT_CALC_LEX], [[#include @@ -198,7 +269,9 @@ AT_SKEL_CC_IF( { #include /* The input. */ -extern FILE *input;]AT_SKEL_CC_IF([[ +extern FILE *input; +extern semantic_value global_result; +extern int global_count;]AT_SKEL_CC_IF([[ #ifndef YYLTYPE # define YYLTYPE ]AT_NAME_PREFIX[::parser::location_type #endif @@ -208,19 +281,10 @@ extern FILE *input;]AT_SKEL_CC_IF([[ %code { #include -#include #include -#if HAVE_UNISTD_H -# include -#else -# undef alarm -# define alarm(seconds) /* empty */ -#endif #define USE(Var) FILE *input; -static semantic_value global_result = 0; -static int global_count = 0; static int power (int base, int exponent); ]AT_SKEL_CC_IF(, @@ -289,6 +353,16 @@ exp: ; %% +static int +power (int base, int exponent) +{ + int res = 1; + assert (0 <= exponent); + for (/* Niente */; exponent; --exponent) + res *= base; + return res; +} + ]AT_SKEL_CC_IF( [AT_LOCATION_TYPE_IF([[ std::ostream& @@ -309,17 +383,6 @@ AT_NAME_PREFIX::parser::error (AT_LOCATION_IF([const location_type& l, ])const s { std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl; } - -/* A C++ yyparse that simulates the C signature. */ -int -yyparse (AT_PARAM_IF([semantic_value *result, int *count])) -{ - AT_NAME_PREFIX::parser parser[]AT_PARAM_IF([ (result, count)]); -#if YYDEBUG - parser.set_debug_level (1); -#endif - return parser.parse (); -} ], [/* A C error reporting function. */ static void @@ -341,59 +404,21 @@ AT_YYERROR_SEES_LOC_IF([ fprintf (stderr, "%s\n", s); }])[ -]AT_DEFINES_IF(, [AT_CALC_LEX])[ - -static int -power (int base, int exponent) -{ - int res = 1; - assert (0 <= exponent); - for (/* Niente */; exponent; --exponent) - res *= base; - return res; -} - - -/* A C main function. */ -int -main (int argc, const char **argv) -{ - semantic_value result = 0; - int count = 0; - int status; - - /* This used to be alarm (10), but that isn't enough time for - a July 1995 vintage DEC Alphastation 200 4/100 system, - according to Nelson H. F. Beebe. 100 seconds is enough. */ - alarm (100); - - if (argc == 2) - input = fopen (argv[1], "r"); - else - input = stdin; - - if (!input) - { - perror (argv[1]); - return 3; - } - -]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug], -[ yydebug = 1;])])[ - status = yyparse (]AT_PARAM_IF([[&result, &count]])[); - if (fclose (input)) - perror ("fclose"); - if (global_result != result) - abort (); - if (global_count != count) - abort (); - return status; -} +]AT_DEFINES_IF([], +[AT_CALC_LEX +AT_CALC_MAIN])[ ]]) + AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])], [[#include "calc.h]AT_SKEL_CC_IF([[h]])[" -]AT_CALC_LEX])]) +]AT_CALC_LEX]) +AT_DATA_SOURCE([[calc-main.c]AT_SKEL_CC_IF([[c]])], +[[#include "calc.h]AT_SKEL_CC_IF([[h]])[" + +]AT_CALC_MAIN]) +]) +m4_popdef([AT_CALC_MAIN]) m4_popdef([AT_CALC_LEX]) ])# _AT_DATA_CALC_Y @@ -506,7 +531,7 @@ m4_ifval([$2], [AT_CHECK([exit 77])]) AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_CALC_Y([$1]) -AT_FULL_COMPILE([calc], [AT_DEFINES_IF([[lex]])]) +AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]])) # Test the priorities. _AT_CHECK_CALC([$1], diff --git a/tests/conflicts.at b/tests/conflicts.at index 599d708b..6c71a368 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -49,6 +49,7 @@ AT_CLEANUP AT_SETUP([%nonassoc and eof]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[ %{ @@ -57,12 +58,7 @@ AT_DATA_GRAMMAR([input.y], #include #define YYERROR_VERBOSE 1 -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ /* The current argument. */ static const char *input; @@ -92,6 +88,7 @@ main (int argc, const char *argv[]) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS m4_pushdef([AT_NONASSOC_AND_EOF_CHECK], [AT_BISON_CHECK([$1[ -o input.c input.y]]) @@ -169,7 +166,7 @@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRAMMAR])([input.y], #include ]], [[ #include #include - void yyerror (char const *msg);]])[ + ]AT_YYERROR_DECLARE])[ ]AT_YYLEX_PROTOTYPE[; #define USE(Var) } @@ -210,31 +207,11 @@ public Object getLVal () *lvalp = 1; return *input++; }]])[ - -/*----------. -| yyerror. | -`----------*/]AT_SKEL_JAVA_IF([[ - -public void yyerror (String msg) -{ - System.err.println (msg); -} - +]AT_YYERROR_DEFINE[ +]AT_SKEL_JAVA_IF([[ }; -%%]], [AT_SKEL_CC_IF([[ - -void -yy::parser::error (std::string const &msg) -{ - std::cerr << msg << std::endl; -}]], [[ - -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -}]])])[ +%%]])[ /*-------. | main. | @@ -465,12 +442,12 @@ AT_CLEANUP # with minimal LR parser tables. AT_SETUP([[LAC: %nonassoc requires splitting canonical LR states]]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[%code { #include - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ } %error-verbose @@ -507,19 +484,8 @@ look: reduce-nonassoc: %prec 'a'; %% - -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -int -yylex (void) -{ - char const *input = "aaa"; - return *input++; -} +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([aaa])[ int main (void) @@ -527,6 +493,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS # Show canonical LR's failure. AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]], diff --git a/tests/glr-regression.at b/tests/glr-regression.at index 4ac48611..67c60707 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -24,6 +24,7 @@ AT_BANNER([[GLR Regression Tests]]) AT_SETUP([Badly Collapsed GLR States]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr1.y], [[/* Regression Test: Improper state compression */ /* Reported by Scott McPeak */ @@ -34,8 +35,8 @@ AT_DATA_GRAMMAR([glr-regr1.y], #define YYSTYPE int static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1); -int yylex (void); -void yyerror (char const *msg); +]AT_YYLEX_DECLARE[ +]AT_YYERROR_DECLARE[ %} @@ -71,12 +72,7 @@ main (void) return yyparse (); } -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int yylex (void) @@ -94,6 +90,7 @@ yylex (void) } } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [], [glr-regr1.y: conflicts: 1 shift/reduce @@ -119,6 +116,7 @@ AT_CLEANUP AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr2a.y], [[/* Regression Test: Improper handling of embedded actions and $-N */ /* Reported by S. Eken */ @@ -130,8 +128,8 @@ AT_DATA_GRAMMAR([glr-regr2a.y], #include #include #include - int yylex (void); - void yyerror (char const *); + ]AT_YYLEX_DECLARE[ + ]AT_YYERROR_DECLARE[ %} %glr-parser @@ -171,7 +169,7 @@ var_printer: 'v' { printf ("Variable: '%s'\n", $-1); } %% - +]AT_YYERROR_DEFINE[ FILE *input; int @@ -181,7 +179,8 @@ yylex (void) char *s; if (feof (stdin)) abort (); - switch (fscanf (input, " %1[a-z,]", buf)) { + switch (fscanf (input, " %1[a-z,]", buf)) + { case 1: return buf[0]; case EOF: @@ -199,11 +198,6 @@ yylex (void) return 'V'; } -void -yyerror (char const *s) -{ printf ("%s\n", s); -} - int main (int argc, char **argv) { @@ -212,6 +206,7 @@ main (int argc, char **argv) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [], [glr-regr2a.y: conflicts: 2 shift/reduce @@ -238,6 +233,7 @@ AT_CLEANUP AT_SETUP([Improper merging of GLR delayed action sets]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr3.y], [[/* Regression Test: Improper merging of GLR delayed action sets. */ /* Reported by M. Rosien */ @@ -248,8 +244,8 @@ AT_DATA_GRAMMAR([glr-regr3.y], #include static int MergeRule (int x0, int x1); -static void yyerror (char const * s); -int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ #define RULE(x) (1 << (x)) @@ -290,13 +286,12 @@ NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge %% -static int MergeRule (int x0, int x1) { +static int +MergeRule (int x0, int x1) +{ return x0 | x1; } - -static void yyerror(char const * s) { - fprintf(stderr,"error: %s\n",s); -} +]AT_YYERROR_DEFINE[ FILE *input = YY_NULL; @@ -320,12 +315,15 @@ int yylex (void) return BAD_CHAR; } -int main(int argc, char* argv[]) { +int +main(int argc, char* argv[]) +{ input = stdin; if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3; return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [], [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce @@ -347,6 +345,7 @@ AT_CLEANUP AT_SETUP([Duplicate representation of merged trees]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr4.y], [[ %union { char *ptr; } @@ -359,8 +358,8 @@ AT_DATA_GRAMMAR([glr-regr4.y], #include static char *merge (YYSTYPE, YYSTYPE); static char *make_value (char const *, char const *); - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static char *ptrs[100]; static char **ptrs_next = ptrs; %} @@ -384,16 +383,8 @@ A2: 'a' { $$ = make_value ("A2", "'a'"); } ; B: 'a' { $$ = make_value ("B", "'a'"); } ; %% - -static int -yylex (void) -{ - static char const input[] = "a"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([a])[ int main (void) @@ -423,13 +414,8 @@ merge (YYSTYPE s1, YYSTYPE s2) sprintf (value, format, s1.ptr, s2.ptr); return value; } - -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [], [glr-regr4.y: conflicts: 1 reduce/reduce @@ -450,13 +436,14 @@ AT_CLEANUP AT_SETUP([User destructor for unresolved GLR semantic value]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr5.y], [[ %{ #include #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */ %} @@ -480,29 +467,15 @@ start: ; %% - -static int -yylex (void) -{ - static char const input[] = "a"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} - -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYLEX_DEFINE(a)[ +]AT_YYERROR_DEFINE[ int main (void) { return yyparse () != 1; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [], [glr-regr5.y: conflicts: 1 reduce/reduce @@ -523,13 +496,14 @@ AT_CLEANUP AT_SETUP([User destructor after an error during a split parse]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr6.y], [[ %{ #include #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ %} %glr-parser @@ -556,18 +530,14 @@ yylex (void) return input[toknum++]; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int main (void) { return yyparse () != 1; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [], [glr-regr6.y: conflicts: 1 reduce/reduce @@ -590,13 +560,14 @@ AT_CLEANUP AT_SETUP([Duplicated user destructor for lookahead]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr7.y], [[ %{ #include #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ #define YYSTACKEXPANDABLE 0 typedef struct count_node { int count; @@ -641,12 +612,7 @@ yylex (void) return 'a'; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int main (void) { @@ -660,6 +626,7 @@ main (void) return status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [], [glr-regr7.y: conflicts: 2 reduce/reduce @@ -682,14 +649,15 @@ AT_CLEANUP AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr8.y], [[ %{ #include #include - static void yyerror (char const *); - static int yylex (void); - static void yyerror (char const *msg); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ + ]AT_YYERROR_DECLARE[ %} %token T_CONSTANT @@ -723,12 +691,7 @@ OptSignalWord : /* empty */ %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int lexIndex; int yylex (void) @@ -758,6 +721,7 @@ main (void) return 0; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [], [glr-regr8.y: conflicts: 1 reduce/reduce @@ -780,13 +744,14 @@ AT_CLEANUP AT_SETUP([No users destructors if stack 0 deleted]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr9.y], [[ %{ # include # include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ # define YYSTACKEXPANDABLE 0 static int tokens = 0; static int destructors = 0; @@ -822,12 +787,7 @@ yylex (void) return 'a'; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int main (void) { @@ -841,6 +801,7 @@ main (void) return !exit_status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [], [glr-regr9.y: conflicts: 1 reduce/reduce @@ -860,13 +821,14 @@ AT_CLEANUP AT_SETUP([Corrupted semantic options if user action cuts parse]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr10.y], [[ %{ # include # include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ #define GARBAGE_SIZE 50 static char garbage[GARBAGE_SIZE]; %} @@ -884,12 +846,7 @@ start: %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -908,6 +865,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [], [glr-regr10.y: conflicts: 1 reduce/reduce @@ -925,12 +883,13 @@ AT_CLEANUP AT_SETUP([Undesirable destructors if user action cuts parse]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr11.y], [[ %{ # include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static int destructors = 0; # define USE(val) %} @@ -949,21 +908,8 @@ start: %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -static int -yylex (void) -{ - static char const input[] = "a"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([a])[ int main (void) @@ -977,6 +923,7 @@ main (void) return exit_status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [], [glr-regr11.y: conflicts: 1 reduce/reduce @@ -994,6 +941,7 @@ AT_CLEANUP AT_SETUP([Leaked semantic values if user action cuts parse]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr12.y], [[ %glr-parser @@ -1007,8 +955,8 @@ AT_DATA_GRAMMAR([glr-regr12.y], %{ # include static int merge (YYSTYPE, YYSTYPE); - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static int parent_rhs_before_value = 0; static int merged_value = 0; static int parent_rhs_after_value = 0; @@ -1068,12 +1016,7 @@ merge (YYSTYPE s1, YYSTYPE s2) return dummy; } -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1108,6 +1051,7 @@ main (void) return exit_status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [], [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce @@ -1127,6 +1071,7 @@ AT_CLEANUP AT_SETUP([Incorrect lookahead during deterministic GLR]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr13.y], [[ /* Tests: @@ -1138,8 +1083,8 @@ AT_DATA_GRAMMAR([glr-regr13.y], %{ #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static void print_lookahead (char const *); #define USE(value) %} @@ -1190,12 +1135,7 @@ change_lookahead: %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1237,6 +1177,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], []) AT_COMPILE([glr-regr13]) @@ -1263,6 +1204,7 @@ AT_CLEANUP AT_SETUP([Incorrect lookahead during nondeterministic GLR]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr14.y], [[ /* Tests: @@ -1289,8 +1231,8 @@ AT_DATA_GRAMMAR([glr-regr14.y], %{ #include #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static void print_lookahead (char const *); static char merge (union YYSTYPE, union YYSTYPE); #define USE(value) @@ -1399,12 +1341,7 @@ no_look: %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1453,6 +1390,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [], [glr-regr14.y: conflicts: 3 reduce/reduce @@ -1483,6 +1421,7 @@ AT_CLEANUP AT_SETUP([Leaked semantic values when reporting ambiguity]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr15.y], [[ %glr-parser @@ -1490,8 +1429,8 @@ AT_DATA_GRAMMAR([glr-regr15.y], %{ # include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static int parent_rhs_before_value = 0; # define USE(val) %} @@ -1530,12 +1469,7 @@ ambiguity2: ; %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1557,6 +1491,7 @@ main (void) return exit_status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [], [glr-regr15.y: conflicts: 2 reduce/reduce @@ -1575,6 +1510,8 @@ AT_CLEANUP ## ------------------------------------------------------------------------- ## AT_SETUP([Leaked lookahead after nondeterministic parse syntax error]) + +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr16.y], [[ %glr-parser @@ -1582,8 +1519,8 @@ AT_DATA_GRAMMAR([glr-regr16.y], %{ # include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ static int lookahead_value = 0; # define USE(val) %} @@ -1596,12 +1533,7 @@ alt2: ; %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1626,6 +1558,7 @@ main (void) return exit_status; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [], [glr-regr16.y: conflicts: 1 reduce/reduce @@ -1644,6 +1577,8 @@ AT_CLEANUP ## ------------------------------------------------------------------------- ## AT_SETUP([Uninitialized location when reporting ambiguity]) + +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr17.y], [[ %glr-parser @@ -1713,6 +1648,7 @@ main (void) return yyparse () != 1; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [], [glr-regr17.y: conflicts: 3 reduce/reduce @@ -1731,12 +1667,14 @@ AT_CLEANUP ## -------------------------------------------------------------## AT_SETUP([Missed %merge type warnings when LHS type is declared later]) + +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([glr-regr18.y], [[%glr-parser %{ #include - static void yyerror (char const *); + ]AT_YYERROR_DECLARE[ static int yylex (); %} @@ -1758,27 +1696,15 @@ sym3: %merge { $$ = 0; } ; %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -static int -yylex () -{ - static int called; - if (called++) - abort (); - return 0; -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE()[ int main (void) { return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [], [glr-regr18.y:26.18-24: result type clash on merge function 'merge': != @@ -1796,13 +1722,14 @@ AT_CLEANUP AT_SETUP([Ambiguity reports]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[ %{ #include #include - static void yyerror (char const *); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ %} %debug @@ -1816,23 +1743,8 @@ start: b: 'b'; d: /* nada. */; %% - -static int -yylex (void) -{ - static char const input[] = "abc"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} - -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYLEX_DEFINE([abc])[ +]AT_YYERROR_DEFINE[ int main (void) { @@ -1840,6 +1752,7 @@ main (void) return !!yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]], 0, [], [input.y: conflicts: 1 reduce/reduce diff --git a/tests/headers.at b/tests/headers.at index 9d4946d6..a28f2e1b 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -19,47 +19,26 @@ AT_BANNER([[Parser Headers.]]) -## ---------------------- ## -## %union and --defines. ## -## ---------------------- ## - - -AT_SETUP([%union and --defines]) - -AT_DATA([input.y], -[%union -{ - int integer; - char *string ; -} -%% -exp: {}; -]) - -AT_BISON_CHECK([--defines input.y]) - -AT_CLEANUP - - - ## --------------------- ## ## Invalid CPP headers. ## ## --------------------- ## -# AT_TEST_CPP_GUARD_H([INPUT-FILE-BASE) -# ------------------------------------- +# AT_TEST_CPP_GUARD_H(BASE-NAME, [DIRECTIVES]) +# -------------------------------------------- +# FIXME: Much of this can be covered by calc.at. m4_define([AT_TEST_CPP_GUARD_H], -[AT_SETUP([Invalid CPP guards: $1]) - +[AT_SETUP([Invalid CPP guards: $2 --defines=$1.h]) +AT_BISON_OPTION_PUSHDEFS([$2]) # Possibly create inner directories. dirname=`AS_DIRNAME([$1])` AS_MKDIR_P([$dirname]) AT_DATA_GRAMMAR([$1.y], -[%{ +[$2 +%{ #include <$1.h> -void yyerror (const char *); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %% dummy:; @@ -67,15 +46,18 @@ dummy:; #include <$1.h> ]) -AT_BISON_CHECK([--defines=$1.h --output=y.tab.c $1.y]) +AT_BISON_CHECK([--defines=$1.h --output=$1.c $1.y]) -AT_COMPILE([y.tab.o], [-I. -c y.tab.c]) +AT_COMPILE([$1.o], [-I. -c $1.c]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP ]) AT_TEST_CPP_GUARD_H([input/input]) AT_TEST_CPP_GUARD_H([9foo]) +AT_TEST_CPP_GUARD_H([input/input], [%glr-parser]) +AT_TEST_CPP_GUARD_H([9foo], [%glr-parser]) diff --git a/tests/input.at b/tests/input.at index d0bc51a7..d94b652e 100644 --- a/tests/input.at +++ b/tests/input.at @@ -386,7 +386,7 @@ AT_CLEANUP AT_SETUP([Torturing the Scanner]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], []) AT_BISON_CHECK([input.y], [1], [], [[input.y:1.1: syntax error, unexpected end of file @@ -463,8 +463,8 @@ char quote[] = "@:>@@:>@,"; %} %{ -static void yyerror (const char *s); -static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} %type '@<:@' @@ -496,7 +496,7 @@ value_as_yystype (value val) res.ival = val; return res; } - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -509,12 +509,6 @@ yylex (void) yylval = value_as_yystype (input[toknum]); return input[toknum++]; } - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} ]]) # Pacify Emacs'font-lock-mode: " @@ -531,6 +525,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-d -v -o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -616,14 +611,15 @@ AT_CLEANUP AT_SETUP([Symbols]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%token WITH-DASH %token WITHOUT_DASH "WITHOUT-DASH" %token WITH.PERIOD %token WITHOUT_PERIOD "WITHOUT.PERIOD" %code { - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ } %% start: with-dash without_dash with.period without_period; @@ -632,7 +628,10 @@ without_dash: "WITHOUT-DASH"; with.period: WITH.PERIOD; without_period: "WITHOUT.PERIOD"; %% +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE[ ]]) +AT_BISON_OPTION_POPDEFS # POSIX Yacc accept periods, but not dashes. AT_BISON_CHECK([--yacc input.y], [1], [], diff --git a/tests/local.at b/tests/local.at index a53f1d17..0d24a44a 100644 --- a/tests/local.at +++ b/tests/local.at @@ -109,7 +109,7 @@ m4_pushdef([AT_SKEL_CC_IF], m4_pushdef([AT_SKEL_JAVA_IF], [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])]) m4_pushdef([AT_GLR_IF], -[m4_bmatch([$3], [%glr-parser\|%skeleton "glr\.], [$1], [$2])]) +[m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])]) m4_pushdef([AT_LALR1_CC_IF], [AT_SKEL_CC_IF([AT_GLR_IF([$2], [$1])], [$2])]) m4_pushdef([AT_GLR_CC_IF], @@ -135,7 +135,11 @@ m4_pushdef([AT_GLR_OR_PARAM_IF], [m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])]) m4_pushdef([AT_NAME_PREFIX], [m4_bmatch([$3], [%name-prefix ".*"], - [m4_bregexp([$3], [name-prefix "\([^"]*\)"], [\1])], + [m4_bregexp([$3], [name-prefix "\([^""]*\)"], [\1])], + [yy])]) +m4_pushdef([AT_API_PREFIX], +[m4_bmatch([$3], [%define api\.prefix ".*"], + [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])], [yy])]) m4_pushdef([AT_TOKEN_PREFIX], [m4_bmatch([$3], [%define api.tokens.prefix ".*"], @@ -207,6 +211,7 @@ m4_popdef([AT_LOC]) m4_popdef([AT_PURE_LEX_IF]) m4_popdef([AT_YYERROR_SEES_LOC_IF]) m4_popdef([AT_YYERROR_ARG_LOC_IF]) +m4_popdef([AT_API_PREFIX]) m4_popdef([AT_NAME_PREFIX]) m4_popdef([AT_GLR_OR_PARAM_IF]) m4_popdef([AT_PURE_AND_LOC_IF]) @@ -272,6 +277,70 @@ m4_define([AT_DATA_GRAMMAR], $2]) ]) +# AT_YYLEX_DECLARE_EXTERN +# AT_YYLEX_DECLARE +# AT_YYLEX_DEFINE(INPUT-STRING, [ACTION]) +# --------------------------------------- +m4_define([AT_YYLEX_DECLARE_EXTERN], +[int AT_API_PREFIX[]lex (void);dnl +]) + +m4_define([AT_YYLEX_DECLARE], +[static AT_YYLEX_DECLARE_EXTERN[]dnl +]) + +m4_define([AT_YYLEX_DEFINE], +[[#include /* abort */ +static int +]AT_API_PREFIX[lex (void) +{ + static char const input[] = "$1"; + static size_t toknum = 0; + int res; + if (! (toknum < sizeof input)) + abort (); + res = input[toknum++]; + ]$2;[]AT_LOCATION_IF([[ + ]AT_API_PREFIX[lloc.first_line = ]AT_API_PREFIX[lloc.last_line = 1; + ]AT_API_PREFIX[lloc.first_column = ]AT_API_PREFIX[lloc.last_column = toknum;]])[ + return res; +}]dnl +]) + +# AT_YYERROR_DECLARE_EXTERN +# AT_YYERROR_DECLARE +# AT_YYERROR_DEFINE +# ------------------------- +# Beware that must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS +# pair. +m4_define([AT_YYERROR_DECLARE_EXTERN], +[void AT_API_PREFIX[]error (const char *msg);dnl +]) + +m4_define([AT_YYERROR_DECLARE], +[static AT_YYERROR_DECLARE_EXTERN[]dnl +]) + +m4_define([AT_YYERROR_DEFINE], +[AT_SKEL_JAVA_IF([[public void yyerror (String msg) +{ + System.err.println (msg); +}]], [AT_SKEL_CC_IF([[void +yy::parser::error (const yy::location &, std::string const &msg) +{ + std::cerr << msg << std::endl; +}]], [[#include +static void +]AT_API_PREFIX[error (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +}]])])dnl +]) + +## --------------- ## +## Running Bison. ## +## --------------- ## + # AT_BISON_CHECK(BISON_ARGS, [OTHER_AT_CHECK_ARGS]) # ------------------------------------------------- # Check Bison by invoking `bison BISON_ARGS'. BISON_ARGS should not contain @@ -455,8 +524,8 @@ AT_CHECK([[test -n "$CONF_JAVA" || exit 77 AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], [[0]], [ignore], [ignore])]) -# AT_FULL_COMPILE(OUTPUT, [OTHER]) -# -------------------------------- +# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2]) +# ------------------------------------------- # Compile OUTPUT.y to OUTPUT.c, OUTPUT.cc, or OUTPUT.java, and then # compile it to OUTPUT or OUTPUT.class. If OTHER is specified, compile # OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or @@ -464,16 +533,27 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], # AT_SKEL_JAVA_IF. m4_define([AT_FULL_COMPILE], [ AT_SKEL_JAVA_IF([ - AT_BISON_CHECK([[-o ]$1[.java ]$1[.y]]) - AT_JAVA_COMPILE([$1[.java]]m4_ifval($2, - [[$1[.java ]$1[-]$2[.java]]])) + AT_BISON_CHECK([-o $1.java $1.y]) + AT_JAVA_COMPILE([$1.java], + m4_join([ ], + [$1.java], + m4_ifval($2, [[$1-$2.java]]), + m4_ifval($3, [[$1-$3.java]]))) ], [ AT_SKEL_CC_IF([ - AT_BISON_CHECK([[-o ]$1[.cc ]$1[.y]]) - AT_COMPILE_CXX([$1]m4_ifval($2, [, [$1[.cc ]$1[-]$2[.cc]]])) + AT_BISON_CHECK([-o $1.cc $1.y]) + AT_COMPILE_CXX([$1], + m4_join([ ], + [$1.cc], + m4_ifval($2, [[$1-$2.cc]]), + m4_ifval($3, [[$1-$3.cc]]))) ], [ - AT_BISON_CHECK([[-o ]$1[.c ]$1[.y]]) - AT_COMPILE([$1]m4_ifval($2, [, [$1[.c ]$1[-]$2[.c]]])) + AT_BISON_CHECK([-o $1.c $1.y]) + AT_COMPILE([$1], + m4_join([ ], + [$1.c], + m4_ifval($2, [[$1-$2.c]]), + m4_ifval($3, [[$1-$3.c]]))) ]) ]) ]) @@ -582,12 +662,12 @@ m4_define([AT_TEST_TABLES_AND_PARSE], [m4_pushdef([AT_COND_CASE], [m4_case([$2], $][@)]) AT_SETUP([$1]) - +AT_BISON_OPTION_PUSHDEFS([$4]) AT_DATA_GRAMMAR([[input.y]], [[%code { #include - static void yyerror (char const *msg); - static int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ } ]$4[ @@ -597,13 +677,7 @@ AT_DATA_GRAMMAR([[input.y]], ]$5[ %% - -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -659,6 +733,7 @@ AT_PARSER_CHECK([[./input]], m4_ifval([$11], [m4_dquote($11)]), m4_ifval([$12], [m4_dquote($12)])) +AT_BISON_OPTION_POPDEFS AT_CLEANUP m4_popdef([AT_COND_CASE])]) diff --git a/tests/named-refs.at b/tests/named-refs.at index 0b2f4c94..0e6f60c8 100644 --- a/tests/named-refs.at +++ b/tests/named-refs.at @@ -19,7 +19,7 @@ AT_BANNER([[Named references tests.]]) AT_SETUP([Tutorial calculator]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([test.y], [[ %{ @@ -33,8 +33,8 @@ FILE *input; static semantic_value global_result = 0; static int global_count = 0; static int power (int base, int exponent); -static void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} %union @@ -83,12 +83,7 @@ exp: | '-' error { $$ = 0; YYERROR; } ; %% - -static void yyerror (const char *s) -{ - fprintf (stderr, "%s\n", s); -} - +]AT_YYERROR_DEFINE[ static int get_char (void) { int res = getc (input); @@ -119,7 +114,8 @@ static int read_signed_integer (void) return sign * n; } -int yylex (void) +static int +yylex (void) { int c; /* Skip white space. */ @@ -190,6 +186,7 @@ AT_DATA([input.txt], AT_BISON_CHECK([-o test.c test.y]) AT_COMPILE([[test]]) AT_PARSER_CHECK([./test input.txt], 0, [], [stderr]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP @@ -198,13 +195,13 @@ AT_CLEANUP AT_SETUP([Undefined and ambiguous references]) - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([test.y], [[ %{ static int power (int base, int exponent); -static void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} %union @@ -268,6 +265,7 @@ test.y:55.3-53: symbol not found in production: r12 test.y:56.29-33: invalid reference: '$expo' test.y:56.3-46: symbol not found in production: expo ]]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP ####################################################################### diff --git a/tests/regression.at b/tests/regression.at index ff798a87..fd08800a 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -24,10 +24,11 @@ AT_BANNER([[Regression tests.]]) AT_SETUP([Trivial grammars]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ -void yyerror (char const *); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ #define YYSTYPE int * %} @@ -37,6 +38,7 @@ int yylex (void); program: 'x'; ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -52,10 +54,11 @@ AT_CLEANUP AT_SETUP([YYSTYPE typedef]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ -void yyerror (char const *); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ typedef union { char const *val; } YYSTYPE; %} @@ -65,6 +68,7 @@ typedef union { char const *val; } YYSTYPE; program: { $$ = ""; }; ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -83,10 +87,11 @@ AT_SETUP([Early token definitions with --yacc]) # Found in GCJ: they expect the tokens to be defined before the user # prologue, so that they can use the token definitions in it. +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %union @@ -103,6 +108,7 @@ int yylex (void); exp: MY_TOKEN; %% ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-y -o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -121,11 +127,12 @@ AT_SETUP([Early token definitions without --yacc]) # Found in GCJ: they expect the tokens to be defined before the user # prologue, so that they can use the token definitions in it. +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ #include -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ void print_my_token (void); %} @@ -146,6 +153,7 @@ print_my_token (void) exp: MY_TOKEN; %% ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -161,6 +169,7 @@ AT_CLEANUP AT_SETUP([Braces parsing]) +AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], [[/* Bison used to swallow the character after '}'. */ @@ -168,6 +177,7 @@ AT_DATA([input.y], exp: { tests = {{{{{{{{{{}}}}}}}}}}; }; %% ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-v -o input.c input.y]) @@ -183,6 +193,7 @@ AT_CLEANUP AT_SETUP([Duplicate string]) +AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], [[/* 'Bison -v' used to dump core when two tokens are defined with the same string, as LE and GE below. */ @@ -195,6 +206,7 @@ AT_DATA([input.y], exp: '(' exp ')' | NUM ; %% ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-v -o input.c input.y], 0, [], [[input.y:6.8-14: warning: symbol "<=" used more than once as a literal string @@ -211,6 +223,7 @@ AT_SETUP([Rule Line Numbers]) AT_KEYWORDS([report]) +AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], [[%% expr: @@ -240,6 +253,7 @@ expr: }; ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c -v input.y]) @@ -428,13 +442,14 @@ AT_CLEANUP AT_SETUP([Token definitions]) +AT_BISON_OPTION_PUSHDEFS # Bison managed, when fed with '%token 'f' "f"' to #define 'f'! AT_DATA_GRAMMAR([input.y], [%{ #include #include -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} [%error-verbose %token MYEOF 0 "end of file" @@ -468,6 +483,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS # Checking the warning message guarantees that the trigraph "??!" isn't # unnecessarily escaped here even though it would need to be if encoded in a @@ -498,19 +514,21 @@ AT_CLEANUP AT_SETUP([Characters Escapes]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [%{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} [%% exp: '\'' "\'" | '\"' "\"" -| '"' "'" +| '"' "'" /* Pacify font-lock-mode: ". */ ; ]]) -# Pacify font-lock-mode: " + +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) @@ -828,7 +846,7 @@ static int yylex (AT_LALR1_CC_IF([int *], [void])); AT_LALR1_CC_IF([#include ], [#include #include -static void yyerror (const char *);]) +]AT_YYERROR_DECLARE[]) %} $1 %token ARROW INVALID NUMBER STRING DATA @@ -953,10 +971,10 @@ m4_define([_AT_DATA_EXPECT2_Y], [AT_DATA_GRAMMAR([expect2.y], [%{ static int yylex (AT_LALR1_CC_IF([int *], [void])); -AT_LALR1_CC_IF([#include ], -[#include -#include -static void yyerror (const char *);]) +AT_LALR1_CC_IF([[#include ]], +[[#include +#include +]AT_YYERROR_DECLARE])[ %} $1 %defines @@ -973,30 +991,19 @@ e: e '+' t | t; t: A | B; %% -AT_LALR1_CC_IF( -[/* A C++ error reporting function. */ -void -yy::parser::error (const std::string& m) -{ - std::cerr << m << std::endl; -} - -int +]AT_YYERROR_DEFINE[ +]AT_LALR1_CC_IF( +[int yyparse () { yy::parser parser; return parser.parse (); } -], -[static void -yyerror (const char *s) -{ - fprintf (stderr, "%s\n", s); -}]) +])[ static int -yylex (AT_LALR1_CC_IF([int *lval], [void])) -[{ +yylex (]AT_LALR1_CC_IF([int *lval], [void])[) +{ static int const tokens[] = { 1000, '+', '+', -1 @@ -1006,19 +1013,19 @@ yylex (AT_LALR1_CC_IF([int *lval], [void])) if (! (toknum < sizeof tokens / sizeof *tokens)) abort (); return tokens[toknum++]; -}] +} int main (void) { return yyparse (); } -]) +]]) ])# _AT_DATA_EXPECT2_Y # AT_CHECK_EXPECT2(BISON-OPTIONS) -# ------------------------------ +# ------------------------------- # Generate the grammar, compile it, run it. m4_define([AT_CHECK_EXPECT2], [AT_SETUP([Expecting two tokens $1]) @@ -1047,12 +1054,12 @@ AT_SETUP([Braced code in declaration in rules section]) # Bison once mistook braced code in a declaration in the rules section to be a # rule action. - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ #include -static void yyerror (char const *msg); -static int yylex (void); +]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} %error-verbose @@ -1071,12 +1078,7 @@ start: %% -static void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -1090,6 +1092,7 @@ main (void) return !yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-t -o input.c input.y]) AT_COMPILE([input]) @@ -1187,12 +1190,12 @@ AT_SETUP([[Token number in precedence declaration]]) # POSIX says token numbers can be declared in %left, %right, and %nonassoc, but # we lost this in Bison 1.50. - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%{ #include - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ %} %error-verbose @@ -1212,12 +1215,7 @@ sr_conflict: %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int yylex (void) { @@ -1232,6 +1230,7 @@ main (void) return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]], [[0]],, [[input.y:23.5-19: warning: rule useless in parser due to conflicts: start: start @@ -1275,11 +1274,12 @@ AT_CLEANUP AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%code { #include - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ #define YYSTACK_USE_ALLOCA 1 } @@ -1315,28 +1315,18 @@ syntax_error: %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -int -yylex (void) -{ +]AT_YYERROR_DEFINE[ /* Induce two syntax error messages (which requires full error recovery by shifting 3 tokens) in order to detect any loss of the reallocated buffer. */ - static char const *input = "abc"; - return *input++; -} - +]AT_YYLEX_DEFINE([abc])[ int main (void) { return yyparse (); } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) @@ -1363,11 +1353,12 @@ AT_CLEANUP AT_SETUP([[parse.error=verbose overflow]]) +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%code { #include - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ /* This prevents this test case from having to induce error messages large enough to overflow size_t. */ @@ -1433,21 +1424,10 @@ syntax_error2: %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -int -yylex (void) -{ +]AT_YYERROR_DEFINE[ /* Induce two syntax error messages (which requires full error recovery by shifting 3 tokens). */ - static char const *input = "abc"; - return *input++; -} - +]AT_YYLEX_DEFINE([abc])[ int main (void) { @@ -1473,7 +1453,7 @@ AT_PARSER_CHECK([[./input]], [[2]], [], syntax error memory exhausted ]]) - +AT_BISON_OPTION_POPDEFS AT_CLEANUP @@ -1491,7 +1471,7 @@ AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_GRAMMAR([input.y], [[%code { #include - void yyerror (char const *); + ]AT_YYERROR_DECLARE[ int yylex (]AT_PURE_IF([[YYSTYPE *]], [[void]])[); } @@ -1512,13 +1492,7 @@ B: 'b' ; C: /*empty*/ { printf ("consistent default reduction\n"); } ; %% - -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int yylex (]AT_PURE_IF([[YYSTYPE *v]], [[void]])[) { @@ -1584,13 +1558,13 @@ AT_CLEANUP AT_SETUP([[LAC: Memory exhaustion]]) -m4_pushdef([AT_LAC_CHECK], [ - +m4_pushdef([AT_LAC_CHECK], +[AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%code { #include - void yyerror (char const *); - int yylex (void); + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ #define YYMAXDEPTH 8 } @@ -1602,20 +1576,8 @@ S: A A A A A A A A A ; A: /*empty*/ | 'a' ; %% - -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -int -yylex (void) -{ - static char const *input = "]$1["; - return *input++; -} - +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE([$1])[ int main (void) { @@ -1629,12 +1591,12 @@ AT_BISON_CHECK([[-Dparse.lac=full -Dparse.lac.es-capacity-initial=1 \ [[input.y: conflicts: 8 shift/reduce ]]) AT_COMPILE([[input]]) - +AT_BISON_OPTION_POPDEFS ]) # Check for memory exhaustion during parsing. -AT_LAC_CHECK([[]]) -AT_PARSER_CHECK([[./input]], [[2]], [[]], +AT_LAC_CHECK([]) +AT_PARSER_CHECK([[./input]], [[2]], [], [[Starting parse Entering state 0 Reading a token: Now at end of input. @@ -1647,8 +1609,8 @@ Stack now 0 # Induce an immediate syntax error with an undefined token, and check # for memory exhaustion while building syntax error message. -AT_LAC_CHECK([[z]], [[0]]) -AT_PARSER_CHECK([[./input]], [[2]], [[]], +AT_LAC_CHECK([z], [[0]]) +AT_PARSER_CHECK([[./input]], [[2]], [], [[Starting parse Entering state 0 Reading a token: Next token is token $undefined () diff --git a/tests/skeletons.at b/tests/skeletons.at index 1a9933fe..76cf0662 100644 --- a/tests/skeletons.at +++ b/tests/skeletons.at @@ -83,10 +83,11 @@ AT_CLEANUP AT_SETUP([[Installed skeleton file names]]) +AT_BISON_OPTION_PUSHDEFS m4_pushdef([AT_GRAM], [[%{ #include - void yyerror (char const *msg); + ]AT_YYERROR_DECLARE[ int yylex (void); %} @@ -99,12 +100,7 @@ start: ; %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ int yylex (void) { @@ -139,6 +135,7 @@ AT_PARSER_CHECK([[./input-gram]], [[1]], [], m4_popdef([AT_GRAM]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP diff --git a/tests/synclines.at b/tests/synclines.at index c12ab9b7..8d742d53 100644 --- a/tests/synclines.at +++ b/tests/synclines.at @@ -68,7 +68,7 @@ AT_CHECK([[sed -e '/^distcc\[[0-9]*\] /d' \ # to issue ERROR-MSG. m4_define([AT_TEST_SYNCLINE], [AT_SETUP([$1]) - +AT_BISON_OPTION_PUSHDEFS # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: @@ -98,6 +98,7 @@ AT_DATA([[input.y]], [$2]) AT_BISON_CHECK([-o input.c input.y]) AT_SYNCLINES_COMPILE([input.c]) AT_CHECK([cat stdout], 0, [$3]) +AT_BISON_OPTION_POPDEFS AT_CLEANUP ]) @@ -110,11 +111,12 @@ AT_CLEANUP AT_TEST_SYNCLINE([Prologue synch line], [[%{ #error "2" -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %% exp: '0'; +%% ]], [input.y:2: #error "2" ]) @@ -130,11 +132,12 @@ AT_TEST_SYNCLINE([%union synch line], char dummy; } %{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %% exp: '0'; +%% ]], [input.y:2: #error "2" ]) @@ -146,8 +149,8 @@ exp: '0'; AT_TEST_SYNCLINE([Postprologue synch line], [[%{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %union { @@ -158,6 +161,7 @@ int yylex (void); %} %% exp: '0'; +%% ]], [input.y:10: #error "10" ]) @@ -169,8 +173,8 @@ exp: '0'; AT_TEST_SYNCLINE([Action synch line], [[%{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %% exp: @@ -188,8 +192,8 @@ exp: AT_TEST_SYNCLINE([Epilogue synch line], [[%{ -void yyerror (const char *s); -int yylex (void); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ %} %% exp: '0'; diff --git a/tests/torture.at b/tests/torture.at index 253041e6..061467d0 100644 --- a/tests/torture.at +++ b/tests/torture.at @@ -42,7 +42,8 @@ esac]) # Create FILE-NAME, containing a self checking parser for a huge # triangular grammar. m4_define([AT_DATA_TRIANGULAR_GRAMMAR], -[AT_DATA([[gengram.pl]], +[AT_BISON_OPTION_PUSHDEFS +AT_DATA([[gengram.pl]], [[#! /usr/bin/perl -w use strict; @@ -56,8 +57,8 @@ print < #include -static int yylex (void); -static void yyerror (const char *msg); +]AT_YYLEX_DECLARE[ +]AT_YYERROR_DECLARE[ %} %union { @@ -127,6 +128,7 @@ main (void) } EOF ]]) +AT_BISON_OPTION_POPDEFS AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout]) mv stdout $1 @@ -157,7 +159,8 @@ AT_CLEANUP # Create FILE-NAME, containing a self checking parser for a huge # horizontal grammar. m4_define([AT_DATA_HORIZONTAL_GRAMMAR], -[AT_DATA([[gengram.pl]], +[AT_BISON_OPTION_PUSHDEFS +AT_DATA([[gengram.pl]], [[#! /usr/bin/perl -w use strict; @@ -171,8 +174,8 @@ print < #include -static int yylex (void); -static void yyerror (const char *msg); +]AT_YYLEX_DECLARE[ +]AT_YYERROR_DECLARE[ %} %token @@ -223,6 +226,7 @@ EOF AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout]) mv stdout $1 +AT_BISON_OPTION_POPDEFS ]) @@ -263,7 +267,8 @@ AT_CLEANUP # Create FILE-NAME, containing a self checking parser for a grammar # requiring SIZE lookahead tokens. m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR], -[AT_DATA([[gengram.pl]], +[AT_BISON_OPTION_PUSHDEFS +AT_DATA([[gengram.pl]], [[#! /usr/bin/perl -w use strict; @@ -278,8 +283,8 @@ print < # include -static int yylex (void); -static void yyerror (const char *msg); +]AT_YYLEX_DECLARE[ +]AT_YYERROR_DECLARE[ %} %union { @@ -363,6 +368,7 @@ EOF AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout]) mv stdout $1 +AT_BISON_OPTION_POPDEFS ]) @@ -390,7 +396,8 @@ AT_CLEANUP # ------------------------------------------------ # A parser specialized in torturing the stack size. m4_define([AT_DATA_STACK_TORTURE], -[# A grammar of parens growing the stack thanks to right recursion. +[AT_BISON_OPTION_PUSHDEFS([$2]) +# A grammar of parens growing the stack thanks to right recursion. # exp: AT_DATA([input.y], [[%{ @@ -399,8 +406,8 @@ AT_DATA([input.y], #include #include ]$1[ - static int yylex (void); - static void yyerror (const char *msg); + ]AT_YYLEX_DECLARE[ + ]AT_YYERROR_DECLARE[ %} ]$2[ %error-verbose @@ -409,12 +416,7 @@ AT_DATA([input.y], %% exp: WAIT_FOR_EOF exp | ; %% -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\n", msg); -} - +]AT_YYERROR_DEFINE[ static int yylex (void) { @@ -462,6 +464,7 @@ main (int argc, const char **argv) } } ]]) +AT_BISON_OPTION_POPDEFS([$2]) AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input]) ])