* Noteworthy changes in release ?.? (????-??-??) [?]
+** Warnings about undeclared symbols
+
+ Bison used to raise an error for %printer and %destructor directives for
+ undefined symbols.
+
+ %printer {} symbol1
+ %destructor {} symbol2
+ %%
+ exp: "a";
+
+ This is now only a warning.
+
** Additional yylex/yyparse arguments
The new directive %param declare additional argument to both yylex
it for char literals and strings, which are always tokens. */
if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
- && !r->ruleprec->declared && !r->ruleprec->prec)
+ && r->ruleprec->status != declared && !r->ruleprec->prec)
warn_at (r->location, _("token for %%prec is not defined: %s"),
r->ruleprec->tag);
}
{
case SYMLIST_SYMBOL:
symbol_destructor_set (node->content.sym, &destructor);
+ if (node->content.sym->status == needed)
+ node->content.sym->status = used;
break;
case SYMLIST_TYPE:
semantic_type_destructor_set (
{
case SYMLIST_SYMBOL:
symbol_printer_set (node->content.sym, &printer);
+ if (node->content.sym->status == needed)
+ node->content.sym->status = used;
break;
case SYMLIST_TYPE:
semantic_type_printer_set (
res->alias = NULL;
res->class = unknown_sym;
- res->declared = false;
+ res->status = needed;
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
fatal (_("too many symbols in input grammar (limit is %d)"),
if (sym->class != unknown_sym && sym->class != class)
{
complain_at (loc, _("symbol %s redefined"), sym->tag);
- sym->declared = false;
+ sym->status = needed;
}
if (class == nterm_sym && sym->class != nterm_sym)
if (declaring)
{
- if (sym->declared)
+ if (sym->status == declared)
warn_at (loc, _("symbol %s redeclared"), sym->tag);
- sym->declared = true;
+ sym->status = declared;
}
}
{
if (sym->class == unknown_sym)
{
- complain_at
- (sym->location,
- _("symbol %s is used, but is not defined as a token and has no rules"),
- sym->tag);
+ if (sym->status == needed)
+ complain_at
+ (sym->location,
+ _("symbol %s is used, but is not defined as a token and has no"
+ " rules"),
+ sym->tag);
+ else
+ warn_at
+ (sym->location,
+ _("symbol %s is used, but is not defined as a token and has no"
+ " rules"),
+ sym->tag);
+
sym->class = nterm_sym;
sym->number = nvars++;
}
typedef struct symbol symbol;
+typedef enum
+ {
+ needed, /**< found but not "defined". */
+ used, /**< used by %printer but not declared. */
+ declared, /**< defined with %type or %token. */
+ } status;
+
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol
symbol-string pair for an alias. */
symbol *alias;
symbol_class class;
- bool declared;
+ status status;
};
/** Undefined user number. */
AT_CLEANUP
+## ---------------------------------------------------- ##
+## Undeclared symbols used for a printer or destructor. ##
+## ---------------------------------------------------- ##
+
+AT_SETUP([Undeclared symbols used for a printer or destructor])
+
+AT_DATA([[input.y]],
+[[%printer {} token1
+%destructor {} token2
+
+%%
+exp: "a";
+]])
+
+AT_BISON_CHECK([input.y], [0], [],
+[[input.y:1.13-18: warning: symbol token1 is used, but is not defined as a token and has no rules
+input.y:2.16-21: warning: symbol token2 is used, but is not defined as a token and has no rules
+input.y: warning: 2 nonterminals useless in grammar
+input.y:1.13-18: warning: nonterminal useless in grammar: token1
+input.y:2.16-21: warning: nonterminal useless in grammar: token2
+]])
+
+AT_CLEANUP
+
## ---------------------------------------- ##
## Unused values with default %destructor. ##