mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 17:53:02 +00:00
warnings: used but undeclared symbols are warnings
We used to raise an error if a symbol appears only in a %printer or %destructor. Make it a warning. * src/symtab.h (status): New enum. (symbol): Replace the binary "declared" with the three-state "status". Adjust dependencies. * src/symtab.c (symbol_check_defined): Needed symbols are an error, whereas "used" are simply warnings. * src/symlist.c (symbol_list_destructor_set, symbol_list_printer): Set symbol status to 'used' when associated to destructors or printers. * input.at (Undeclared symbols used for a printer or destructor): New.
This commit is contained in:
committed by
Akim Demaille
parent
dda2c1adba
commit
b921d92fcb
12
NEWS
12
NEWS
@@ -2,6 +2,18 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
* 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
|
** Additional yylex/yyparse arguments
|
||||||
|
|
||||||
The new directive %param declare additional argument to both yylex
|
The new directive %param declare additional argument to both yylex
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ grammar_rule_check (const symbol_list *r)
|
|||||||
it for char literals and strings, which are always tokens. */
|
it for char literals and strings, which are always tokens. */
|
||||||
if (r->ruleprec
|
if (r->ruleprec
|
||||||
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
|
&& 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"),
|
warn_at (r->location, _("token for %%prec is not defined: %s"),
|
||||||
r->ruleprec->tag);
|
r->ruleprec->tag);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ symbol_list_destructor_set (symbol_list *node, char const *code, location loc)
|
|||||||
{
|
{
|
||||||
case SYMLIST_SYMBOL:
|
case SYMLIST_SYMBOL:
|
||||||
symbol_destructor_set (node->content.sym, &destructor);
|
symbol_destructor_set (node->content.sym, &destructor);
|
||||||
|
if (node->content.sym->status == needed)
|
||||||
|
node->content.sym->status = used;
|
||||||
break;
|
break;
|
||||||
case SYMLIST_TYPE:
|
case SYMLIST_TYPE:
|
||||||
semantic_type_destructor_set (
|
semantic_type_destructor_set (
|
||||||
@@ -256,6 +258,8 @@ symbol_list_printer_set (symbol_list *node, char const *code, location loc)
|
|||||||
{
|
{
|
||||||
case SYMLIST_SYMBOL:
|
case SYMLIST_SYMBOL:
|
||||||
symbol_printer_set (node->content.sym, &printer);
|
symbol_printer_set (node->content.sym, &printer);
|
||||||
|
if (node->content.sym->status == needed)
|
||||||
|
node->content.sym->status = used;
|
||||||
break;
|
break;
|
||||||
case SYMLIST_TYPE:
|
case SYMLIST_TYPE:
|
||||||
semantic_type_printer_set (
|
semantic_type_printer_set (
|
||||||
|
|||||||
25
src/symtab.c
25
src/symtab.c
@@ -85,7 +85,7 @@ symbol_new (uniqstr tag, location loc)
|
|||||||
|
|
||||||
res->alias = NULL;
|
res->alias = NULL;
|
||||||
res->class = unknown_sym;
|
res->class = unknown_sym;
|
||||||
res->declared = false;
|
res->status = needed;
|
||||||
|
|
||||||
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
||||||
fatal (_("too many symbols in input grammar (limit is %d)"),
|
fatal (_("too many symbols in input grammar (limit is %d)"),
|
||||||
@@ -361,7 +361,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
|||||||
if (sym->class != unknown_sym && sym->class != class)
|
if (sym->class != unknown_sym && sym->class != class)
|
||||||
{
|
{
|
||||||
complain_at (loc, _("symbol %s redefined"), sym->tag);
|
complain_at (loc, _("symbol %s redefined"), sym->tag);
|
||||||
sym->declared = false;
|
sym->status = needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class == nterm_sym && sym->class != nterm_sym)
|
if (class == nterm_sym && sym->class != nterm_sym)
|
||||||
@@ -373,9 +373,9 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
|||||||
|
|
||||||
if (declaring)
|
if (declaring)
|
||||||
{
|
{
|
||||||
if (sym->declared)
|
if (sym->status == declared)
|
||||||
warn_at (loc, _("symbol %s redeclared"), sym->tag);
|
warn_at (loc, _("symbol %s redeclared"), sym->tag);
|
||||||
sym->declared = true;
|
sym->status = declared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,10 +421,19 @@ symbol_check_defined (symbol *sym)
|
|||||||
{
|
{
|
||||||
if (sym->class == unknown_sym)
|
if (sym->class == unknown_sym)
|
||||||
{
|
{
|
||||||
complain_at
|
if (sym->status == needed)
|
||||||
(sym->location,
|
complain_at
|
||||||
_("symbol %s is used, but is not defined as a token and has no rules"),
|
(sym->location,
|
||||||
sym->tag);
|
_("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->class = nterm_sym;
|
||||||
sym->number = nvars++;
|
sym->number = nvars++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ typedef int symbol_number;
|
|||||||
|
|
||||||
typedef struct symbol symbol;
|
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
|
/* When extending this structure, be sure to complete
|
||||||
symbol_check_alias_consistency. */
|
symbol_check_alias_consistency. */
|
||||||
struct symbol
|
struct symbol
|
||||||
@@ -90,7 +97,7 @@ struct symbol
|
|||||||
symbol-string pair for an alias. */
|
symbol-string pair for an alias. */
|
||||||
symbol *alias;
|
symbol *alias;
|
||||||
symbol_class class;
|
symbol_class class;
|
||||||
bool declared;
|
status status;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Undefined user number. */
|
/** Undefined user number. */
|
||||||
|
|||||||
@@ -271,6 +271,30 @@ input.y:5.10-24: previous declaration
|
|||||||
|
|
||||||
AT_CLEANUP
|
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. ##
|
## Unused values with default %destructor. ##
|
||||||
|
|||||||
Reference in New Issue
Block a user