mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
d: add api.value.type union support
The union of the values is handled by the backend. In D, unions can hold classes, structs, etc., so this is more similar to the C++ api.value.type variant. * data/skeletons/d.m4, data/skeletons/lalr1.d: Here. * tests/calc.at, tests/local.at: Test it.
This commit is contained in:
@@ -275,7 +275,7 @@ m4_define([b4_declare_symbol_enum],
|
||||
]])
|
||||
|
||||
|
||||
# b4-case(ID, CODE, [COMMENTS])
|
||||
# b4_case(ID, CODE, [COMMENTS])
|
||||
# -----------------------------
|
||||
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||
$2
|
||||
@@ -302,6 +302,109 @@ m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_perc
|
||||
m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
|
||||
# ---------------------- #
|
||||
# api.value.type=union. #
|
||||
# ---------------------- #
|
||||
|
||||
# b4_symbol_type_register(SYMBOL-NUM)
|
||||
# -----------------------------------
|
||||
# Symbol SYMBOL-NUM has a type (for union) instead of a type-tag.
|
||||
# Extend the definition of %union's body (b4_union_members) with a
|
||||
# field of that type, and extend the symbol's "type" field to point to
|
||||
# the field name, instead of the type name.
|
||||
m4_define([b4_symbol_type_register],
|
||||
[m4_define([b4_symbol($1, type_tag)],
|
||||
[b4_symbol_if([$1], [has_id],
|
||||
[b4_symbol([$1], [id])],
|
||||
[yykind_[]b4_symbol([$1], [number])])])dnl
|
||||
m4_append([b4_union_members],
|
||||
m4_expand([m4_format([ %-40s %s],
|
||||
m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]),
|
||||
[b4_symbol_tag_comment([$1])])]))
|
||||
])
|
||||
|
||||
|
||||
# b4_type_define_tag(SYMBOL1-NUM, ...)
|
||||
# ------------------------------------
|
||||
# For the batch of symbols SYMBOL1-NUM... (which all have the same
|
||||
# type), enhance the %union definition for each of them, and set
|
||||
# there "type" field to the field tag name, instead of the type name.
|
||||
m4_define([b4_type_define_tag],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[m4_map([b4_symbol_type_register], [$@])])
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
|
||||
# ----------------------------------------------
|
||||
# Same of b4_symbol_value, but when api.value.type=union.
|
||||
m4_define([b4_symbol_value_union],
|
||||
[m4_ifval([$3],
|
||||
[(*($3*)(&$1))],
|
||||
[m4_ifval([$2],
|
||||
[b4_symbol_if([$2], [has_type],
|
||||
[($1.b4_symbol([$2], [type_tag]))],
|
||||
[$1])],
|
||||
[$1])])])
|
||||
|
||||
|
||||
# b4_value_type_setup_union
|
||||
# -------------------------
|
||||
# Setup support for api.value.type=union. Symbols are defined with a
|
||||
# type instead of a union member name: build the corresponding union,
|
||||
# and give the symbols their tag.
|
||||
m4_define([b4_value_type_setup_union],
|
||||
[m4_define([b4_union_members])
|
||||
b4_type_foreach([b4_type_define_tag])
|
||||
m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
|
||||
])
|
||||
|
||||
|
||||
# _b4_value_type_setup_keyword
|
||||
# ----------------------------
|
||||
# api.value.type is defined with a keyword/string syntax. Check if
|
||||
# that is properly defined, and prepare its use.
|
||||
m4_define([_b4_value_type_setup_keyword],
|
||||
[b4_percent_define_check_values([[[[api.value.type]],
|
||||
[[none]],
|
||||
[[union]],
|
||||
[[union-directive]],
|
||||
[[yystype]]]])dnl
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[union], [b4_value_type_setup_union])])
|
||||
|
||||
|
||||
# b4_value_type_setup
|
||||
# -------------------
|
||||
# Check if api.value.type is properly defined, and possibly prepare
|
||||
# its use.
|
||||
b4_define_silent([b4_value_type_setup],
|
||||
[
|
||||
# Define default value.
|
||||
b4_percent_define_ifdef([[api.value.type]], [],
|
||||
[# %union => api.value.type=union-directive
|
||||
m4_ifdef([b4_union_members],
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [union-directive])],
|
||||
[# no tag seen => api.value.type={int}
|
||||
m4_if(b4_tag_seen_flag, 0,
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [code])
|
||||
m4_define([b4_percent_define(api.value.type)], [int])],
|
||||
[# otherwise api.value.type=yystype
|
||||
m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [yystype])])])])
|
||||
|
||||
# Set up.
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[keyword], [_b4_value_type_setup_keyword])
|
||||
])
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Semantic Values. ##
|
||||
## ----------------- ##
|
||||
@@ -454,11 +557,18 @@ alias Position = ]b4_position_type[;]])[
|
||||
m4_define([b4_basic_symbol_constructor_define],
|
||||
[b4_token_visible_if([$1],
|
||||
[ this(TokenKind token]b4_symbol_if([$1], [has_type],
|
||||
[[, typeof(YYSemanticType.]b4_symbol([$1], [type])dnl
|
||||
[) val]])[]b4_locations_if([[, Location loc]])[)
|
||||
[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl
|
||||
[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[)
|
||||
{
|
||||
kind = yytranslate_(token);]b4_symbol_if([$1], [has_type], [[
|
||||
value_.]b4_symbol([$1], [type])[ = val;]])[]b4_locations_if([
|
||||
kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[
|
||||
static foreach (member; __traits(allMembers, YYSemanticType))
|
||||
{
|
||||
static if (is(typeof(mixin("value_." ~ member)) == ]b4_symbol([$1], [type])[))
|
||||
{
|
||||
mixin("value_." ~ member ~ " = val;");
|
||||
}
|
||||
}]])], [b4_symbol_if([$1], [has_type], [[
|
||||
value_.]b4_symbol([$1], [type])[ = val;]])])[]b4_locations_if([
|
||||
location_ = loc;])[
|
||||
}
|
||||
])])
|
||||
|
||||
@@ -206,7 +206,7 @@ public struct ]b4_location_type[
|
||||
|
||||
private immutable bool yy_location_is_class = false;
|
||||
|
||||
]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
|
||||
]])])[]b4_value_type_setup[]m4_ifdef([b4_user_union_members], [private union YYSemanticType
|
||||
{
|
||||
b4_user_union_members
|
||||
};],
|
||||
|
||||
@@ -645,11 +645,11 @@ m4_define([_AT_DATA_CALC_Y(d)],
|
||||
alias semantic_value = int;
|
||||
}
|
||||
/* Exercise %union. */
|
||||
%union
|
||||
]AT_UNION_IF([[]], [[%union
|
||||
{
|
||||
semantic_value ival;
|
||||
};
|
||||
%printer { yyo.write($$); } <ival>;
|
||||
};]])[
|
||||
%printer { yyo.write($$); } <]AT_UNION_IF([[int]], [[ival]])[>;
|
||||
|
||||
%code {
|
||||
]AT_TOKEN_TRANSLATE_IF([[
|
||||
@@ -670,8 +670,8 @@ m4_define([_AT_DATA_CALC_Y(d)],
|
||||
|
||||
/* Bison Declarations */
|
||||
%token EOF 0 ]AT_TOKEN_TRANSLATE_IF([_("end of file")], ["end of input"])[
|
||||
%token <ival> NUM "number"
|
||||
%type <ival> exp
|
||||
%token <]AT_UNION_IF([[int]], [[ival]])[> NUM "number"
|
||||
%type <]AT_UNION_IF([[int]], [[ival]])[> exp
|
||||
|
||||
%token EQUAL "="
|
||||
MINUS "-"
|
||||
@@ -1499,6 +1499,7 @@ AT_CHECK_CALC_LALR1_D([%locations %define parse.lac full %define parse.error det
|
||||
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error detailed %debug %verbose %parse-param {semantic_value *result}{int *count}{int *nerrs}])
|
||||
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error detailed %debug %define api.prefix {calc} %verbose %parse-param {semantic_value *result}{int *count}{int *nerrs}])
|
||||
|
||||
AT_CHECK_CALC_LALR1_D([%define parse.error custom %define api.value.type union])
|
||||
|
||||
# ----------------------- #
|
||||
# LALR1 Java Calculator. #
|
||||
|
||||
@@ -319,6 +319,8 @@ m4_pushdef([AT_UNION_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type union], [$1], [$2])])
|
||||
m4_pushdef([AT_VARIANT_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type variant], [$1], [$2])])
|
||||
m4_pushdef([AT_UNION_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type union], [$1], [$2])])
|
||||
m4_pushdef([AT_API_prefix],
|
||||
[m4_bmatch([$3], [%define api\.prefix {.*}],
|
||||
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])],
|
||||
|
||||
Reference in New Issue
Block a user