multistart: adjust reader checks for generated rules

So far we were not checking the generated rule 0 at all.  Now there
can be several of them.  Instead of not checking at all, let's be more
selective on the check to run on them.

* src/reader.c (grammar_rule_check_and_complete): Don't check for
value usage for generated rules, it is ok to have a valued start
symbol, in which case it is ok for the generated rule ("accept: start
$end {}") to not use $1.
(packgram): Call grammar_rule_check_and_complete for all the rules.
This commit is contained in:
Akim Demaille
2020-07-05 07:56:04 +02:00
parent a0b044186b
commit a6805bb8d9

View File

@@ -266,6 +266,7 @@ symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
static void static void
grammar_rule_check_and_complete (symbol_list *r) grammar_rule_check_and_complete (symbol_list *r)
{ {
const symbol *lhs = r->content.sym;
/* Type check. /* Type check.
If there is an action, then there is nothing we can do: the user If there is an action, then there is nothing we can do: the user
@@ -273,13 +274,13 @@ grammar_rule_check_and_complete (symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */ value can't be used. */
if (!r->action_props.code && r->content.sym->content->type_name) if (!r->action_props.code && lhs->content->type_name)
{ {
symbol *first_rhs = r->next->content.sym; symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */ /* If $$ is being set in default way, report if any type mismatch. */
if (first_rhs) if (first_rhs)
{ {
char const *lhs_type = r->content.sym->content->type_name; char const *lhs_type = lhs->content->type_name;
char const *rhs_type = char const *rhs_type =
first_rhs->content->type_name ? first_rhs->content->type_name : ""; first_rhs->content->type_name ? first_rhs->content->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type)) if (!UNIQSTR_EQ (lhs_type, rhs_type))
@@ -311,25 +312,29 @@ grammar_rule_check_and_complete (symbol_list *r)
_("empty rule for typed nonterminal, and no action")); _("empty rule for typed nonterminal, and no action"));
} }
/* Check that symbol values that should be used are in fact used. */ /* Check that symbol values that should be used are in fact used.
{ Don't check the generated start rules. It has no action, so some
int n = 0; rhs symbols may appear unused, but the parsing algorithm ensures
for (symbol_list const *l = r; l && l->content.sym; l = l->next, ++n) that %destructor's are invoked appropriately. */
{ if (lhs != acceptsymbol)
bool midrule_warning = false; {
if (!l->action_props.is_value_used int n = 0;
&& symbol_should_be_used (l, &midrule_warning) for (symbol_list const *l = r; l && l->content.sym; l = l->next, ++n)
/* The default action, $$ = $1, 'uses' both. */ {
&& (r->action_props.code || (n != 0 && n != 1))) bool midrule_warning = false;
{ if (!l->action_props.is_value_used
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother; && symbol_should_be_used (l, &midrule_warning)
if (n) /* The default action, $$ = $1, 'uses' both. */
complain (&l->sym_loc, warn_flag, _("unused value: $%d"), n); && (r->action_props.code || (n != 0 && n != 1)))
else {
complain (&l->rhs_loc, warn_flag, _("unset value: $$")); warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
} if (n)
} complain (&l->sym_loc, warn_flag, _("unused value: $%d"), n);
} else
complain (&l->rhs_loc, warn_flag, _("unset value: $$"));
}
}
}
/* Check that %empty => empty rule. */ /* Check that %empty => empty rule. */
if (r->percent_empty_loc.start.file if (r->percent_empty_loc.start.file
@@ -624,11 +629,7 @@ packgram (void)
->action_props.is_value_used))) ->action_props.is_value_used)))
lhs->content.sym->tag += 1; lhs->content.sym->tag += 1;
/* Don't check the generated rule 0. It has no action, so some rhs grammar_rule_check_and_complete (lhs);
symbols may appear unused, but the parsing algorithm ensures that
%destructor's are invoked appropriately. */
if (lhs != grammar)
grammar_rule_check_and_complete (lhs);
rules[ruleno].code = ruleno; rules[ruleno].code = ruleno;
rules[ruleno].number = ruleno; rules[ruleno].number = ruleno;