mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
Get action warnings (grammar_rule_check) right even when symbol
declarations appear after the rules. Don't mistake the type of $$ in a midrule to be that of its parent rule's $$. * src/reader.c (grammar_current_rule_end): Don't invoke grammar_rule_check yet since not all symbol declarations may have been parsed yet. (grammar_midrule_action): Likewise. Don't record whether the midrule's $$ has been used yet since actions haven't been translated yet. Record the midrule's parent rule and its RHS index within the parent rule. (grammar_current_rule_action_append): Don't translate the action yet since not all symbol declarations may have been parsed yet and, thus, warnings about types for $$, $n, @$, and @n can't be reported yet. (packgram): Translate the action and invoke grammar_rule_check now that all symbol declarations have been parsed. * src/scan-code.l (handle_action_dollar): Now that this is invoked after parsing the entire grammar file, the symbol list here in the case of a midrule is actually the midrule's empty RHS, so reference its parent rule's RHS where necessary. On the other hand, now that you can already know it's a midrule, you aren't forced to think $$ has the same type as its parent rule's $$. (handle_action_at): In the case of a midrule, reference the parent rule where necessary. * src/symlist.c (symbol_list_new): Initialize new midrule-related members. (symbol_list_length): Now that this is invoked after all rules have been parsed, a NULL symbol (rather than a NULL symbol list node) terminates a rule. symbol_list_print already does this correctly. * src/symlist.h (symbol_list.midrule_parent_rule, symbol_list.midrule_parent_rhs_index): New members so that midrules can remember their relationships with their parents. * tests/input.at (Type Clashes): Extend to catch the midrule $$ error fixed by the above patch. (_AT_UNUSED_VALUES_DECLARATIONS, AT_CHECK_UNUSED_VALUES): New m4 macros implementing... (Unused values): ... this old test case and... (Unused values before symbol declarations): ... this new test case. This one is the same as `Unused values' except that all symbol declarations appear after the rules in order to catch the rest of the errors fixed by the above patch.
This commit is contained in:
@@ -240,7 +240,19 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
{
|
||||
const char *type_name = NULL;
|
||||
char *cp = text + 1;
|
||||
int rule_length = symbol_list_length (rule->next);
|
||||
symbol_list *effective_rule;
|
||||
int effective_rule_length;
|
||||
|
||||
if (rule->midrule_parent_rule)
|
||||
{
|
||||
effective_rule = rule->midrule_parent_rule;
|
||||
effective_rule_length = rule->midrule_parent_rhs_index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
effective_rule = rule;
|
||||
effective_rule_length = symbol_list_length (rule->next);
|
||||
}
|
||||
|
||||
/* Get the type name if explicit. */
|
||||
if (*cp == '<')
|
||||
@@ -257,8 +269,17 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
if (!type_name)
|
||||
type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
|
||||
if (!type_name && typed)
|
||||
complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
|
||||
rule->sym->tag);
|
||||
{
|
||||
if (rule->midrule_parent_rule)
|
||||
complain_at (dollar_loc,
|
||||
_("$$ for the midrule at $%d of `%s' has no declared"
|
||||
" type"),
|
||||
rule->midrule_parent_rhs_index,
|
||||
effective_rule->sym->tag);
|
||||
else
|
||||
complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
|
||||
rule->sym->tag);
|
||||
}
|
||||
if (!type_name)
|
||||
type_name = "";
|
||||
obstack_fgrow1 (&obstack_for_string,
|
||||
@@ -270,23 +291,23 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
long int num;
|
||||
set_errno (0);
|
||||
num = strtol (cp, 0, 10);
|
||||
if (INT_MIN <= num && num <= rule_length && ! get_errno ())
|
||||
if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
|
||||
{
|
||||
int n = num;
|
||||
if (1-n > max_left_semantic_context)
|
||||
max_left_semantic_context = 1-n;
|
||||
if (!type_name && n > 0)
|
||||
type_name =
|
||||
symbol_list_n_type_name_get (rule, dollar_loc, n);
|
||||
symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
|
||||
if (!type_name && typed)
|
||||
complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
|
||||
n, rule->sym->tag);
|
||||
n, effective_rule->sym->tag);
|
||||
if (!type_name)
|
||||
type_name = "";
|
||||
obstack_fgrow3 (&obstack_for_string,
|
||||
"]b4_rhs_value(%d, %d, [%s])[",
|
||||
rule_length, n, type_name);
|
||||
symbol_list_n_used_set (rule, n, true);
|
||||
effective_rule_length, n, type_name);
|
||||
symbol_list_n_used_set (effective_rule, n, true);
|
||||
}
|
||||
else
|
||||
complain_at (dollar_loc, _("integer out of range: %s"), quote (text));
|
||||
@@ -303,8 +324,13 @@ static void
|
||||
handle_action_at (symbol_list *rule, char *text, location at_loc)
|
||||
{
|
||||
char *cp = text + 1;
|
||||
int rule_length = symbol_list_length (rule->next);
|
||||
locations_flag = true;
|
||||
int effective_rule_length;
|
||||
|
||||
if (rule->midrule_parent_rule)
|
||||
effective_rule_length = rule->midrule_parent_rhs_index - 1;
|
||||
else
|
||||
effective_rule_length = symbol_list_length (rule->next);
|
||||
|
||||
if (*cp == '$')
|
||||
obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
|
||||
@@ -314,11 +340,11 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
|
||||
set_errno (0);
|
||||
num = strtol (cp, 0, 10);
|
||||
|
||||
if (INT_MIN <= num && num <= rule_length && ! get_errno ())
|
||||
if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
|
||||
{
|
||||
int n = num;
|
||||
obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
|
||||
rule_length, n);
|
||||
effective_rule_length, n);
|
||||
}
|
||||
else
|
||||
complain_at (at_loc, _("integer out of range: %s"), quote (text));
|
||||
|
||||
Reference in New Issue
Block a user