1 /* Symbol table manager for Bison. 
   3    Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006 Free 
   4    Software Foundation, Inc. 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   8    Bison is free software; you can redistribute it and/or modify 
   9    it under the terms of the GNU General Public License as published by 
  10    the Free Software Foundation; either version 2, or (at your option) 
  13    Bison is distributed in the hope that it will be useful, 
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  16    GNU General Public License for more details. 
  18    You should have received a copy of the GNU General Public License 
  19    along with Bison; see the file COPYING.  If not, write to 
  20    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
  21    Boston, MA 02110-1301, USA.  */ 
  33 /*------------------------. 
  34 | Distinguished symbols.  | 
  35 `------------------------*/ 
  37 symbol 
*errtoken 
= NULL
; 
  38 symbol 
*undeftoken 
= NULL
; 
  39 symbol 
*endtoken 
= NULL
; 
  40 symbol 
*accept 
= NULL
; 
  41 symbol 
*startsymbol 
= NULL
; 
  42 location startsymbol_location
; 
  44 /*---------------------------------. 
  45 | Create a new symbol, named TAG.  | 
  46 `---------------------------------*/ 
  49 symbol_new (uniqstr tag
, location loc
) 
  51   symbol 
*res 
= xmalloc (sizeof *res
); 
  57   res
->type_name 
= NULL
; 
  58   res
->destructor 
= NULL
; 
  61   res
->number 
= NUMBER_UNDEFINED
; 
  63   res
->assoc 
= undef_assoc
; 
  64   res
->user_token_number 
= USER_NUMBER_UNDEFINED
; 
  67   res
->class = unknown_sym
; 
  68   res
->declared 
= false; 
  70   if (nsyms 
== SYMBOL_NUMBER_MAXIMUM
) 
  71     fatal (_("too many symbols in input grammar (limit is %d)"), 
  72            SYMBOL_NUMBER_MAXIMUM
); 
  82 #define SYMBOL_ATTR_PRINT(Attr)                         \ 
  84     fprintf (f, " %s { %s }", #Attr, s->Attr) 
  87 symbol_print (symbol 
*s
, FILE *f
) 
  91       fprintf (f
, "\"%s\"", s
->tag
); 
  92       SYMBOL_ATTR_PRINT (type_name
); 
  93       SYMBOL_ATTR_PRINT (destructor
); 
  94       SYMBOL_ATTR_PRINT (printer
); 
  97     fprintf (f
, "<NULL>"); 
 100 #undef SYMBOL_ATTR_PRINT 
 102 /*------------------------------------------------------------------. 
 103 | Complain that S's WHAT is redeclared at SECOND, and was first set | 
 105 `------------------------------------------------------------------*/ 
 108 redeclaration (symbol
* s
, const char *what
, location first
, location second
) 
 110   complain_at (second
, _("%s redeclaration for %s"), what
, s
->tag
); 
 111   complain_at (first
, _("previous declaration")); 
 115 /*-----------------------------------------------------------------. 
 116 | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 | 
 118 `-----------------------------------------------------------------*/ 
 121 symbol_type_set (symbol 
*sym
, uniqstr type_name
, location loc
) 
 126         redeclaration (sym
, "%type", sym
->type_location
, loc
); 
 127       uniqstr_assert (type_name
); 
 128       sym
->type_name 
= type_name
; 
 129       sym
->type_location 
= loc
; 
 134 /*------------------------------------------------------------------. 
 135 | Set the DESTRUCTOR associated with SYM.  Do nothing if passed 0.  | 
 136 `------------------------------------------------------------------*/ 
 139 symbol_destructor_set (symbol 
*sym
, const char *destructor
, location loc
) 
 144         redeclaration (sym
, "%destructor", sym
->destructor_location
, loc
); 
 145       sym
->destructor 
= destructor
; 
 146       sym
->destructor_location 
= loc
; 
 151 /*---------------------------------------------------------------. 
 152 | Set the PRINTER associated with SYM.  Do nothing if passed 0.  | 
 153 `---------------------------------------------------------------*/ 
 156 symbol_printer_set (symbol 
*sym
, const char *printer
, location loc
) 
 161         redeclaration (sym
, "%printer", sym
->printer_location
, loc
); 
 162       sym
->printer 
= printer
; 
 163       sym
->printer_location 
= loc
; 
 168 /*-----------------------------------------------------------------. 
 169 | Set the PRECEDENCE associated with SYM.  Does nothing if invoked | 
 170 | with UNDEF_ASSOC as ASSOC.                                       | 
 171 `-----------------------------------------------------------------*/ 
 174 symbol_precedence_set (symbol 
*sym
, int prec
, assoc a
, location loc
) 
 176   if (a 
!= undef_assoc
) 
 179         redeclaration (sym
, assoc_to_string (a
), sym
->prec_location
, loc
); 
 182       sym
->prec_location 
= loc
; 
 185   /* Only terminals have a precedence. */ 
 186   symbol_class_set (sym
, token_sym
, loc
, false); 
 190 /*------------------------------------. 
 191 | Set the CLASS associated with SYM.  | 
 192 `------------------------------------*/ 
 195 symbol_class_set (symbol 
*sym
, symbol_class 
class, location loc
, bool declaring
) 
 197   if (sym
->class != unknown_sym 
&& sym
->class != class) 
 199       complain_at (loc
, _("symbol %s redefined"), sym
->tag
); 
 200       sym
->declared 
= false; 
 203   if (class == nterm_sym 
&& sym
->class != nterm_sym
) 
 204     sym
->number 
= nvars
++; 
 205   else if (class == token_sym 
&& sym
->number 
== NUMBER_UNDEFINED
) 
 206     sym
->number 
= ntokens
++; 
 213         warn_at (loc
, _("symbol %s redeclared"), sym
->tag
); 
 214       sym
->declared 
= true; 
 219 /*------------------------------------------------. 
 220 | Set the USER_TOKEN_NUMBER associated with SYM.  | 
 221 `------------------------------------------------*/ 
 224 symbol_user_token_number_set (symbol 
*sym
, int user_token_number
, location loc
) 
 226   assert (sym
->class == token_sym
); 
 228   if (sym
->user_token_number 
!= USER_NUMBER_UNDEFINED
 
 229       && sym
->user_token_number 
!= user_token_number
) 
 230     complain_at (loc
, _("redefining user token number of %s"), sym
->tag
); 
 232   sym
->user_token_number 
= user_token_number
; 
 233   /* User defined $end token? */ 
 234   if (user_token_number 
== 0) 
 237       endtoken
->number 
= 0; 
 238       /* It is always mapped to 0, so it was already counted in 
 245 /*----------------------------------------------------------. 
 246 | If SYM is not defined, report an error, and consider it a | 
 248 `----------------------------------------------------------*/ 
 251 symbol_check_defined (symbol 
*sym
) 
 253   if (sym
->class == unknown_sym
) 
 257          _("symbol %s is used, but is not defined as a token and has no rules"), 
 259       sym
->class = nterm_sym
; 
 260       sym
->number 
= nvars
++; 
 267 symbol_check_defined_processor (void *sym
, void *null ATTRIBUTE_UNUSED
) 
 269   return symbol_check_defined (sym
); 
 273 /*------------------------------------------------------------------. 
 274 | Declare the new symbol SYM.  Make it an alias of SYMVAL, and type | 
 275 | SYMVAL with SYM's type.                                           | 
 276 `------------------------------------------------------------------*/ 
 279 symbol_make_alias (symbol 
*sym
, symbol 
*symval
, location loc
) 
 282     warn_at (loc
, _("symbol `%s' used more than once as a literal string"), 
 285     warn_at (loc
, _("symbol `%s' given more than one literal string"), 
 289       symval
->class = token_sym
; 
 290       symval
->user_token_number 
= sym
->user_token_number
; 
 291       sym
->user_token_number 
= USER_NUMBER_ALIAS
; 
 294       /* sym and symval combined are only one symbol.  */ 
 297       assert (ntokens 
== sym
->number 
|| ntokens 
== symval
->number
); 
 298       sym
->number 
= symval
->number 
= 
 299         (symval
->number 
< sym
->number
) ? symval
->number 
: sym
->number
; 
 300       symbol_type_set (symval
, sym
->type_name
, loc
); 
 305 /*---------------------------------------------------------. 
 306 | Check that THIS, and its alias, have same precedence and | 
 308 `---------------------------------------------------------*/ 
 311 symbol_check_alias_consistency (symbol 
*this) 
 313   symbol 
*alias 
= this; 
 314   symbol 
*orig  
= this->alias
; 
 316   /* Check only those that _are_ the aliases.  */ 
 317   if (!(this->alias 
&& this->user_token_number 
== USER_NUMBER_ALIAS
)) 
 320   if (orig
->type_name 
!= alias
->type_name
) 
 323         symbol_type_set (alias
, orig
->type_name
, orig
->type_location
); 
 325         symbol_type_set (orig
, alias
->type_name
, alias
->type_location
); 
 329   if (orig
->destructor 
|| alias
->destructor
) 
 331       if (orig
->destructor
) 
 332         symbol_destructor_set (alias
, orig
->destructor
, 
 333                                orig
->destructor_location
); 
 335         symbol_destructor_set (orig
, alias
->destructor
, 
 336                                alias
->destructor_location
); 
 339   if (orig
->printer 
|| alias
->printer
) 
 342         symbol_printer_set (alias
, orig
->printer
, orig
->printer_location
); 
 344         symbol_printer_set (orig
, alias
->printer
, alias
->printer_location
); 
 347   if (alias
->prec 
|| orig
->prec
) 
 350         symbol_precedence_set (alias
, orig
->prec
, orig
->assoc
, 
 351                                orig
->prec_location
); 
 353         symbol_precedence_set (orig
, alias
->prec
, alias
->assoc
, 
 354                                alias
->prec_location
); 
 359 symbol_check_alias_consistency_processor (void *this, 
 360                                           void *null ATTRIBUTE_UNUSED
) 
 362   symbol_check_alias_consistency (this); 
 367 /*-------------------------------------------------------------------. 
 368 | Assign a symbol number, and write the definition of the token name | 
 369 | into FDEFINES.  Put in SYMBOLS.                                    | 
 370 `-------------------------------------------------------------------*/ 
 373 symbol_pack (symbol 
*this) 
 375   if (this->class == nterm_sym
) 
 377       this->number 
+= ntokens
; 
 379   else if (this->alias
) 
 381       /* This symbol and its alias are a single token defn. 
 382          Allocate a tokno, and assign to both check agreement of 
 383          prec and assoc fields and make both the same */ 
 384       if (this->number 
== NUMBER_UNDEFINED
) 
 386           if (this == endtoken 
|| this->alias 
== endtoken
) 
 387             this->number 
= this->alias
->number 
= 0; 
 390               assert (this->alias
->number 
!= NUMBER_UNDEFINED
); 
 391               this->number 
= this->alias
->number
; 
 394       /* Do not do processing below for USER_NUMBER_ALIASes.  */ 
 395       if (this->user_token_number 
== USER_NUMBER_ALIAS
) 
 398   else /* this->class == token_sym */ 
 399     assert (this->number 
!= NUMBER_UNDEFINED
); 
 401   symbols
[this->number
] = this; 
 406 symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 408   return symbol_pack (this); 
 414 /*--------------------------------------------------. 
 415 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  | 
 416 `--------------------------------------------------*/ 
 419 symbol_translation (symbol 
*this) 
 422   if (this->class == token_sym
 
 423       && this->user_token_number 
!= USER_NUMBER_ALIAS
) 
 425       /* A token which translation has already been set? */ 
 426       if (token_translations
[this->user_token_number
] != undeftoken
->number
) 
 427         complain_at (this->location
, 
 428                      _("tokens %s and %s both assigned number %d"), 
 429                      symbols
[token_translations
[this->user_token_number
]]->tag
, 
 430                      this->tag
, this->user_token_number
); 
 432       token_translations
[this->user_token_number
] = this->number
; 
 439 symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 441   return symbol_translation (this); 
 445 /*----------------------. 
 446 | A symbol hash table.  | 
 447 `----------------------*/ 
 449 /* Initial capacity of symbols hash table.  */ 
 450 #define HT_INITIAL_CAPACITY 257 
 452 static struct hash_table 
*symbol_table 
= NULL
; 
 455 hash_compare_symbol (const symbol 
*m1
, const symbol 
*m2
) 
 457   /* Since tags are unique, we can compare the pointers themselves.  */ 
 458   return UNIQSTR_EQ (m1
->tag
, m2
->tag
); 
 462 hash_symbol_comparator (void const *m1
, void const *m2
) 
 464   return hash_compare_symbol (m1
, m2
); 
 468 hash_symbol (const symbol 
*m
, size_t tablesize
) 
 470   /* Since tags are unique, we can hash the pointer itself.  */ 
 471   return ((uintptr_t) m
->tag
) % tablesize
; 
 475 hash_symbol_hasher (void const *m
, size_t tablesize
) 
 477   return hash_symbol (m
, tablesize
); 
 481 /*-------------------------------. 
 482 | Create the symbol hash table.  | 
 483 `-------------------------------*/ 
 488   symbol_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 491                                   hash_symbol_comparator
, 
 496 /*----------------------------------------------------------------. 
 497 | Find the symbol named KEY, and return it.  If it does not exist | 
 499 `----------------------------------------------------------------*/ 
 502 symbol_from_uniqstr (const uniqstr key
, location loc
) 
 508   entry 
= hash_lookup (symbol_table
, &probe
); 
 512       /* First insertion in the hash. */ 
 513       entry 
= symbol_new (key
, loc
); 
 514       hash_insert (symbol_table
, entry
); 
 520 /*----------------------------------------------------------------. 
 521 | Find the symbol named KEY, and return it.  If it does not exist | 
 523 `----------------------------------------------------------------*/ 
 526 symbol_get (const char *key
, location loc
) 
 528   return symbol_from_uniqstr (uniqstr_new (key
), loc
); 
 532 /*------------------------------------------------------------------. 
 533 | Generate a dummy nonterminal, whose name cannot conflict with the | 
 535 `------------------------------------------------------------------*/ 
 538 dummy_symbol_get (location loc
) 
 540   /* Incremented for each generated symbol.  */ 
 541   static int dummy_count 
= 0; 
 542   static char buf
[256]; 
 546   sprintf (buf
, "@%d", ++dummy_count
); 
 547   sym 
= symbol_get (buf
, loc
); 
 548   sym
->class = nterm_sym
; 
 549   sym
->number 
= nvars
++; 
 554 /*-------------------. 
 555 | Free the symbols.  | 
 556 `-------------------*/ 
 561   hash_free (symbol_table
); 
 566 /*---------------------------------------------------------------. 
 567 | Look for undefined symbols, report an error, and consider them | 
 569 `---------------------------------------------------------------*/ 
 572 symbols_do (Hash_processor processor
, void *processor_data
) 
 574   hash_do_for_each (symbol_table
, processor
, processor_data
); 
 578 /*--------------------------------------------------------------. 
 579 | Check that all the symbols are defined.  Report any undefined | 
 580 | symbols and consider them nonterminals.                       | 
 581 `--------------------------------------------------------------*/ 
 584 symbols_check_defined (void) 
 586   symbols_do (symbol_check_defined_processor
, NULL
); 
 589 /*------------------------------------------------------------------. 
 590 | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same | 
 592 `------------------------------------------------------------------*/ 
 595 symbols_token_translations_init (void) 
 597   bool num_256_available_p 
= true; 
 600   /* Find the highest user token number, and whether 256, the POSIX 
 601      preferred user token number for the error token, is used.  */ 
 602   max_user_token_number 
= 0; 
 603   for (i 
= 0; i 
< ntokens
; ++i
) 
 605       symbol 
*this = symbols
[i
]; 
 606       if (this->user_token_number 
!= USER_NUMBER_UNDEFINED
) 
 608           if (this->user_token_number 
> max_user_token_number
) 
 609             max_user_token_number 
= this->user_token_number
; 
 610           if (this->user_token_number 
== 256) 
 611             num_256_available_p 
= false; 
 615   /* If 256 is not used, assign it to error, to follow POSIX.  */ 
 616   if (num_256_available_p
 
 617       && errtoken
->user_token_number 
== USER_NUMBER_UNDEFINED
) 
 618     errtoken
->user_token_number 
= 256; 
 620   /* Set the missing user numbers. */ 
 621   if (max_user_token_number 
< 256) 
 622     max_user_token_number 
= 256; 
 624   for (i 
= 0; i 
< ntokens
; ++i
) 
 626       symbol 
*this = symbols
[i
]; 
 627       if (this->user_token_number 
== USER_NUMBER_UNDEFINED
) 
 628         this->user_token_number 
= ++max_user_token_number
; 
 629       if (this->user_token_number 
> max_user_token_number
) 
 630         max_user_token_number 
= this->user_token_number
; 
 633   token_translations 
= xnmalloc (max_user_token_number 
+ 1, 
 634                                  sizeof *token_translations
); 
 636   /* Initialize all entries for literal tokens to 2, the internal 
 637      token number for $undefined, which represents all invalid inputs. 
 639   for (i 
= 0; i 
< max_user_token_number 
+ 1; i
++) 
 640     token_translations
[i
] = undeftoken
->number
; 
 641   symbols_do (symbol_translation_processor
, NULL
); 
 645 /*----------------------------------------------------------------. 
 646 | Assign symbol numbers, and write definition of token names into | 
 647 | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        | 
 648 `----------------------------------------------------------------*/ 
 653   symbols 
= xcalloc (nsyms
, sizeof *symbols
); 
 655   symbols_do (symbol_check_alias_consistency_processor
, NULL
); 
 656   symbols_do (symbol_pack_processor
, NULL
); 
 658   symbols_token_translations_init (); 
 660   if (startsymbol
->class == unknown_sym
) 
 661     fatal_at (startsymbol_location
, 
 662               _("the start symbol %s is undefined"), 
 664   else if (startsymbol
->class == token_sym
) 
 665     fatal_at (startsymbol_location
, 
 666               _("the start symbol %s is a token"),