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

@@ -48,89 +48,123 @@ AT_CLEANUP
AT_SETUP([Type Clashes])
AT_DATA([input.y],
[[%token foo
[[%union { int bar; }
%token foo
%type <bar> exp
%%
exp: foo {} foo
exp: foo { $$; } foo { $2; } foo
| foo
| /* Empty. */
;
]])
AT_CHECK([bison input.y], [], [],
[[input.y:4.6-15: warning: type clash on default action: <bar> != <>
input.y:5.6-8: warning: type clash on default action: <bar> != <>
input.y:6.5: warning: empty rule for typed nonterminal, and no action
AT_CHECK([bison input.y], [1], [],
[[input.y:5.12-13: $$ for the midrule at $2 of `exp' has no declared type
input.y:5.24-25: $2 of `exp' has no declared type
input.y:5.6-32: warning: type clash on default action: <bar> != <>
input.y:6.6-8: warning: type clash on default action: <bar> != <>
input.y:7.5: warning: empty rule for typed nonterminal, and no action
]])
AT_CLEANUP
# _AT_UNUSED_VALUES_DECLARATIONS()
# --------------------------------------------
# Generate the token, type, and destructor
# declarations for the unused values tests.
m4_define([_AT_UNUSED_VALUES_DECLARATIONS],
[[[%token <integer> INT;
%type <integer> a b c d e f g h i j k l;
%destructor { destroy ($$); } INT a b c d e f g h i j k l;]]])
# AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER)
# --------------------------------------------
# Generate a grammar to test unused values,
# compile it, run it. If DECLARATIONS_AFTER
# is set, then the token, type, and destructor
# declarations are generated after the rules
# rather than before.
m4_define([AT_CHECK_UNUSED_VALUES],
[AT_DATA([input.y],
m4_ifval($1, [
], [_AT_UNUSED_VALUES_DECLARATIONS
])[[%%
start:
'a' a { $]2[ } | 'b' b { $]2[ } | 'c' c { $]2[ } | 'd' d { $]2[ } | 'e' e { $]2[ }
| 'f' f { $]2[ } | 'g' g { $]2[ } | 'h' h { $]2[ } | 'i' i { $]2[ } | 'j' j { $]2[ }
| 'k' k { $]2[ } | 'l' l { $]2[ }
;
a: INT | INT { } INT { } INT { };
b: INT | /* empty */;
c: INT | INT { $]1[ } INT { } INT { };
d: INT | INT { } INT { $]1[ } INT { };
e: INT | INT { } INT { } INT { $]1[ };
f: INT | INT { } INT { } INT { $]$[ = $]1[ + $]3[ + $]5[; };
g: INT | INT { $]$[ } INT { $]$[ } INT { };
h: INT | INT { $]$[ } INT { $]$[ = $]2[ } INT { };
i: INT | INT INT { } { $]$[ = $]1[ + $]2[; };
j: INT | INT INT { $<integer>$ = 1; } { $]$[ = $]1[ + $]2[; };
k: INT | INT INT { $]$[; } { $]$[ = $]3[; } { };
l: INT | INT { $]$[ = $]1[; } INT { $]$[ = $]2[ + $]3[; } INT { $]$[ = $]4[ + $]5[; };]]m4_ifval($1, [
_AT_UNUSED_VALUES_DECLARATIONS])
)
AT_CHECK([bison input.y], [0], [],
[[input.y:11.10-32: warning: unset value: $]$[
input.y:11.10-32: warning: unused value: $]1[
input.y:11.10-32: warning: unused value: $]3[
input.y:11.10-32: warning: unused value: $]5[
input.y:12.9: warning: empty rule for typed nonterminal, and no action
input.y:13.10-35: warning: unset value: $]$[
input.y:13.10-35: warning: unused value: $]3[
input.y:13.10-35: warning: unused value: $]5[
input.y:14.10-35: warning: unset value: $]$[
input.y:14.10-35: warning: unused value: $]3[
input.y:14.10-35: warning: unused value: $]5[
input.y:15.10-36: warning: unset value: $]$[
input.y:15.10-36: warning: unused value: $]3[
input.y:15.10-36: warning: unused value: $]5[
input.y:17.10-38: warning: unset value: $]$[
input.y:17.10-38: warning: unused value: $]1[
input.y:17.10-38: warning: unused value: $]2[
input.y:17.10-38: warning: unused value: $]3[
input.y:17.10-38: warning: unused value: $]4[
input.y:17.10-38: warning: unused value: $]5[
input.y:18.10-43: warning: unset value: $]$[
input.y:18.10-43: warning: unused value: $]1[
input.y:18.10-43: warning: unused value: $]3[
input.y:18.10-43: warning: unused value: $]4[
input.y:18.10-43: warning: unused value: $]5[
input.y:20.10-55: warning: unused value: $]3[
input.y:21.10-41: warning: unset value: $]$[
input.y:21.10-41: warning: unused value: $]1[
input.y:21.10-41: warning: unused value: $]2[
input.y:21.10-41: warning: unused value: $]4[
]])])
## --------------- ##
## Unused values. ##
## --------------- ##
AT_SETUP([Unused values])
AT_CHECK_UNUSED_VALUES
AT_CLEANUP
AT_DATA([input.y],
[[%token <integer> INT
%type <integer> a b c d e f g h i j k l
%destructor { destroy ($$); } INT a b c d e f g h i j k l
%%
start:
'a' a { $2 } | 'b' b { $2 } | 'c' c { $2 } | 'd' d { $2 } | 'e' e { $2 }
| 'f' f { $2 } | 'g' g { $2 } | 'h' h { $2 } | 'i' i { $2 } | 'j' j { $2 }
| 'k' k { $2 } | 'l' l { $2 }
;
a: INT | INT { } INT { } INT { };
b: INT | /* empty */;
c: INT | INT { $1 } INT { } INT { };
d: INT | INT { } INT { $1 } INT { };
e: INT | INT { } INT { } INT { $1 };
f: INT | INT { } INT { } INT { $$ = $1 + $3 + $5; };
g: INT | INT { $$ } INT { $$ } INT { };
h: INT | INT { $$ } INT { $$ = $2 } INT { };
i: INT | INT INT { } { $$ = $1 + $2; };
j: INT | INT INT { $<integer>$ = 1; } { $$ = $1 + $2; };
k: INT | INT INT { $$; } { $$ = $3; } { };
l: INT | INT { $$ = $1; } INT { $$ = $2 + $3; } INT { $$ = $4 + $5; };
]])
AT_CHECK([bison input.y], [], [],
[[input.y:11.10-32: warning: unset value: $$
input.y:11.10-32: warning: unused value: $1
input.y:11.10-32: warning: unused value: $3
input.y:11.10-32: warning: unused value: $5
input.y:12.9: warning: empty rule for typed nonterminal, and no action
input.y:13.10-35: warning: unset value: $$
input.y:13.10-35: warning: unused value: $3
input.y:13.10-35: warning: unused value: $5
input.y:14.10-35: warning: unset value: $$
input.y:14.10-35: warning: unused value: $3
input.y:14.10-35: warning: unused value: $5
input.y:15.10-36: warning: unset value: $$
input.y:15.10-36: warning: unused value: $3
input.y:15.10-36: warning: unused value: $5
input.y:17.10-38: warning: unset value: $$
input.y:17.10-38: warning: unused value: $1
input.y:17.10-38: warning: unused value: $2
input.y:17.10-38: warning: unused value: $3
input.y:17.10-38: warning: unused value: $4
input.y:17.10-38: warning: unused value: $5
input.y:18.10-43: warning: unset value: $$
input.y:18.10-43: warning: unused value: $1
input.y:18.10-43: warning: unused value: $3
input.y:18.10-43: warning: unused value: $4
input.y:18.10-43: warning: unused value: $5
input.y:20.10-55: warning: unused value: $3
input.y:21.10-41: warning: unset value: $$
input.y:21.10-41: warning: unused value: $1
input.y:21.10-41: warning: unused value: $2
input.y:21.10-41: warning: unused value: $4
]])
## ------------------------------------------ ##
## Unused values before symbol declarations. ##
## ------------------------------------------ ##
AT_SETUP([Unused values before symbol declarations])
AT_CHECK_UNUSED_VALUES([1])
AT_CLEANUP