parser: improve the error message for symbol class redefinition

Currently our error messages include both "symbol redeclared" and
"symbol redefined", and they mean something different.  This is
obscure, let's make this clearer.

I think the idea between 'definition' vs. 'declaration' is that in the
case of the nonterminals, the actual definition is its set of rules,
so %nterm would be about declaration.  The case of %token is less
clear.

* src/symtab.c (complain_class_redefined): New.
(symbol_class_set): Use it.
Simplify the logic of this function to clearly skip its body when the
preconditions are not met.
* tests/input.at (Symbol class redefinition): New.
This commit is contained in:
Akim Demaille
2018-12-09 08:14:35 +01:00
parent afdefecab6
commit 20b0746793
3 changed files with 74 additions and 18 deletions

5
TODO
View File

@@ -7,6 +7,11 @@ Several features are not available in all the backends.
- token constructors: Java and C - token constructors: Java and C
* Short term * Short term
** consistency
nonterminal vs non terminal vs non-terminal
token vs terminal
redeclaration vs redefinition
** yacc.c ** yacc.c
Now that ylwrap is fixed, we should include foo.tab.h from foo.tab.c rather Now that ylwrap is fixed, we should include foo.tab.h from foo.tab.c rather
than duplicating it. than duplicating it.

View File

@@ -302,6 +302,19 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first,
_("previous declaration")); _("previous declaration"));
} }
static void
complain_class_redeclared (symbol *sym, symbol_class class, location second)
{
unsigned i = 0;
complain_indent (&second, complaint, &i,
class == token_sym
? _("symbol %s redeclared as a token")
: _("symbol %s redeclared as a nonterminal"), sym->tag);
i += SUB_INDENT;
complain_indent (&sym->location, complaint, &i,
_("previous definition"));
}
void void
symbol_location_as_lhs_set (symbol *sym, location loc) symbol_location_as_lhs_set (symbol *sym, location loc)
@@ -430,27 +443,26 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
void void
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{ {
bool warned = false; aver (class != unknown_sym);
if (sym->content->class != unknown_sym && sym->content->class != class) sym_content *s = sym->content;
if (s->class != unknown_sym && s->class != class)
complain_class_redeclared (sym, class, loc);
else
{ {
complain (&loc, complaint, _("symbol %s redefined"), sym->tag); s->class = class;
/* Don't report both "redefined" and "redeclared". */
warned = true;
}
if (class == nterm_sym && sym->content->class != nterm_sym) if (class == nterm_sym && s->class != nterm_sym)
sym->content->number = nvars++; s->number = nvars++;
else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED) else if (class == token_sym && s->number == NUMBER_UNDEFINED)
sym->content->number = ntokens++; s->number = ntokens++;
sym->content->class = class; if (declaring)
{
if (declaring) if (s->status == declared)
{ complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
if (sym->content->status == declared && !warned) else
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag); s->status = declared;
else }
sym->content->status = declared;
} }
} }

View File

@@ -483,6 +483,45 @@ AT_CHECK_UNUSED_VALUES([1], [1])
AT_CLEANUP AT_CLEANUP
## --------------------------- ##
## Symbol class redefinition. ##
## --------------------------- ##
AT_SETUP([Symbol class redefinition])
AT_DATA([[input.y]],
[[%token FOO
%nterm FOO BAR
%token BAR
%%
FOO: BAR
BAR:
]])
AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:2.1-6: warning: deprecated directive, use '%type' [-Wdeprecated]
%nterm FOO BAR
^^^^^^
input.y:2.8-10: error: symbol FOO redeclared as a nonterminal
%nterm FOO BAR
^^^
input.y:1.8-10: previous definition
%token FOO
^^^
input.y:3.8-10: error: symbol BAR redeclared as a token
%token BAR
^^^
input.y:2.12-14: previous definition
%nterm FOO BAR
^^^
input.y:5.1-3: error: rule given for FOO, which is a token
FOO: BAR
^^^
]])
AT_CLEANUP
## --------------------------------------------- ## ## --------------------------------------------- ##
## Default %printer and %destructor redeclared. ## ## Default %printer and %destructor redeclared. ##
## --------------------------------------------- ## ## --------------------------------------------- ##