bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

backend: revamp the handling of symbol types


From: Akim Demaille
Subject: backend: revamp the handling of symbol types
Date: Mon, 3 Dec 2018 18:58:30 +0100

I'm quite happy with the result of this change.  It improves the
implementation of api.value.type = union (to which I plan to have
a similar implementation of variants).  For instance, here are
excerpts of the generated changes of Bison's own grammar parser:

> diff --git a/src/parse-gram.c b/src/parse-gram.c
> index 1dffd520..6599619f 100644
> --- a/src/parse-gram.c
> +++ b/src/parse-gram.c
> @@ -1140,24 +1140,24 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE 
> const * const yyvaluep,     case 89: /* value  */
>  #line 630 "src/parse-gram.y" /* yacc.c:681  */
>        {
> -  switch ((*(value_type*)(&(*yyvaluep))).kind)
> +  switch (((*yyvaluep).value).kind)
>      {
> -    case muscle_code:    fprintf (yyo,  "{%s}",  
> (*(value_type*)(&(*yyvaluep))).chars); break;
> -    case muscle_keyword: fprintf (yyo,   "%s",   
> (*(value_type*)(&(*yyvaluep))).chars); break;
> -    case muscle_string:  fprintf (yyo, "\"%s\"", 
> (*(value_type*)(&(*yyvaluep))).chars); break;
> +    case muscle_code:    fprintf (yyo,  "{%s}",  ((*yyvaluep).value).chars); 
> break;
> +    case muscle_keyword: fprintf (yyo,   "%s",   ((*yyvaluep).value).chars); 
> break;
> +    case muscle_string:  fprintf (yyo, "\"%s\"", ((*yyvaluep).value).chars); 
> break;
>      }
>  }
>  #line 1188 "src/parse-gram.c" /* yacc.c:681  */
> @@ -1189,7 +1189,7 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE 
> const * const yyvaluep, YY
>  
>      case 90: /* id  */
>  #line 205 "src/parse-gram.y" /* yacc.c:681  */
> -      { fprintf (yyo, "%s", (*(symbol**)(&(*yyvaluep)))->tag); }
> +      { fprintf (yyo, "%s", ((*yyvaluep).id)->tag); }
>  #line 1194 "src/parse-gram.c" /* yacc.c:681  */
>          break;
>  
> @@ -2118,17 +2117,17 @@ yyreduce:
>    case 7:
>  #line 282 "src/parse-gram.y" /* yacc.c:1649  */
>      {
> -      muscle_percent_define_ensure ((*(uniqstr*)(&yyvsp[0])), (yylsp[0]), 
> true);
> +      muscle_percent_define_ensure ((yyvsp[0].PERCENT_FLAG), (yylsp[0]), 
> true);
>      }
>    case 35:
>  #line 342 "src/parse-gram.y" /* yacc.c:1649  */
>      {
>        code_props code;
> -      code_props_symbol_action_init (&code, (*(char**)(&yyvsp[-1])), 
> (yylsp[-1]));
> +      code_props_symbol_action_init (&code, (yyvsp[-1].BRACED_CODE), 
> (yylsp[-1]));
>        code_props_translate_code (&code);
>        {
> -        for (symbol_list *list = (*(symbol_list**)(&yyvsp[0])); list; list = 
> list->next)
> -          symbol_list_code_props_set (list, 
> (*(code_props_type*)(&yyvsp[-2])), &code);
> -        symbol_list_free ((*(symbol_list**)(&yyvsp[0])));
> +        for (symbol_list *list = (yyvsp[0].generic_symlist); list; list = 
> list->next)
> +          symbol_list_code_props_set (list, (yyvsp[-2].code_props_type), 
> &code);
> +        symbol_list_free ((yyvsp[0].generic_symlist));
>        }
>      }
> @@ -2731,7 +2730,7 @@ yyreduce:
>                        _("character literals cannot be non-terminals"));
>            YYERROR;
>          }
> -      (*(symbol**)(&yyval)) = symbol_get (char_name ((*(unsigned 
> char*)(&yyvsp[0]))), (yylsp[0]));
> -      symbol_class_set ((*(symbol**)(&yyval)), token_sym, (yylsp[0]), false);
> -      symbol_user_token_number_set ((*(symbol**)(&yyval)), (*(unsigned 
> char*)(&yyvsp[0])), (yylsp[0]));
> +      (yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR)), (yylsp[0]));
> +      symbol_class_set ((yyval.id), token_sym, (yylsp[0]), false);
> +      symbol_user_token_number_set ((yyval.id), (yyvsp[0].CHAR), (yylsp[0]));
>      }


The code is much more natural, and is correctly using the
union tags instead of relying on casts.  Of course, this will
help when sitting lalr1.cc on top of unions.

This change also showed me that some documentation for the skeletons
is dearly needed.



commit c44a782a4e2a1720676dcbf4d51b4edcf5133ef3
Author: Akim Demaille <address@hidden>
Date:   Mon Dec 3 07:03:29 2018 +0100

    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.

diff --git a/data/bison.m4 b/data/bison.m4
index 4be8e696..9b80f7d2 100644
--- a/data/bison.m4
+++ b/data/bison.m4
@@ -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])])
diff --git a/data/c-like.m4 b/data/c-like.m4
index 4e476ac8..ff0e87c5 100644
--- a/data/c-like.m4
+++ b/data/c-like.m4
@@ -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
diff --git a/data/c.m4 b/data/c.m4
index bb19b348..5e253d63 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -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
diff --git a/data/glr.c b/data/glr.c
index 4c0c0165..f3e5fc34 100644
--- a/data/glr.c
+++ b/data/glr.c
@@ -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
 [
diff --git a/data/java.m4 b/data/java.m4
index 12491fd4..5290d590 100644
--- a/data/java.m4
+++ b/data/java.m4
@@ -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()
 # -----------------
diff --git a/data/lalr1.cc b/data/lalr1.cc
index b66846b4..e97b9b41 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -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
 
diff --git a/data/lalr1.java b/data/lalr1.java
index 7326d624..ae87cfb8 100644
--- a/data/lalr1.java
+++ b/data/lalr1.java
@@ -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)])[);
   }
 
diff --git a/data/variant.hh b/data/variant.hh
index 93ee3218..eea2c765 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -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])])
-
-# b4_symbol_value_template(VAL, [TYPE])
-# -------------------------------------
+[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, 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])])])
 
 
 
diff --git a/data/yacc.c b/data/yacc.c
index ff023e88..e74ba71a 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -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(address@hidden([$2], [$1])@}], [$3])])
+[b4_symbol_value(address@hidden([$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
diff --git a/src/scan-code.l b/src/scan-code.l
index a58ab4be..6ec278a9 100644
--- a/src/scan-code.l
+++ b/src/scan-code.l
@@ -627,10 +627,9 @@ handle_action_dollar (symbol_list *rule, char *text, 
location dollar_loc)
 
     case LHS_REF:
       {
-        if (!type_name)
-          type_name = symbol_list_n_type_name_get (rule, 0);
-
-        if (!type_name)
+        symbol_list *sym = symbol_list_n_get (rule, 0);
+        if (!type_name
+            && !sym->content.sym->content->type_name)
           {
             if (union_seen | tag_seen)
               {
@@ -649,7 +648,8 @@ handle_action_dollar (symbol_list *rule, char *text, 
location dollar_loc)
               untyped_var_seen = true;
           }
 
-        obstack_sgrow (&obstack_for_string, "]b4_lhs_value(");
+        obstack_printf (&obstack_for_string, "]b4_lhs_value(%d, ",
+                        sym->content.sym->content->number);
         obstack_quote (&obstack_for_string, type_name);
         obstack_sgrow (&obstack_for_string, ")[");
         rule->action_props.is_value_used = true;
@@ -661,9 +661,9 @@ handle_action_dollar (symbol_list *rule, char *text, 
location dollar_loc)
       {
         if (max_left_semantic_context < 1 - n)
           max_left_semantic_context = 1 - n;
-        if (!type_name && 0 < n)
-          type_name = symbol_list_n_type_name_get (effective_rule, n);
-        if (!type_name)
+        symbol_list *sym = 0 < n ? symbol_list_n_get (effective_rule, n) : 
NULL;
+        if (!type_name
+            && (!sym || !sym->content.sym->content->type_name))
           {
             if (union_seen | tag_seen)
               complain (&dollar_loc, complaint,
@@ -674,12 +674,17 @@ handle_action_dollar (symbol_list *rule, char *text, 
location dollar_loc)
           }
 
         obstack_printf (&obstack_for_string,
-                        "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
+                        "]b4_rhs_value(%d, %d, ",
+                        effective_rule_length, n);
+        if (sym)
+          obstack_printf (&obstack_for_string, "%d, ", 
sym->content.sym->content->number);
+        else
+          obstack_sgrow (&obstack_for_string, "[], ");
+
         obstack_quote (&obstack_for_string, type_name);
         obstack_sgrow (&obstack_for_string, ")[");
         if (0 < n)
           {
-            symbol_list *sym = symbol_list_n_get (effective_rule, n);
             if (muscle_percent_define_ifdef ("api.value.automove")
                 && sym->action_props.is_value_used)
               complain (&dollar_loc, Wother,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]