Re: Public / protected access to parser's symbol_name() in C++

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches,gmane.comp.parsers.bison.general
Message-ID <[email protected]>
hi Martin,

> Le 9 mai 2020 à 18:51, Martin Blais <[email protected]> a écrit :
> 
> On Sat, May 9, 2020 at 12:44 PM Akim Demaille <[email protected]> wrote:
> 
>> I'll soon release a version where this is public.  It should have been public.
> 
> I had a hunch it had been intended that way.

Yup  :)

I'm installing this.  Thanks for the report!

commit 6bb37dbe27456c93681b1a0ed7dd068622a16dd6
Author: Akim Demaille <[email protected]>
Date:   Sun May 10 09:00:38 2020 +0200

    c++: make parser::symbol_name public
    
    Reported by Martin Blais <[email protected]>.
    https://lists.gnu.org/r/help-bison/2020-05/msg00005.html
    
    * data/skeletons/lalr1.cc (symbol_name): Make it public.
    Add a private hidden hook to enable testing of private parts.
    * tests/local.at (AT_DATA_GRAMMAR_PROLOGUE): Help Emacs find the right
    language mode.
    * tests/c++.at (C++ Variant-based Symbols Unit Tests): Check that we
    can read symbol_name.

diff --git a/NEWS b/NEWS
index 31df56c5..509766f7 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@ GNU Bison NEWS
 
   GNU readline portability issues.
 
+  In C++, yy::parser::symbol_name is now a public member, as was intended.
+
 * Noteworthy changes in release 3.6 (2020-05-08) [stable]
 
 ** Backward incompatible changes
diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc
index e6da4d81..6fa5674e 100644
--- a/data/skeletons/lalr1.cc
+++ b/data/skeletons/lalr1.cc
@@ -241,6 +241,24 @@ m4_define([b4_shared_declarations],
     /// Report a syntax error.
     void error (const syntax_error& err);
 
+]b4_parse_error_bmatch(
+[custom\|detailed],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static std::string symbol_name (symbol_kind_type yysymbol);
+]])[
+
 ]b4_token_constructor_define[
 ]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
     class context
@@ -317,26 +335,14 @@ m4_define([b4_shared_declarations],
     static symbol_kind_type yytranslate_ (int t);
 
 ]b4_parse_error_bmatch(
-[custom\|detailed],
-[[    /// The user-facing name of the symbol whose (internal) number is
-    /// YYSYMBOL.  No bounds checking.
-    static const char *symbol_name (symbol_kind_type yysymbol);]],
 [simple],
 [[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
-    /// The user-facing name of the symbol whose (internal) number is
-    /// YYSYMBOL.  No bounds checking.
-    static const char *symbol_name (symbol_kind_type yysymbol);
-
     /// For a symbol, its name in clear.
     static const char* const yytname_[];
 #endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
 ]],
 [verbose],
-[[    /// The user-facing name of the symbol whose (internal) number is
-    /// YYSYMBOL.  No bounds checking.
-    static std::string symbol_name (symbol_kind_type yysymbol);
-
-    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+[[    /// Convert the symbol name \a n to a form suitable for a diagnostic.
     static std::string yytnamerr_ (const char *yystr);
 
     /// For a symbol, its name in clear.
@@ -474,6 +480,7 @@ m4_define([b4_shared_declarations],
     };
 
 ]b4_parse_param_vars[
+]b4_percent_code_get([[yy_bison_internal_hook]])[
   };
 
 ]b4_token_ctor_if([b4_yytranslate_define([$1])[
diff --git a/tests/c++.at b/tests/c++.at
index 490c6c25..d3f52513 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -109,11 +109,6 @@ AT_DATA_GRAMMAR([list.yy],
 %define parse.assert
 %debug
 
-%code top
-{
-  // Get access to stack_symbol_type for the tests.
-# define private public
-}
 %code provides
 {
   ]AT_YYLEX_DECLARE[
@@ -136,6 +131,14 @@ AT_DATA_GRAMMAR([list.yy],
 %code requires { #include <vector> }
 %code { int yylex (yy::parser::semantic_type* lvalp); }
 
+// A hack which relies on internal hooks to check stack_symbol_type,
+// which is private.
+%code yy_bison_internal_hook {
+  public:
+    typedef stack_symbol_type yy_stack_symbol_type;
+    typedef stack_type yy_stack_type;
+}
+
 %%
 exp: "int" { $$.push_back ($1); }
 %%
@@ -157,6 +160,8 @@ int main()
   // symbol_type: construction, accessor.
   {
     parser::symbol_type s = parser::make_INT (12);
+    assert_eq (s.kind (), parser::symbol_kind::S_INT);
+    assert_eq (parser::symbol_name (s.kind ()), "\"int\"");
     assert_eq (s.value.as<int> (), 12);
   }
 
@@ -180,12 +185,13 @@ int main()
   }
 
   // stack_symbol_type: construction, accessor.
+  typedef parser::yy_stack_symbol_type stack_symbol_type;
   {
 #if 201103L <= YY_CPLUSPLUS
-    auto ss = parser::stack_symbol_type(1, parser::make_INT(123));
+    auto ss = stack_symbol_type (1, parser::make_INT(123));
 #else
     parser::symbol_type s = parser::make_INT (123);
-    parser::stack_symbol_type ss(1, s);
+    stack_symbol_type ss(1, s);
 #endif
     assert_eq (ss.value.as<int> (), 123);
   }
@@ -194,17 +200,17 @@ int main()
   // Sufficiently many so that it will be resized.
   // Probably 3 times (starting at 200).
   {
-    parser::stack_type st;
+    parser::yy_stack_type st;
     const int mucho = 1700;
     const int int_reduction_state = 1; // Read list.output to find it.
     for (int i = 0; i < mucho; ++i)
       {
 #if 201103L <= YY_CPLUSPLUS
-        st.push(parser::stack_symbol_type{int_reduction_state,
-                                          parser::make_INT (i)});
+        st.push(stack_symbol_type{int_reduction_state,
+                                  parser::make_INT (i)});
 #else
         parser::symbol_type s = parser::make_INT (i);
-        parser::stack_symbol_type ss (int_reduction_state, s);
+        stack_symbol_type ss (int_reduction_state, s);
         st.push (ss);
 #endif
       }
diff --git a/tests/local.at b/tests/local.at
index 11d367fc..2e8532d0 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -500,7 +500,7 @@ m4_define([AT_DATA_SOURCE_PROLOGUE],
 # The prologue that should be included in any grammar whose parser is
 # meant to be compiled.
 m4_define([AT_DATA_GRAMMAR_PROLOGUE],
-[[%code top {
+[[%code top { /* -*- ]AT_LANG[ -*- */
 ]AT_DATA_SOURCE_PROLOGUE[]dnl
 [}
 ]])
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.