mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-21 02:03:03 +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])])
|
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||||
$2
|
$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]))
|
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. ##
|
## Semantic Values. ##
|
||||||
## ----------------- ##
|
## ----------------- ##
|
||||||
@@ -454,11 +557,18 @@ alias Position = ]b4_position_type[;]])[
|
|||||||
m4_define([b4_basic_symbol_constructor_define],
|
m4_define([b4_basic_symbol_constructor_define],
|
||||||
[b4_token_visible_if([$1],
|
[b4_token_visible_if([$1],
|
||||||
[ this(TokenKind token]b4_symbol_if([$1], [has_type],
|
[ this(TokenKind token]b4_symbol_if([$1], [has_type],
|
||||||
[[, typeof(YYSemanticType.]b4_symbol([$1], [type])dnl
|
[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl
|
||||||
[) val]])[]b4_locations_if([[, Location loc]])[)
|
[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[)
|
||||||
{
|
{
|
||||||
kind = yytranslate_(token);]b4_symbol_if([$1], [has_type], [[
|
kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[
|
||||||
value_.]b4_symbol([$1], [type])[ = val;]])[]b4_locations_if([
|
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;])[
|
location_ = loc;])[
|
||||||
}
|
}
|
||||||
])])
|
])])
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ public struct ]b4_location_type[
|
|||||||
|
|
||||||
private immutable bool yy_location_is_class = false;
|
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
|
b4_user_union_members
|
||||||
};],
|
};],
|
||||||
|
|||||||
@@ -645,11 +645,11 @@ m4_define([_AT_DATA_CALC_Y(d)],
|
|||||||
alias semantic_value = int;
|
alias semantic_value = int;
|
||||||
}
|
}
|
||||||
/* Exercise %union. */
|
/* Exercise %union. */
|
||||||
%union
|
]AT_UNION_IF([[]], [[%union
|
||||||
{
|
{
|
||||||
semantic_value ival;
|
semantic_value ival;
|
||||||
};
|
};]])[
|
||||||
%printer { yyo.write($$); } <ival>;
|
%printer { yyo.write($$); } <]AT_UNION_IF([[int]], [[ival]])[>;
|
||||||
|
|
||||||
%code {
|
%code {
|
||||||
]AT_TOKEN_TRANSLATE_IF([[
|
]AT_TOKEN_TRANSLATE_IF([[
|
||||||
@@ -670,8 +670,8 @@ m4_define([_AT_DATA_CALC_Y(d)],
|
|||||||
|
|
||||||
/* Bison Declarations */
|
/* Bison Declarations */
|
||||||
%token EOF 0 ]AT_TOKEN_TRANSLATE_IF([_("end of file")], ["end of input"])[
|
%token EOF 0 ]AT_TOKEN_TRANSLATE_IF([_("end of file")], ["end of input"])[
|
||||||
%token <ival> NUM "number"
|
%token <]AT_UNION_IF([[int]], [[ival]])[> NUM "number"
|
||||||
%type <ival> exp
|
%type <]AT_UNION_IF([[int]], [[ival]])[> exp
|
||||||
|
|
||||||
%token EQUAL "="
|
%token EQUAL "="
|
||||||
MINUS "-"
|
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 %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([%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. #
|
# LALR1 Java Calculator. #
|
||||||
|
|||||||
@@ -319,6 +319,8 @@ m4_pushdef([AT_UNION_IF],
|
|||||||
[m4_bmatch([$3], [%define api\.value\.type union], [$1], [$2])])
|
[m4_bmatch([$3], [%define api\.value\.type union], [$1], [$2])])
|
||||||
m4_pushdef([AT_VARIANT_IF],
|
m4_pushdef([AT_VARIANT_IF],
|
||||||
[m4_bmatch([$3], [%define api\.value\.type variant], [$1], [$2])])
|
[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_pushdef([AT_API_prefix],
|
||||||
[m4_bmatch([$3], [%define api\.prefix {.*}],
|
[m4_bmatch([$3], [%define api\.prefix {.*}],
|
||||||
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])],
|
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])],
|
||||||
|
|||||||
Reference in New Issue
Block a user