mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
c++: exhibit a safe symbol_type
Instead of introducing make_symbol (whose name, btw, somewhat
infringes on the user's "name space", if she defines a token named
"symbol"), let's make the construction of symbol_type safer, using
assertions.
For instance with:
%token ':' <std::string> ID <int> INT;
generate:
symbol_type (int token, const std::string&);
symbol_type (int token, const int&);
symbol_type (int token);
It does mean that now named token constructors (make_ID, make_INT,
etc.) go through a useless assert, but I think we can ignore this: I
assume any decent compiler will inline the symbol_type ctor inside the
make_TOKEN functions, which will show that the assert is trivially
verified, hence I expect no code will be emitted for it. And anyway,
that's an assert, NDEBUG controls it.
* data/c++.m4 (symbol_type): Turn into a subclass of
basic_symbol<by_type>.
Declare symbol constructors when variants are enabled.
* data/variant.hh (_b4_type_constructor_declare)
(_b4_type_constructor_define): Replace with...
(_b4_symbol_constructor_declare, _b4_symbol_constructor_def): these.
Generate symbol_type constructors.
* doc/bison.texi (Complete Symbols): Document.
* tests/types.at: Check.
This commit is contained in:
@@ -288,6 +288,24 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
AT_VAL.build (std::pair<std::string, std::string> ("two", "deux"));],
|
||||
[10:11, two:deux])
|
||||
|
||||
# Type-based token constructors on move-only types, and types with commas.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type variant
|
||||
%define api.token.constructor],
|
||||
[[%token <std::pair<int, int>> '1' '2';]],
|
||||
['1' '2'
|
||||
{
|
||||
std::cout << $1.first << ':' << $1.second << ", "
|
||||
<< $2.first << ':' << $2.second << '\n';
|
||||
}],
|
||||
["12"],
|
||||
[[typedef yy::parser::symbol_type symbol;
|
||||
if (res)
|
||||
return symbol (res, std::make_pair (res - '0', res - '0' + 1));
|
||||
else
|
||||
return symbol (res)]],
|
||||
[1:2, 2:3])
|
||||
|
||||
# Move-only types, and variadic emplace.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%code requires { #include <memory> }
|
||||
@@ -336,11 +354,11 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
<< $2.first << ':' << $2.second << '\n'; }],
|
||||
["12"],
|
||||
[[if (res == '1')
|
||||
return yy::parser::make_symbol ('1', std::make_unique<int> (10));
|
||||
return {res, std::make_unique<int> (10)};
|
||||
else if (res == '2')
|
||||
return yy::parser::make_symbol ('2', std::make_pair (21, 22));
|
||||
return {res, std::make_pair (21, 22)};
|
||||
else
|
||||
return yy::parser::make_symbol (0)]],
|
||||
return res]],
|
||||
[10, 21:22],
|
||||
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user