* src/symtab.c (symbol_check_alias_consistency): Also check

type names, destructors, and printers.
Reported by Alexandre Duret-Lutz.
Recode the handling of associativity and precedence in terms
of symbol_precedence_set.
Accept no redeclaration at all, not even equal to the previous
value.
(redeclaration): New.
Use it to factor redeclaration complaints.
(symbol_make_alias): Don't set the type of the alias, let
symbol_check_alias_consistency do it as for other features.
* src/symtab.h (symbol): Add new member prec_location, and
type_location.
* src/symtab.c (symbol_precedence_set, symbol_type_set): Set them.
* tests/input.at (Incompatible Aliases): New.
This commit is contained in:
Akim Demaille
2004-10-11 09:03:55 +00:00
parent 2ed24dd8c7
commit df09ef2e8f
4 changed files with 128 additions and 39 deletions

View File

@@ -1,3 +1,21 @@
2004-10-11 Akim Demaille <akim@epita.fr>
* src/symtab.c (symbol_check_alias_consistency): Also check
type names, destructors, and printers.
Reported by Alexandre Duret-Lutz.
Recode the handling of associativity and precedence in terms
of symbol_precedence_set.
Accept no redeclaration at all, not even equal to the previous
value.
(redeclaration): New.
Use it to factor redeclaration complaints.
(symbol_make_alias): Don't set the type of the alias, let
symbol_check_alias_consistency do it as for other features.
* src/symtab.h (symbol): Add new member prec_location, and
type_location.
* src/symtab.c (symbol_precedence_set, symbol_type_set): Set them.
* tests/input.at (Incompatible Aliases): New.
2004-10-09 Paul Eggert <eggert@cs.ucla.edu>
.cvsignore fixes to accommodate gnulib changes,

View File

@@ -71,6 +71,19 @@ symbol_new (uniqstr tag, location loc)
}
/*------------------------------------------------------------------.
| Complain that S's WHAT is redeclared at SECOND, and was first set |
| at FIRST. |
`------------------------------------------------------------------*/
static void
redeclaration (symbol* s, const char *what, location first, location second)
{
complain_at (second, _("%s redeclaration for %s"), what, s->tag);
complain_at (first, _("first declaration"));
}
/*-----------------------------------------------------------------.
| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
| as TYPE_NAME. |
@@ -82,9 +95,10 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
if (type_name)
{
if (sym->type_name)
complain_at (loc, _("type redeclaration for %s"), sym->tag);
redeclaration (sym, "%type", sym->type_location, loc);
uniqstr_assert (type_name);
sym->type_name = type_name;
sym->type_location = loc;
}
}
@@ -99,8 +113,7 @@ symbol_destructor_set (symbol *sym, char *destructor, location loc)
if (destructor)
{
if (sym->destructor)
complain_at (loc, _("%s redeclaration for %s"),
"%destructor", sym->tag);
redeclaration (sym, "%destructor", sym->destructor_location, loc);
sym->destructor = destructor;
sym->destructor_location = loc;
}
@@ -117,8 +130,7 @@ symbol_printer_set (symbol *sym, char *printer, location loc)
if (printer)
{
if (sym->printer)
complain_at (loc, _("%s redeclaration for %s"),
"%printer", sym->tag);
redeclaration (sym, "%printer", sym->destructor_location, loc);
sym->printer = printer;
sym->printer_location = loc;
}
@@ -136,9 +148,10 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
if (a != undef_assoc)
{
if (sym->prec != 0)
complain_at (loc, _("redefining precedence of %s"), sym->tag);
redeclaration (sym, assoc_to_string (a), sym->prec_location, loc);
sym->prec = prec;
sym->assoc = a;
sym->prec_location = loc;
}
/* Only terminals have a precedence. */
@@ -230,10 +243,10 @@ symbol_make_alias (symbol *sym, symbol *symval, location loc)
{
if (symval->alias)
warn_at (loc, _("symbol `%s' used more than once as a literal string"),
symval->tag);
symval->tag);
else if (sym->alias)
warn_at (loc, _("symbol `%s' given more than one literal string"),
sym->tag);
sym->tag);
else
{
symval->class = token_sym;
@@ -248,7 +261,6 @@ symbol_make_alias (symbol *sym, symbol *symval, location loc)
abort ();
sym->number = symval->number =
(symval->number < sym->number) ? symval->number : sym->number;
symbol_type_set (symval, sym->type_name, loc);
}
}
@@ -258,45 +270,60 @@ symbol_make_alias (symbol *sym, symbol *symval, location loc)
| associativity. |
`---------------------------------------------------------*/
static inline bool
static inline void
symbol_check_alias_consistency (symbol *this)
{
/* Check only those who _are_ the aliases. */
if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
{
if (this->prec != this->alias->prec)
{
if (this->prec != 0 && this->alias->prec != 0)
complain_at (this->alias->location,
_("conflicting precedences for %s and %s"),
this->tag, this->alias->tag);
if (this->prec != 0)
this->alias->prec = this->prec;
else
this->prec = this->alias->prec;
}
symbol *alias = this;
symbol *orig = this->alias;
if (this->assoc != this->alias->assoc)
{
if (this->assoc != undef_assoc && this->alias->assoc != undef_assoc)
complain_at (this->alias->location,
_("conflicting associativities for %s (%s) and %s (%s)"),
this->tag, assoc_to_string (this->assoc),
this->alias->tag, assoc_to_string (this->alias->assoc));
if (this->assoc != undef_assoc)
this->alias->assoc = this->assoc;
else
this->assoc = this->alias->assoc;
}
/* Check only those that _are_ the aliases. */
if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
return;
if (orig->type_name || alias->type_name)
{
if (orig->type_name)
symbol_type_set (alias, orig->type_name, orig->type_location);
else
symbol_type_set (orig, alias->type_name, alias->type_location);
}
if (orig->destructor || alias->destructor)
{
if (orig->destructor)
symbol_destructor_set (alias, orig->destructor,
orig->destructor_location);
else
symbol_destructor_set (orig, alias->destructor,
alias->destructor_location);
}
if (orig->printer || alias->printer)
{
if (orig->printer)
symbol_printer_set (alias, orig->printer, orig->printer_location);
else
symbol_printer_set (orig, alias->printer, alias->printer_location);
}
if (alias->prec || orig->prec)
{
if (orig->prec)
symbol_precedence_set (alias, orig->prec, orig->assoc,
orig->prec_location);
else
symbol_precedence_set (orig, alias->prec, alias->assoc,
alias->prec_location);
}
return true;
}
static bool
symbol_check_alias_consistency_processor (void *this,
void *null ATTRIBUTE_UNUSED)
{
return symbol_check_alias_consistency (this);
symbol_check_alias_consistency (this);
return true;
}

View File

@@ -46,6 +46,9 @@ typedef short int symbol_number;
typedef struct symbol symbol;
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol
{
/* The key, name of the symbol. */
@@ -55,12 +58,16 @@ struct symbol
/* Its %type and associated printer and destructor. */
uniqstr type_name;
location type_location;
char *destructor;
location destructor_location;
char *printer;
location printer_location;
symbol_number number;
location prec_location;
short int prec;
assoc assoc;
int user_token_number;

View File

@@ -1,5 +1,5 @@
# Checking the Bison scanner. -*- Autotest -*-
# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -82,6 +82,43 @@ input.y:6.5: warning: empty rule for typed nonterminal, and no action
AT_CLEANUP
## ---------------------- ##
## Incompatible Aliases. ##
## ---------------------- ##
AT_SETUP([Incompatible Aliases])
AT_DATA([input.y],
[[%token foo "foo"
%type <bar> foo
%printer {bar} foo
%destructor {bar} foo
%left foo
%type <baz> "foo"
%printer {baz} "foo"
%destructor {baz} "foo"
%left "foo"
%%
exp: foo;
]])
AT_CHECK([bison input.y], [1], [],
[[input.y:8.7-11: %type redeclaration for foo
input.y:3.7-11: first declaration
input.y:10.13-17: %destructor redeclaration for foo
input.y:5.13-17: first declaration
input.y:9.19-23: %printer redeclaration for foo
input.y:10.13-17: first declaration
input.y:11.1-5: %left redeclaration for foo
input.y:6.1-5: first declaration
]])
AT_CLEANUP
## ----------------------- ##
## Torturing the Scanner. ##