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:
Joel E. Denny
2006-06-26 04:16:50 +00:00
parent 300a193064
commit ffa4ba3aef
6 changed files with 205 additions and 85 deletions

View File

@@ -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));