multistart: introduce and use rule_is_accepting

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
commit aa21f8fc966dc24b7d775758846fef70bfc9317d
Author: Akim Demaille <[email protected]>
Date:   Sun Nov 8 17:50:46 2020 +0100

    multistart: introduce and use rule_is_accepting
    
    * src/gram.h (rule_is_accepting): New.
    * src/graphviz.c, src/print-xml.c, src/print.c, src/lalr.c: Use it.
    Some of these occurrences were incorrect (checking whether this is
    rule 0), and not behaving properly in the case of multistart.

diff --git a/TODO b/TODO
index 8b009d08..c6a71a34 100644
--- a/TODO
+++ b/TODO
@@ -685,25 +685,6 @@ participate in the count.
 Do we want to disallow terminal start symbols?  The limitation is not
 technical.  Can it be useful to someone to "parse" a token?
 
-*** Fix default_reduction_only_for_accept
-In src/lalr.c:
-
-  /* We need a lookahead either to distinguish different reductions
-     (i.e., there are two or more), or to distinguish a reduction from a
-     shift.  Otherwise, it is straightforward, and the state is
-     'consistent'.  However, do not treat a state with any reductions as
-     consistent unless it is the accepting state (because there is never
-     a lookahead token that makes sense there, and so no lookahead token
-     should be read) if the user has otherwise disabled default
-     reductions.  */
-  s->consistent =
-    !(reds->num > 1
-      || (reds->num == 1 && trans->num && TRANSITION_IS_SHIFT (trans, 0))
-      || (reds->num == 1 && reds->rules[0]->number != 0
-          && default_reduction_only_for_accept));
-
-We should have a test for "is accepting rule".
-
 ** %include
 This is a popular demand.  We already made many changes in the parser that
 should make this reasonably easy to implement.
diff --git a/src/gram.h b/src/gram.h
index 95fec9be..fb1f1b85 100644
--- a/src/gram.h
+++ b/src/gram.h
@@ -233,9 +233,23 @@ item_rule (item_number const *item)
 void item_print (item_number *item, rule const *previous_rule,
                  FILE *out);
 
+/*--------.
+| Rules.  |
+`--------*/
+
 /* A function that selects a rule.  */
 typedef bool (*rule_filter) (rule const *);
 
+/* Whether is the accepting rules. */
+static inline bool
+rule_is_accepting (rule const *r)
+{
+  /* In the case of multistart, we need to check whether the LHS is
+     $accept.  In the case of "unistart", it would suffice to
+     check whether this is rule number 0.  */
+  return r->lhs == acceptsymbol->content;
+}
+
 /* Whether the rule has a 'number' smaller than NRULES.  That is, it
    is useful in the grammar.  */
 bool rule_useful_in_grammar_p (rule const *r);
diff --git a/src/graphviz.c b/src/graphviz.c
index 799d5bef..659629bb 100644
--- a/src/graphviz.c
+++ b/src/graphviz.c
@@ -135,7 +135,7 @@ conclude_red (struct obstack *out, int source, rule_number ruleno,
       /* Build the associated diamond representation of the target rule. */
       fprintf (fout, " \"%dR%d%s\" [label=\"",
                source, ruleno, ed);
-      bool final = rules[ruleno].lhs->symbol == acceptsymbol;
+      bool const final = rule_is_accepting (&rules[ruleno]);
       if (final)
         fprintf (fout, "Acc");
       else
diff --git a/src/lalr.c b/src/lalr.c
index 941a1d68..5d0ee836 100644
--- a/src/lalr.c
+++ b/src/lalr.c
@@ -473,7 +473,7 @@ state_lookaheads_count (state *s, bool default_reduction_only_for_accept)
   s->consistent =
     !(reds->num > 1
       || (reds->num == 1 && trans->num && TRANSITION_IS_SHIFT (trans, 0))
-      || (reds->num == 1 && reds->rules[0]->number != 0
+      || (reds->num == 1 && !rule_is_accepting (reds->rules[0])
           && default_reduction_only_for_accept));
 
   return s->consistent ? 0 : reds->num;
diff --git a/src/print-xml.c b/src/print-xml.c
index 7548fb66..c75bad12 100644
--- a/src/print-xml.c
+++ b/src/print-xml.c
@@ -216,8 +216,7 @@ static void
 print_reduction (FILE *out, int level, char const *lookahead,
                  rule *r, bool enabled)
 {
-  const bool final = r->lhs->symbol == acceptsymbol;
-  if (final)
+  if (rule_is_accepting (r))
     xml_printf (out, level,
                 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
                 xml_escape (lookahead),
diff --git a/src/print.c b/src/print.c
index 4555ba98..f1dfa856 100644
--- a/src/print.c
+++ b/src/print.c
@@ -198,8 +198,7 @@ print_reduction (FILE *out, size_t width,
     fputc (' ', out);
   if (!enabled)
     fputc ('[', out);
-  const bool final = r->lhs->symbol == acceptsymbol;
-  if (final)
+  if (rule_is_accepting (r))
     fprintf (out, _("accept"));
   else
     fprintf (out, _("reduce using rule %d (%s)"), r->number,
@@ -318,7 +317,7 @@ print_reductions (FILE *out, const state *s)
       aver (STREQ (default_reductions, "most")
             || (STREQ (default_reductions, "consistent")
                 && default_reduction_only)
-            || (reds->num == 1 && reds->rules[0]->number == 0));
+            || (reds->num == 1 && rule_is_accepting (reds->rules[0])));
       (void) default_reduction_only;
       free (default_reductions);
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.