c++: make parser::symbol_name public

Reported by Martin Blais <blais@furius.ca>.
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.
This commit is contained in:
Akim Demaille
2020-05-10 09:00:38 +02:00
parent c3585f41ef
commit 6bb37dbe27
4 changed files with 40 additions and 25 deletions

2
NEWS
View File

@@ -6,6 +6,8 @@ GNU Bison NEWS
GNU readline portability issues. 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] * Noteworthy changes in release 3.6 (2020-05-08) [stable]
** Backward incompatible changes ** Backward incompatible changes

View File

@@ -241,6 +241,24 @@ m4_define([b4_shared_declarations],
/// Report a syntax error. /// Report a syntax error.
void error (const syntax_error& err); 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_token_constructor_define[
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[ ]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
class context class context
@@ -317,26 +335,14 @@ m4_define([b4_shared_declarations],
static symbol_kind_type yytranslate_ (int t); static symbol_kind_type yytranslate_ (int t);
]b4_parse_error_bmatch( ]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], [simple],
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[ [[#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. /// For a symbol, its name in clear.
static const char* const yytname_[]; static const char* const yytname_[];
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[ #endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
]], ]],
[verbose], [verbose],
[[ /// The user-facing name of the symbol whose (internal) number is [[ /// Convert the symbol name \a n to a form suitable for a diagnostic.
/// 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.
static std::string yytnamerr_ (const char *yystr); static std::string yytnamerr_ (const char *yystr);
/// For a symbol, its name in clear. /// For a symbol, its name in clear.
@@ -474,6 +480,7 @@ m4_define([b4_shared_declarations],
}; };
]b4_parse_param_vars[ ]b4_parse_param_vars[
]b4_percent_code_get([[yy_bison_internal_hook]])[
}; };
]b4_token_ctor_if([b4_yytranslate_define([$1])[ ]b4_token_ctor_if([b4_yytranslate_define([$1])[

View File

@@ -109,11 +109,6 @@ AT_DATA_GRAMMAR([list.yy],
%define parse.assert %define parse.assert
%debug %debug
%code top
{
// Get access to stack_symbol_type for the tests.
# define private public
}
%code provides %code provides
{ {
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
@@ -136,6 +131,14 @@ AT_DATA_GRAMMAR([list.yy],
%code requires { #include <vector> } %code requires { #include <vector> }
%code { int yylex (yy::parser::semantic_type* lvalp); } %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); } exp: "int" { $$.push_back ($1); }
%% %%
@@ -157,6 +160,8 @@ int main()
// symbol_type: construction, accessor. // symbol_type: construction, accessor.
{ {
parser::symbol_type s = parser::make_INT (12); 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); assert_eq (s.value.as<int> (), 12);
} }
@@ -180,12 +185,13 @@ int main()
} }
// stack_symbol_type: construction, accessor. // stack_symbol_type: construction, accessor.
typedef parser::yy_stack_symbol_type stack_symbol_type;
{ {
#if 201103L <= YY_CPLUSPLUS #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 #else
parser::symbol_type s = parser::make_INT (123); parser::symbol_type s = parser::make_INT (123);
parser::stack_symbol_type ss(1, s); stack_symbol_type ss(1, s);
#endif #endif
assert_eq (ss.value.as<int> (), 123); assert_eq (ss.value.as<int> (), 123);
} }
@@ -194,17 +200,17 @@ int main()
// Sufficiently many so that it will be resized. // Sufficiently many so that it will be resized.
// Probably 3 times (starting at 200). // Probably 3 times (starting at 200).
{ {
parser::stack_type st; parser::yy_stack_type st;
const int mucho = 1700; const int mucho = 1700;
const int int_reduction_state = 1; // Read list.output to find it. const int int_reduction_state = 1; // Read list.output to find it.
for (int i = 0; i < mucho; ++i) for (int i = 0; i < mucho; ++i)
{ {
#if 201103L <= YY_CPLUSPLUS #if 201103L <= YY_CPLUSPLUS
st.push(parser::stack_symbol_type{int_reduction_state, st.push(stack_symbol_type{int_reduction_state,
parser::make_INT (i)}); parser::make_INT (i)});
#else #else
parser::symbol_type s = parser::make_INT (i); 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); st.push (ss);
#endif #endif
} }

View File

@@ -500,7 +500,7 @@ m4_define([AT_DATA_SOURCE_PROLOGUE],
# The prologue that should be included in any grammar whose parser is # The prologue that should be included in any grammar whose parser is
# meant to be compiled. # meant to be compiled.
m4_define([AT_DATA_GRAMMAR_PROLOGUE], m4_define([AT_DATA_GRAMMAR_PROLOGUE],
[[%code top { [[%code top { /* -*- ]AT_LANG[ -*- */
]AT_DATA_SOURCE_PROLOGUE[]dnl ]AT_DATA_SOURCE_PROLOGUE[]dnl
[} [}
]]) ]])