skel: better aliasing of identifiers
authorTheophile Ranquet <ranquet@lrde.epita.fr>
Fri, 4 Jan 2013 11:30:01 +0000 (12:30 +0100)
committerTheophile Ranquet <ranquet@lrde.epita.fr>
Fri, 11 Jan 2013 17:57:09 +0000 (18:57 +0100)
* data/glr.c, data/yacc.c: Avoid emitting useless defines.
* data/glr.cc: Restore prefixes for epilogue.

NEWS
data/glr.c
data/glr.cc
data/yacc.c
tests/c++.at

diff --git a/NEWS b/NEWS
index a44e1be..6e499ae 100644 (file)
--- 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
index 106b95a..c2dc4c9 100644 (file)
@@ -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()
 
index 5f5a96f..7e42346 100644 (file)
@@ -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.  |
 `------------------*/
index 9b227ae..4e59024 100644 (file)
@@ -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[
index 6b10f88..a5d41a9 100644 (file)
@@ -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 <ival> 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