c++: provide symbol constructors per type

On

    %token <int> FOO BAR

we currently generate make_FOO(int) and make_BAR(int).  However, in
order to factor their scanners, some users would also like to have
make_symbol(tok, int), where tok is FOO or BAR.  To ensure type
safety, add assertions that do check that value type and token type
match.  Bind this assertion to the parse.assert %define variable.

Suggested by Frank Heckenbach.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00034.html
Should also match expectations from Аскар Сафин.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00023.html

* data/variant.hh: Use b4_token_visible_if where applicable.
(_b4_type_constructor_declare, _b4_type_constructor_define): New.
Use them.
This commit is contained in:
Akim Demaille
2018-12-18 07:16:55 +01:00
parent 34c52d10ac
commit 1f4dd2671a
2 changed files with 102 additions and 2 deletions

View File

@@ -325,6 +325,25 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
[10, 21:22],
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])
# Type-based token constructors on move-only types, and types with commas.
AT_TEST([%skeleton "]b4_skel["
%code requires { #include <memory> }
%define api.value.type variant
%define api.token.constructor],
[[%token <std::unique_ptr<int>> '1';
%token <std::pair<int, int>> '2';]],
['1' '2' { std::cout << *$1 << ", "
<< $2.first << ':' << $2.second << '\n'; }],
["12"],
[[if (res == '1')
return yy::parser::make_symbol ('1', std::make_unique<int> (10));
else if (res == '2')
return yy::parser::make_symbol ('2', std::make_pair (21, 22));
else
return yy::parser::make_symbol (0)]],
[10, 21:22],
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])
])
])