From a38d0b914507d2c9163eef84240bf1a059a0659f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 8 Nov 2020 17:50:46 +0100 Subject: [PATCH] multistart: introduce and use rule_is_initial * 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, "", 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); }