backend: revamp the handling of symbol types

Currently it is the front end that passes the symbol types to the
backend.  For instance:

  %token <ival> NUM
  %type <ival> exp1 exp2
  exp1: NUM { $$ = $1; }
  exp2: NUM { $<ival>$ = $<ival>1; }

In both cases, $$ and $1 are passed to the backend as having type
'ival' resulting in code like `val.ival`.  This is troublesome in the
case of api.value.type=union, since in that the case the code this:

  %define api.value.type union
  %token <int> NUM
  %type <int> exp1 exp2
  exp1: NUM { $$ = $1; }
  exp2: NUM { $<int>$ = $<int>1; }

because in this case, since the backend does not know the symbol being
processed, it is forced to generate casts in both cases: *(int*)(&val)`.
This is unfortunate in the first case (exp1) where there is no reason
at all to use a cast instead of `val.NUM` and `val.exp1`.

So instead delegate the computation of the actual value type to the
backend: pass $<ival>$ as `symbol-number, ival` and $$ as
`symbol-number, MULL`, instead of passing `ival` before.

* src/scan-code.l (handle_action_dollar): Find the symbol the action
is about, not just its tyye.  Pass both symbol-number, and explicit
type tag ($<tag>n when there is one) to b4_lhs_value and b4_rhs_value.

* data/bison.m4 (b4_symbol_action): adjust to the new signature to
b4_dollar_pushdef.

* data/c-like.m4 (_b4_dollar_dollar, b4_dollar_pushdef): Accept the
symbol-number as new argument.

* data/c.m4 (b4_symbol_value): Accept the symbol-number as new
argument, and use it.
(b4_symbol_value_union): Accept the symbol-number as new
argument, and use it to prefer ready a union member rather than
casting the union.
* data/yacc.c (b4_lhs_value, b4_rhs_value): Accept the new
symbol-number argument.
Adjust uses of b4_dollar_pushdef.
* data/glr.c (b4_lhs_value, b4_rhs_value): Adjust.

* data/lalr1.cc (b4_symbol_value_template, b4_lhs_value): Adjust
to the new symbol-number argument.
* data/variant.hh (b4_symbol_value, b4_symbol_value_template): Accept
the new symbol-number argument.

* data/java.m4 (b4_symbol_value, b4_rhs_data): New.
(b4_rhs_value): Use them.
* data/lalr1.java: Adjust to b4_dollar_pushdef, and use b4_rhs_data.
This commit is contained in:
Akim Demaille
2018-12-03 07:03:29 +01:00
parent e40db8976c
commit c44a782a4e
10 changed files with 151 additions and 86 deletions

View File

@@ -468,8 +468,8 @@ m4_define([b4_symbol_action_location],
m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2],
[b4_dollar_pushdef([(*yyvaluep)],
b4_symbol_if([$1], [has_type],
[m4_dquote(b4_symbol([$1], [type]))]),
[$1],
[],
[(*yylocationp)])dnl
_b4_symbol_case([$1])[]dnl
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])

View File

@@ -39,25 +39,26 @@ m4_define([b4_comment],
# _b4_dollar_dollar(VALUE, FIELD, DEFAULT-FIELD)
# ----------------------------------------------
# _b4_dollar_dollar(VALUE, SYMBOL-NUM, FIELD, DEFAULT-FIELD)
# ----------------------------------------------------------
# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
# otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a
# otherwise just VALUE. Be sure to pass "(VALUE)" if VALUE is a
# pointer.
m4_define([_b4_dollar_dollar],
[b4_symbol_value([$1],
m4_if([$2], [[]],
[[$3]], [[$2]]))])
[$2],
m4_if([$3], [[]],
[[$4]], [[$3]]))])
# b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION)
# b4_dollar_pushdef(VALUE-POINTER, SYMBOL-NUM, [TYPE_TAG], LOCATION)
# b4_dollar_popdef
# ---------------------------------------------------------
# Define b4_dollar_dollar for VALUE and DEFAULT-FIELD,
# ------------------------------------------------------------------
# Define b4_dollar_dollar for VALUE-POINTER and DEFAULT-FIELD,
# and b4_at_dollar for LOCATION.
m4_define([b4_dollar_pushdef],
[m4_pushdef([b4_dollar_dollar],
[_b4_dollar_dollar([$1], m4_dquote($][1), [$2])])dnl
m4_pushdef([b4_at_dollar], [$3])dnl
[_b4_dollar_dollar([$1], [$2], m4_dquote($][1), [$3])])dnl
m4_pushdef([b4_at_dollar], [$4])dnl
])
m4_define([b4_dollar_popdef],
[m4_popdef([b4_at_dollar])dnl

View File

@@ -373,15 +373,28 @@ m4_define([b4_token_enums_defines],
## ----------------- ##
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
# Given a semantic value VAL ($$, $1 etc.), extract its value of type
# TYPE if TYPE is given, otherwise just return VAL. The result can be
# used safely, it is put in parens to avoid nasty precedence issues.
# TYPE is *not* put in braces, provide some if needed.
# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
# ----------------------------------------------
# Expansion of $$, $1, $<TYPE-TAG>3, etc.
#
# The semantic value from a given VAL.
#
# VAL: some semantic value storage (typically a union).
# e.g., yylval
# SYMBOL-NUM: the symbol number from which we extract the
# type tag.
# TYPE-TAG, the user forced the <TYPE-TAG>.
#
# The result can be used safely, it is put in parens to avoid nasty
# precedence issues.
m4_define([b4_symbol_value],
[($1[]m4_ifval([$2], [.$2]))])
[m4_ifval([$3],
[($1.$3)],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[($1.b4_symbol([$2], [type]))],
[$1])],
[$1])])])
## ---------------------- ##
@@ -604,14 +617,17 @@ m4_define([b4_type_define_tag],
])
# b4_symbol_value_union(VAL, [TYPE])
# ----------------------------------
# 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([$2],
[(*($2*)(&$1))],
[$1])])
])
[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

View File

@@ -112,11 +112,11 @@ m4_define([b4_locuser_args],
## ----------------- ##
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
# b4_lhs_value(SYMBOL-NUM, [TYPE])
# --------------------------------
# Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value],
[b4_symbol_value([(*yyvalp)], [$1])])
[b4_symbol_value([(*yyvalp)], [$1], [$2])])
# b4_rhs_data(RULE-LENGTH, POS)
@@ -127,12 +127,12 @@ m4_define([b4_rhs_data],
[((yyGLRStackItem const *)yyvsp)@{YYFILL (b4_subtract([$2], [$1]))@}.yystate])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# --------------------------------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3])])
[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])])
@@ -2265,7 +2265,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
yylval = yyval_default;]b4_locations_if([
yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action
b4_dollar_popdef])[]dnl
[

View File

@@ -219,21 +219,56 @@ m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])
## ----------------- ##
# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
# ----------------------------------------------
# Expansion of $$, $1, $<TYPE-TAG>3, etc.
#
# The semantic value from a given VAL.
#
# VAL: some semantic value storage (typically a union).
# e.g., yylval
# SYMBOL-NUM: the symbol number from which we extract the
# type tag.
# TYPE-TAG, the user forced the <TYPE-TAG>.
#
# The result can be used safely, it is put in parens to avoid nasty
# precedence issues.
m4_define([b4_symbol_value],
[m4_ifval([$3],
[(($3)($1))],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[((b4_symbol([$2], [type]))($1))],
[$1])],
[$1])])])
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
m4_define([b4_lhs_value], [yyval])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# b4_rhs_data(RULE-LENGTH, POS)
# -----------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
#
# In this simple implementation, %token and %type have class names
# between the angle brackets.
m4_define([b4_rhs_data],
[yystack.valueAt ($1-($2))])
# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# --------------------------------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
#
# In this simple implementation, %token and %type have class names
# between the angle brackets.
m4_define([b4_rhs_value],
[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))])
[b4_symbol_value([b4_rhs_data([$1], [$2])], [$3], [$4])])
# b4_lhs_location()
# -----------------

View File

@@ -41,20 +41,20 @@ m4_define([b4_integral_parser_table_define],
};dnl
])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# -------------------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes
# a difference when using variants. Note that b4_value_type_setup_union
# overrides b4_symbol_value, so we must override it again.
m4_copy([b4_symbol_value], [b4_symbol_value_template])
m4_append([b4_value_type_setup_union],
[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
# b4_lhs_value(SYMBOL-NUM, SYMBOL-NUM, [TYPE])
# --------------------------------------------
# Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value],
[b4_symbol_value([yylhs.value], [$1])])
[b4_symbol_value([yylhs.value], [$1], [$2])])
# b4_lhs_location()
@@ -80,12 +80,12 @@ m4_define([b4_rhs_state],
[b4_rhs_data([$1], [$2]).state])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# --------------------------------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([_b4_rhs_value],
[b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
[b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3], [$4])])
m4_define([b4_rhs_value],
[b4_percent_define_ifdef([api.value.automove],
@@ -109,9 +109,9 @@ m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2],
[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
b4_dollar_pushdef([yysym.value],
b4_symbol_if([$1], [has_type],
[m4_dquote(b4_symbol([$1], [type]))]),
[yysym.location])dnl
[$1],
[],
[yysym.location])dnl
_b4_symbol_case([$1])
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
b4_symbol([$1], [$2])
@@ -780,7 +780,7 @@ m4_if(b4_prefix, [yy], [],
YYCDEBUG << "Starting parse\n";
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yyla.value], [], [yyla.location])dnl
b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
b4_user_initial_action
b4_dollar_popdef])[]dnl

View File

@@ -584,7 +584,7 @@ b4_define_state])[
/* Initialize the stack. */
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action
b4_dollar_popdef[]dnl
])[
@@ -594,7 +594,7 @@ b4_dollar_popdef[]dnl
{
push_parse_initialize ();
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action
b4_dollar_popdef[]dnl
])[
@@ -1033,7 +1033,7 @@ b4_both_if([[
for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (" $" + (yyi + 1) + " =",
yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}

View File

@@ -304,20 +304,28 @@ m4_define([b4_value_type_declare],
# How the semantic value is extracted when using variants.
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
# b4_symbol_value(VAL, SYMBOL-NUM, [TYPE])
# ----------------------------------------
m4_define([b4_symbol_value],
[m4_ifval([$2],
[$1.as< $2 > ()],
[$1])])
[m4_ifval([$3],
[$1.as< $3 > ()],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[$1.as < b4_symbol([$2], [type]) > ()],
[$1])],
[$1])])])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# -------------------------------------------------
# Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template],
[m4_ifval([$2],
[$1.template as< $2 > ()],
[$1])])
[m4_ifval([$3],
[$1.template as< $3 > ()],
[m4_ifval([$2],
[b4_symbol_if([$2], [has_type],
[$1.template as < b4_symbol([$2], [type]) > ()],
[$1])],
[$1])])])

View File

@@ -128,19 +128,19 @@ m4_define([b4_int_type],
## ----------------- ##
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
# b4_lhs_value(SYMBOL-NUM, [TYPE])
# --------------------------------
# Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
m4_define([b4_lhs_value],
[b4_symbol_value(yyval, [$1])])
[b4_symbol_value(yyval, [$1], [$2])])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
# --------------------------------------------------
# Expansion of $<TYPE>POS, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3], [$4])])
## ----------- ##
@@ -1426,7 +1426,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [],
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
b4_user_initial_action
b4_dollar_popdef[]dnl