[PATCH 1/4] multistart: introduce and use rule_is_initial

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
* src/gram.h (rule_is_initial): 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.
---
 TODO            | 19 -------------------
 src/gram.h      | 15 +++++++++++++++
 src/graphviz.c  |  2 +-
 src/lalr.c      |  2 +-
 src/print-xml.c |  3 +--
 src/print.c     |  5 ++---
 6 files changed, 20 insertions(+), 26 deletions(-)

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..db874e24 100644
--- a/src/gram.h
+++ b/src/gram.h
@@ -233,9 +233,24 @@ 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 an accepting rule (i.e., its reduction terminates
+   parsing with success). */
+static inline bool
+rule_is_initial (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..da4db481 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_initial (&rules[ruleno]);
       if (final)
         fprintf (fout, "Acc");
       else
diff --git a/src/lalr.c b/src/lalr.c
index 941a1d68..8a89d49e 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_initial (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..b1f728d1 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_initial (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..233d257a 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_initial (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_initial (reds->rules[0])));
       (void) default_reduction_only;
       free (default_reductions);
     }
-- 
2.29.2
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.