kinds: also define the possibly qualified symbol kinds

* data/skeletons/bison.m4 (b4_symbol_kind): Rename as...
(b4_symbol_kind_base): this.
(b4_symbol_kind): New, for fully qualified kind name.
* data/skeletons/lalr1.cc (b4_symbol_kind): New.
Adjust to use b4_symbol_kind where appropriate.
* src/parse-gram.h, src/parse-gram.c: regen.
This commit is contained in:
Akim Demaille
2020-05-23 13:18:59 +02:00
parent 3ff248ebfe
commit 23f7554188
10 changed files with 113 additions and 80 deletions

View File

@@ -84,19 +84,20 @@ field), where field can `has_id`, `id`, etc.: see
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
- `has_id`: 0 or 1
Whether the symbol has an id.
Whether the symbol has an `id`.
- `id`: string
If has_id, the id (prefixed by api.token.prefix if defined), otherwise
defined as empty. Guaranteed to be usable as a C identifier. This is
used to define the token kind (i.e., the enum used by the return value of
yylex).
If `has_id`, the name of the token kind (prefixed by api.token.prefix if
defined), otherwise empty. Guaranteed to be usable as a C identifier.
This is used to define the token kind (i.e., the enum used by the return
value of yylex). Should be named `token_kind`.
- `tag`: string
A human representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
A human readable representation of the symbol. Can be `'foo'`,
`'foo.id'`, `'"foo"'` etc.
- `code`: integer
The token code associated to the `id`.
The token code associated to the token kind `id`.
The external number as used by yylex. Can be ASCII code when a character,
some number chosen by bison, or some user number in the case of `%token
FOO <NUM>`. Corresponds to `yychar` in `yacc.c`.
@@ -104,9 +105,14 @@ The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
- `is_token`: 0 or 1
Whether this is a terminal symbol.
- `kind_base`: string
The base of the symbol kind, i.e., the enumerator of this symbol (token or
nonterminal) which is mapping to its `number`.
- `kind`: string
The symbol kind, i.e., the enumerator of this symbol (token or nonterminal)
which is mapping to its `number`.
Same as `kind_base`, but possibly with a prefix in some languages. E.g.,
EOF's `kind_base` and `kind` are `YYSYMBOL_YYEOF` in C, but are
`S_YYEMPTY` and `symbol_kind::S_YYEMPTY` in C++.
- `number`: integer
The code associated to the `kind`.

View File

@@ -438,14 +438,14 @@ m4_define([b4_symbol_token_kind],
_b4_symbol([$1], [id])])
# b4_symbol_kind(NUM)
# -------------------
# b4_symbol_kind_base(NUM)
# ------------------------
# Build the name of the kind of this symbol. It must always exist,
# otherwise some symbols might not be represented in the enum, which
# might be compiled into too small a type to contain all the symbol
# numbers.
m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
m4_define([b4_symbol_kind],
m4_define([b4_symbol_kind_base],
[b4_percent_define_get([api.symbol.prefix])dnl
m4_case([$1],
[-2], [[YYEMPTY]],
@@ -458,6 +458,13 @@ m4_case([$1],
[m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
# b4_symbol_kind(NUM)
# -------------------
# Same as b4_symbol_kind, but possibly with a prefix in some
# languages. E.g., EOF's kind_base and kind are YYSYMBOL_YYEOF in C,
# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
# b4_symbol(NUM, FIELD)
# ---------------------
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
@@ -466,6 +473,7 @@ m4_case([$1],
m4_define([b4_symbol],
[m4_case([$2],
[id], [b4_symbol_token_kind([$1])],
[kind_base], [b4_symbol_kind_base([$1])],
[kind], [b4_symbol_kind([$1])],
[_b4_symbol($@)])])

View File

@@ -193,7 +193,7 @@ m4_define([b4_declare_symbol_enum],
[[enum symbol_kind_type
{
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
]b4_symbol_kind([-2])[ = -2,
]b4_symbol(-2, kind_base)[ = -2,
]b4_symbol_foreach([ b4_symbol_enum])dnl
[ };]])
@@ -507,7 +507,7 @@ m4_define([b4_public_types_define],
bool
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
{
return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
return this->kind () == ]b4_symbol(-2, kind)[;
}
template <typename Base>
@@ -523,7 +523,7 @@ m4_define([b4_public_types_define],
// by_kind.
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
: kind_ (symbol_kind::]b4_symbol_prefix[YYEMPTY)
: kind_ (]b4_symbol(-2, kind)[)
{}
#if 201103L <= YY_CPLUSPLUS
@@ -545,7 +545,7 @@ m4_define([b4_public_types_define],
]b4_inline([$1])[void
]b4_parser_class[::by_kind::clear ()
{
kind_ = symbol_kind::]b4_symbol_prefix[YYEMPTY;
kind_ = ]b4_symbol(-2, kind)[;
}
]b4_inline([$1])[void

View File

@@ -572,7 +572,7 @@ m4_define([b4_symbol_translate],
m4_define([b4_symbol_enum],
[m4_format([ %-40s %s],
m4_format([[%s = %s%s%s]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1],
m4_if([$1], b4_last_symbol, [], [[,]])),
[b4_symbol_tag_comment([$1])])])
@@ -587,7 +587,7 @@ m4_define([b4_declare_symbol_enum],
[[/* Symbol kind. */
enum yysymbol_kind_t
{
]b4_symbol_kind([-2])[ = -2,
]b4_symbol([-2], kind_base)[ = -2,
]b4_symbol_foreach([b4_symbol_enum])dnl
[};
typedef enum yysymbol_kind_t yysymbol_kind_t;

View File

@@ -152,6 +152,8 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
## Token kinds. ##
## ------------- ##
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
# ---------------------------------------
# Output the definition of this token as an enum.
@@ -178,6 +180,11 @@ b4_symbol_foreach([b4_token_enum])dnl
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[SymbolKind.b4_symbol_kind_base($@)])
# b4_symbol_enum(SYMBOL-NUM)
# --------------------------
@@ -185,7 +192,7 @@ b4_percent_define_default([[api.symbol.prefix]], [[S_]])
m4_define([b4_symbol_enum],
[m4_format([ %-30s %s],
m4_format([[%s = %s,]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1]),
[b4_symbol_tag_comment([$1])])])
@@ -199,7 +206,7 @@ m4_define([b4_declare_symbol_enum],
[[ /* Symbol kinds. */
public enum SymbolKind
{
]b4_symbol_kind([-2])[ = -2, /* No symbol. */
]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
]b4_symbol_foreach([b4_symbol_enum])dnl
[ };
]])])

View File

@@ -66,12 +66,6 @@ m4_defn([b4_parse_param]))],
[[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
])
# b4_declare_symbol_enum
# ----------------------
m4_append([b4_declare_symbol_enum],
[[typedef symbol_kind_type yysymbol_kind_t;
]])
# b4_yy_symbol_print_define
# -------------------------
@@ -354,13 +348,17 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
#endif
]m4_define([b4_define_symbol_kind],
[m4_format([#define %-15s %s],
b4_symbol($][1, kind_base),
b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($][1, kind_base))
])[
]m4_define([b4_declare_symbol_enum],
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
#define ]b4_symbol_prefix[YYerror ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYerror
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
]])[
// Expose C++ symbol kinds to C.
]b4_define_symbol_kind(-2)dnl
b4_symbol_foreach([b4_define_symbol_kind])])[
]b4_percent_code_get([[provides]])[
]m4_popdef([b4_parse_param])dnl
])

View File

@@ -159,13 +159,20 @@ b4_symbol_foreach([b4_token_enum])])])
## Symbol kinds. ##
## -------------- ##
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[SymbolKind.b4_symbol_kind_base($@)])
# b4_symbol_enum(SYMBOL-NUM)
# --------------------------
# Output the definition of this symbol as an enum.
m4_define([b4_symbol_enum],
[m4_format([ %-30s %s],
m4_format([[%s(%s)%s]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1],
m4_if([$1], b4_last_symbol, [[;]], [[,]])),
[b4_symbol_tag_comment([$1])])])

View File

@@ -59,6 +59,13 @@ m4_define([b4_integral_parser_table_define],
};dnl
])
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[symbol_kind::b4_symbol_kind_base($@)])
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# -------------------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes
@@ -666,7 +673,7 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
{
if (state == empty_state)
return symbol_kind::]b4_symbol(-2, kind)[;
return ]b4_symbol(-2, kind)[;
else
return YY_CAST (symbol_kind_type, yystos_[+state]);
}
@@ -691,7 +698,7 @@ m4_if(b4_prefix, [yy], [],
b4_symbol_variant([that.kind ()],
[value], [move], [YY_MOVE (that.value)])])[
// that is emptied.
that.kind_ = symbol_kind::]b4_symbol(-2, kind)[;
that.kind_ = ]b4_symbol(-2, kind)[;
}
#if YY_CPLUSPLUS < 201103L
@@ -920,13 +927,13 @@ b4_dollar_popdef])[]dnl
}
YY_SYMBOL_PRINT ("Next token is", yyla);
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
if (yyla.kind () == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yyla.kind_ = ]symbol_kind::b4_symbol(2, kind)[;
yyla.kind_ = ]b4_symbol(2, kind)[;
goto yyerrlab1;
}
@@ -1063,7 +1070,7 @@ b4_dollar_popdef])[]dnl
error, discard it. */
// Return failure if at end of input.
if (yyla.kind () == symbol_kind::]b4_symbol_prefix[YYEOF)
if (yyla.kind () == ]b4_symbol(0, kind)[)
YYABORT;
else if (!yyla.empty ())
{
@@ -1104,9 +1111,9 @@ b4_dollar_popdef])[]dnl
yyn = yypact_[+yystack_[0].state];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += symbol_kind::]b4_symbol(1, kind)[;
yyn += ]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_
&& yycheck_[yyn] == symbol_kind::]b4_symbol(1, kind)[)
&& yycheck_[yyn] == ]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -1298,8 +1305,8 @@ b4_dollar_popdef])[]dnl
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
{
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
if (yysym != symbol_kind::]b4_symbol(1, kind)[
&& yysym != symbol_kind::]b4_symbol_prefix[YYUNDEF
if (yysym != ]b4_symbol(1, kind)[
&& yysym != ]b4_symbol(2, kind)[
&& yyparser_.yy_lac_check_ (yysym))
{
if (!yyarg)
@@ -1321,7 +1328,7 @@ b4_dollar_popdef])[]dnl
int yychecklim = yylast_ - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol(1, kind)[
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
{
if (!yyarg)
@@ -1334,7 +1341,7 @@ b4_dollar_popdef])[]dnl
}
]])[
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = symbol_kind::]b4_symbol(-2, kind)[;
yyarg[0] = ]b4_symbol(-2, kind)[;
return yycount;
}

View File

@@ -430,7 +430,7 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
{
/// Lookahead and lookahead in internal form.
int yychar = TokenKind.YYEMPTY;
SymbolKind yytoken = SymbolKind.]b4_symbol(-2, kind)[;
SymbolKind yytoken = ]b4_symbol(-2, kind)[;
/* State. */
int yyn = 0;
@@ -509,14 +509,14 @@ m4_popdef([b4_at_dollar])])dnl
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
if (yytoken == SymbolKind.]b4_symbol(1, kind)[)
if (yytoken == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = TokenKind.YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yychar = TokenKind.]b4_symbol(2, id)[;
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -587,8 +587,8 @@ m4_popdef([b4_at_dollar])])dnl
if (yyerrstatus_ == 0)
{
++yynerrs_;
if (yychar == TokenKind.YYEMPTY)
yytoken = SymbolKind.]b4_symbol(-2, kind)[;
if (yychar == TokenKind.]b4_symbol(-2, id)[)
yytoken = ]b4_symbol(-2, kind)[;
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
}
]b4_locations_if([
@@ -638,8 +638,8 @@ m4_popdef([b4_at_dollar])])dnl
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += SymbolKind.]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[)
yyn += ]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -726,7 +726,7 @@ m4_popdef([b4_at_dollar])])dnl
will still contain any token that will not be accepted due
to an error action in a later state.
*/
if (tok != SymbolKind.]b4_symbol(-2, kind)[)
if (tok != ]b4_symbol(-2, kind)[)
{
// FIXME: This method of building the message is not compatible
// with internationalization.
@@ -745,14 +745,14 @@ m4_popdef([b4_at_dollar])])dnl
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
int count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
++count;
if (count < 5)
{
count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
{
res ~= count++ == 0 ? ", expecting " : " or ";
@@ -844,14 +844,14 @@ m4_popdef([b4_at_dollar])])dnl
immutable int code_max_ = ]b4_code_max[;
if (t <= 0)
return SymbolKind.]b4_symbol_prefix[YYEOF;
return ]b4_symbol(0, kind)[;
else if (t <= code_max_)
{
import std.conv : to;
return to!SymbolKind (translate_table[t]);
}
else
return SymbolKind.]b4_symbol_prefix[YYUNDEF;]])[
return ]b4_symbol(2, kind)[;]])[
}
private static immutable int yylast_ = ]b4_last[;

View File

@@ -602,9 +602,9 @@ b4_dollar_popdef[]dnl
push_token_consumed = false;]], [b4_parse_trace_if([[
yycdebug ("Reading a token");]])[
yychar = yylexer.yylex ();
yylval = yylexer.getLVal ();]b4_locations_if([
yylloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
yylval = yylexer.getLVal();]b4_locations_if([[
yylloc = new ]b4_location_type[(yylexer.getStartPos(),
yylexer.getEndPos());]])[
]])[
}
@@ -613,14 +613,14 @@ b4_dollar_popdef[]dnl
yySymbolPrint("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);]])[
if (yytoken == SymbolKind.]b4_symbol_prefix[YYerror)
if (yytoken == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = Lexer.]b4_percent_define_get([api.token.prefix])[YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yychar = Lexer.]b4_symbol(2, id)[;
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -744,9 +744,9 @@ b4_dollar_popdef[]dnl
yyn = yypact_[yystate];
if (!yyPactValueIsDefault (yyn))
{
yyn += SymbolKind.]b4_symbol(1, kind)[.getCode ();
yyn += ]b4_symbol(1, kind)[.getCode();
if (0 <= yyn && yyn <= YYLAST_
&& yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[.getCode ())
&& yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -933,7 +933,7 @@ b4_dollar_popdef[]dnl
int yychecklim = YYLAST_ - yyn + 1;
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol(1, kind)[.getCode ()
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode()
&& !yyTableValueIsError(yytable_[yyx + yyn]))
{
if (yyarg == null)
@@ -1087,11 +1087,11 @@ b4_dollar_popdef[]dnl
[[ {
int code_max_ = ]b4_code_max[;
if (t <= 0)
return SymbolKind.]b4_symbol_prefix[YYEOF;
return ]b4_symbol(0, kind)[;
else if (t <= code_max_)
return SymbolKind.get(yytranslate_table_[t]);
else
return SymbolKind.]b4_symbol_prefix[YYUNDEF;
return ]b4_symbol(2, kind)[;
}
]b4_integral_parser_table_define([translate_table], [b4_translate])[
]])[