]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
Fix bug such that the first pushed token's value and location are
[bison.git] / src / reader.c
index 604c03b10eae59ffc0d9d28f64eab05c198edb8b..7b7692328bdc558d6b6aea82b813cc2a614e66e1 100644 (file)
@@ -243,19 +243,24 @@ grammar_current_rule_begin (symbol *lhs, location loc)
 
 
 /*----------------------------------------------------------------------.
-| A symbol should be used if it has a destructor, or if it is a         |
-| mid-rule symbol (i.e., the generated LHS replacing a mid-rule         |
-| action) that was assigned to, as in "exp: { $$ = 1; } { $$ = $1; }".  |
+| A symbol should be used if either:                                    |
+|   1. It has a destructor.                                             |
+|   2. --warnings=midrule-values and the symbol is a mid-rule symbol    |
+|      (i.e., the generated LHS replacing a mid-rule action) that was   |
+|      assigned to or used, as in "exp: { $$ = 1; } { $$ = $1; }".      |
 `----------------------------------------------------------------------*/
 
 static bool
 symbol_should_be_used (symbol_list const *s)
 {
-  return (symbol_destructor_get (s->content.sym)
-         || (s->midrule && s->midrule->used)
-         || (s->midrule_parent_rule
-             && symbol_list_n_get (s->midrule_parent_rule,
-                                    s->midrule_parent_rhs_index)->used));
+  if (symbol_destructor_get (s->content.sym))
+    return true;
+  if (warnings_flag & warnings_midrule_values)
+    return ((s->midrule && s->midrule->used)
+           || (s->midrule_parent_rule
+               && symbol_list_n_get (s->midrule_parent_rule,
+                                     s->midrule_parent_rhs_index)->used));
+  return false;
 }
 
 /*----------------------------------------------------------------.
@@ -382,6 +387,7 @@ grammar_midrule_action (void)
 void
 grammar_current_rule_prec_set (symbol *precsym, location loc)
 {
+  symbol_class_set (precsym, token_sym, loc, false);
   if (current_rule->ruleprec)
     complain_at (loc, _("only one %s allowed per rule"), "%prec");
   current_rule->ruleprec = precsym;
@@ -459,11 +465,12 @@ packgram (void)
 
   rules = xnmalloc (nrules, sizeof *rules);
 
-  /* Before invoking grammar_rule_check on any rule, make sure
-     all actions have already been scanned in order to set `used' flags.
-     Otherwise, checking that a midrule's $$ is set will not always work
-     properly because the midrule check must forward-reference the midrule's
-     parent rule.  */
+  /* Before invoking grammar_rule_check on any rule, make sure all actions have
+     already been scanned in order to set `used' flags.  Otherwise, checking
+     that a midrule's $$ should be set will not always work properly because
+     the check must forward-reference the midrule's parent rule.  For the same
+     reason, all the `used' flags must be set before checking whether to remove
+     `$' from any midrule symbol name.  */
   while (p)
     {
       if (p->action)
@@ -492,6 +499,15 @@ packgram (void)
       rules[ruleno].action = p->action;
       rules[ruleno].action_location = p->action_location;
 
+      /* If the midrule's $$ is set or its $n is used, remove the `$' from the
+        symbol name so that it's a user-defined symbol so that the default
+        %destructor and %printer apply.  */
+      if (p->midrule_parent_rule
+          && (p->used
+             || symbol_list_n_get (p->midrule_parent_rule,
+                                   p->midrule_parent_rhs_index)->used))
+       p->content.sym->tag += 1;
+
       /* Don't check the generated rule 0.  It has no action, so some rhs
         symbols may appear unused, but the parsing algorithm ensures that
         %destructor's are invoked appropriately.  */
@@ -656,5 +672,5 @@ check_and_convert_grammar (void)
   packgram ();
 
   /* The grammar as a symbol_list is no longer needed. */
-  LIST_FREE (symbol_list, grammar);
+  symbol_list_free (grammar);
 }