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.
This commit is contained in:
Akim Demaille
2020-11-08 17:50:46 +01:00
parent 4b0cd01fb7
commit a38d0b9145
6 changed files with 20 additions and 26 deletions

19
TODO
View File

@@ -685,25 +685,6 @@ participate in the count.
Do we want to disallow terminal start symbols? The limitation is not Do we want to disallow terminal start symbols? The limitation is not
technical. Can it be useful to someone to "parse" a token? 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 ** %include
This is a popular demand. We already made many changes in the parser that This is a popular demand. We already made many changes in the parser that
should make this reasonably easy to implement. should make this reasonably easy to implement.

View File

@@ -233,9 +233,24 @@ item_rule (item_number const *item)
void item_print (item_number *item, rule const *previous_rule, void item_print (item_number *item, rule const *previous_rule,
FILE *out); FILE *out);
/*--------.
| Rules. |
`--------*/
/* A function that selects a rule. */ /* A function that selects a rule. */
typedef bool (*rule_filter) (rule const *); 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 /* Whether the rule has a 'number' smaller than NRULES. That is, it
is useful in the grammar. */ is useful in the grammar. */
bool rule_useful_in_grammar_p (rule const *r); bool rule_useful_in_grammar_p (rule const *r);

View File

@@ -135,7 +135,7 @@ conclude_red (struct obstack *out, int source, rule_number ruleno,
/* Build the associated diamond representation of the target rule. */ /* Build the associated diamond representation of the target rule. */
fprintf (fout, " \"%dR%d%s\" [label=\"", fprintf (fout, " \"%dR%d%s\" [label=\"",
source, ruleno, ed); source, ruleno, ed);
bool final = rules[ruleno].lhs->symbol == acceptsymbol; bool const final = rule_is_initial (&rules[ruleno]);
if (final) if (final)
fprintf (fout, "Acc"); fprintf (fout, "Acc");
else else

View File

@@ -473,7 +473,7 @@ state_lookaheads_count (state *s, bool default_reduction_only_for_accept)
s->consistent = s->consistent =
!(reds->num > 1 !(reds->num > 1
|| (reds->num == 1 && trans->num && TRANSITION_IS_SHIFT (trans, 0)) || (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)); && default_reduction_only_for_accept));
return s->consistent ? 0 : reds->num; return s->consistent ? 0 : reds->num;

View File

@@ -216,8 +216,7 @@ static void
print_reduction (FILE *out, int level, char const *lookahead, print_reduction (FILE *out, int level, char const *lookahead,
rule *r, bool enabled) rule *r, bool enabled)
{ {
const bool final = r->lhs->symbol == acceptsymbol; if (rule_is_initial (r))
if (final)
xml_printf (out, level, xml_printf (out, level,
"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>", "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
xml_escape (lookahead), xml_escape (lookahead),

View File

@@ -198,8 +198,7 @@ print_reduction (FILE *out, size_t width,
fputc (' ', out); fputc (' ', out);
if (!enabled) if (!enabled)
fputc ('[', out); fputc ('[', out);
const bool final = r->lhs->symbol == acceptsymbol; if (rule_is_initial (r))
if (final)
fprintf (out, _("accept")); fprintf (out, _("accept"));
else else
fprintf (out, _("reduce using rule %d (%s)"), r->number, 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") aver (STREQ (default_reductions, "most")
|| (STREQ (default_reductions, "consistent") || (STREQ (default_reductions, "consistent")
&& default_reduction_only) && default_reduction_only)
|| (reds->num == 1 && reds->rules[0]->number == 0)); || (reds->num == 1 && rule_is_initial (reds->rules[0])));
(void) default_reduction_only; (void) default_reduction_only;
free (default_reductions); free (default_reductions);
} }