246 |
grammar_current_rule_check (void) |
grammar_current_rule_check (void) |
247 |
{ |
{ |
248 |
symbol_t *lhs = current_rule->sym; |
symbol_t *lhs = current_rule->sym; |
249 |
|
char const *lhs_type = lhs->type_name; |
250 |
symbol_t *first_rhs = current_rule->next->sym; |
symbol_t *first_rhs = current_rule->next->sym; |
251 |
|
|
252 |
/* 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 |
253 |
is allowed to shoot in her foot. */ |
is allowed to shoot herself in the foot. */ |
254 |
if (current_rule->action) |
if (current_rule->action) |
255 |
return; |
return; |
256 |
|
|
257 |
/* If $$ is being set in default way, report if any type mismatch. |
/* Don't worry about the default action if $$ is untyped, since $$'s |
258 |
*/ |
value can't be used. */ |
259 |
|
if (! lhs_type) |
260 |
|
return; |
261 |
|
|
262 |
|
/* If $$ is being set in default way, report if any type mismatch. */ |
263 |
if (first_rhs) |
if (first_rhs) |
264 |
{ |
{ |
|
const char *lhs_type = lhs->type_name ? lhs->type_name : ""; |
|
265 |
const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : ""; |
const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : ""; |
266 |
if (strcmp (lhs_type, rhs_type)) |
if (strcmp (lhs_type, rhs_type)) |
267 |
complain_at (current_rule->location, |
complain_at (current_rule->location, |
270 |
} |
} |
271 |
/* Warn if there is no default for $$ but we need one. */ |
/* Warn if there is no default for $$ but we need one. */ |
272 |
else |
else |
273 |
{ |
complain_at (current_rule->location, |
274 |
if (lhs->type_name) |
_("empty rule for typed nonterminal, and no action")); |
|
complain_at (current_rule->location, |
|
|
_("empty rule for typed nonterminal, and no action")); |
|
|
} |
|
275 |
} |
} |
276 |
|
|
277 |
|
|