From 99d795e8f28470838cc45bd38ce3da9503fe20fb Mon Sep 17 00:00:00 2001 From: Theophile Ranquet Date: Fri, 4 Jan 2013 12:30:01 +0100 Subject: [PATCH] skel: better aliasing of identifiers * data/glr.c, data/yacc.c: Avoid emitting useless defines. * data/glr.cc: Restore prefixes for epilogue. --- NEWS | 12 ++++++++++++ data/glr.c | 22 ++++++++++++++++++++-- data/glr.cc | 18 ++++++++++++++++++ data/yacc.c | 9 +++++---- tests/c++.at | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index a44e1beb..6e499aee 100644 --- a/NEWS +++ b/NEWS @@ -198,6 +198,18 @@ GNU Bison NEWS used by the scanner, or rejecting invalid combinations from a factory invoked by the user actions). +*** The epilogue is no longer affected by internal #defines + + The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in + generated code. These weren't properly undefined before the inclusion of + the user epilogue, so functions such as the following were butchered by the + preprocessor expansion: + + int yylex (yy::parser::semantic_type *yylval); + + This is has been fixed: yylval, ynerrs, yychar, and yylloc are now valid + identifiers for user-provided variables. + ** Renamed %define variables The following variables have been renamed for consistency. Backward diff --git a/data/glr.c b/data/glr.c index 106b95a7..c2dc4c9b 100644 --- a/data/glr.c +++ b/data/glr.c @@ -196,11 +196,12 @@ b4_percent_code_get([[top]])[ #define yyparse ]b4_prefix[parse #define yylex ]b4_prefix[lex #define yyerror ]b4_prefix[error +#define yydebug ]b4_prefix[debug +]]b4_pure_if([], [[ #define yylval ]b4_prefix[lval #define yychar ]b4_prefix[char -#define yydebug ]b4_prefix[debug #define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ -#define yylloc ]b4_prefix[lloc]])])[ +#define yylloc ]b4_prefix[lloc]])]))[ /* First part of user declarations. */ ]b4_user_pre_prologue[ @@ -2543,6 +2544,23 @@ yypdumpstack (yyGLRStack* yystackp) YYFPRINTF (stderr, "\n"); } #endif + +#undef yylval +#undef yychar +#undef yynerrs]b4_locations_if([ +#undef yylloc]) + +m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yydebug ]b4_prefix[debug +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])[ + ]b4_epilogue[]dnl b4_output_end() diff --git a/data/glr.cc b/data/glr.cc index 5f5a96f4..7e42346c 100644 --- a/data/glr.cc +++ b/data/glr.cc @@ -118,10 +118,28 @@ m4_defn([b4_initial_action])]))])[ [[const char* msg], [msg]])]) +#undef yynerrs +#undef yychar +#undef yylval]b4_locations_if([ +#undef yylloc]) + +m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yydebug ]b4_prefix[debug +]]b4_pure_if([], [[ +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])) + # Hijack the epilogue to define implementations (yyerror, parser member # functions etc.). m4_append([b4_epilogue], [b4_syncline([@oline@], [@ofile@])[ + /*------------------. | Report an error. | `------------------*/ diff --git a/data/yacc.c b/data/yacc.c index 9b227aea..4e590241 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -346,11 +346,12 @@ m4_if(b4_api_prefix, [yy], [], #define yypstate ]b4_prefix[pstate]])[ #define yylex ]b4_prefix[lex #define yyerror ]b4_prefix[error -#define yylval ]b4_prefix[lval -#define yychar ]b4_prefix[char #define yydebug ]b4_prefix[debug -#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ -#define yylloc ]b4_prefix[lloc]])])[ +#define yynerrs ]b4_prefix[nerrs +]]b4_pure_if([], [[ +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])]))[ /* Copy the first part of user declarations. */ ]b4_user_pre_prologue[ diff --git a/tests/c++.at b/tests/c++.at index 6b10f88c..a5d41a98 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -752,3 +752,46 @@ AT_PARSER_CHECK([[./input aaaaR]], [[0]]) AT_BISON_OPTION_POPDEFS AT_CLEANUP + +## ------------------------------------ ## +## C++ GLR parser identifier shadowing ## +## ------------------------------------ ## + +AT_SETUP([[C++ GLR parser identifier shadowing]]) + +AT_DATA_GRAMMAR([input.yy], [ +%skeleton "glr.cc" + +%union +{ + int ival; +} + +%token ZERO; + +%code +{ + int yylex (yy::parser::semantic_type *yylval); +} + +%% +exp: ZERO + +%% + +int yylex (yy::parser::semantic_type *yylval) +{ + return yy::parser::token::ZERO; +} + +void yy::parser::error (std::string const& msg) +{} + +int main() +{} +]) + +AT_BISON_CHECK([[-o input.cc input.yy]]) +AT_COMPILE_CXX([[input]]) + +AT_CLEANUP -- 2.45.2