Home | History | Annotate | Download | only in src
      1 /* Symbol table manager for Bison.
      2 
      3    Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software
      4    Foundation, Inc.
      5 
      6    This file is part of Bison, the GNU Compiler Compiler.
      7 
      8    This program 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 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program 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.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20 
     21 #include <config.h>
     22 #include "system.h"
     23 
     24 #include <hash.h>
     25 
     26 #include "complain.h"
     27 #include "gram.h"
     28 #include "symtab.h"
     29 
     30 /*-------------------------------------------------------------------.
     31 | Symbols sorted by tag.  Allocated by the first invocation of       |
     32 | symbols_do, after which no more symbols should be created.         |
     33 `-------------------------------------------------------------------*/
     34 
     35 static symbol **symbols_sorted = NULL;
     36 
     37 /*------------------------.
     38 | Distinguished symbols.  |
     39 `------------------------*/
     40 
     41 symbol *errtoken = NULL;
     42 symbol *undeftoken = NULL;
     43 symbol *endtoken = NULL;
     44 symbol *accept = NULL;
     45 symbol *startsymbol = NULL;
     46 location startsymbol_location;
     47 
     48 /*---------------------------------------.
     49 | Default %destructor's and %printer's.  |
     50 `---------------------------------------*/
     51 
     52 static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT;
     53 static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT;
     54 static code_props default_tagged_printer = CODE_PROPS_NONE_INIT;
     55 static code_props default_tagless_printer = CODE_PROPS_NONE_INIT;
     56 
     57 /*---------------------------------.
     58 | Create a new symbol, named TAG.  |
     59 `---------------------------------*/
     60 
     61 static symbol *
     62 symbol_new (uniqstr tag, location loc)
     63 {
     64   symbol *res = xmalloc (sizeof *res);
     65 
     66   uniqstr_assert (tag);
     67 
     68   /* If the tag is not a string (starts with a double quote), check
     69      that it is valid for Yacc. */
     70   if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-'))
     71     yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"),
     72              tag);
     73 
     74   res->tag = tag;
     75   res->location = loc;
     76 
     77   res->type_name = NULL;
     78   code_props_none_init (&res->destructor);
     79   code_props_none_init (&res->printer);
     80 
     81   res->number = NUMBER_UNDEFINED;
     82   res->prec = 0;
     83   res->assoc = undef_assoc;
     84   res->user_token_number = USER_NUMBER_UNDEFINED;
     85 
     86   res->alias = NULL;
     87   res->class = unknown_sym;
     88   res->declared = false;
     89 
     90   if (nsyms == SYMBOL_NUMBER_MAXIMUM)
     91     fatal (_("too many symbols in input grammar (limit is %d)"),
     92 	   SYMBOL_NUMBER_MAXIMUM);
     93   nsyms++;
     94   return res;
     95 }
     96 
     97 /*----------------------------------------.
     98 | Create a new semantic type, named TAG.  |
     99 `----------------------------------------*/
    100 
    101 static semantic_type *
    102 semantic_type_new (uniqstr tag)
    103 {
    104   semantic_type *res = xmalloc (sizeof *res);
    105 
    106   uniqstr_assert (tag);
    107   res->tag = tag;
    108   code_props_none_init (&res->destructor);
    109   code_props_none_init (&res->printer);
    110 
    111   return res;
    112 }
    113 
    114 
    115 /*-----------------.
    116 | Print a symbol.  |
    117 `-----------------*/
    118 
    119 #define SYMBOL_ATTR_PRINT(Attr)				\
    120   if (s->Attr)						\
    121     fprintf (f, " %s { %s }", #Attr, s->Attr)
    122 
    123 #define SYMBOL_CODE_PRINT(Attr)                         \
    124   if (s->Attr.code)                                     \
    125     fprintf (f, " %s { %s }", #Attr, s->Attr.code)
    126 
    127 void
    128 symbol_print (symbol *s, FILE *f)
    129 {
    130   if (s)
    131     {
    132       fprintf (f, "\"%s\"", s->tag);
    133       SYMBOL_ATTR_PRINT (type_name);
    134       SYMBOL_CODE_PRINT (destructor);
    135       SYMBOL_CODE_PRINT (printer);
    136     }
    137   else
    138     fprintf (f, "<NULL>");
    139 }
    140 
    141 #undef SYMBOL_ATTR_PRINT
    142 #undef SYMBOL_CODE_PRINT
    143 
    144 /*------------------------------------------------------------------.
    145 | Complain that S's WHAT is redeclared at SECOND, and was first set |
    146 | at FIRST.                                                         |
    147 `------------------------------------------------------------------*/
    148 
    149 static void
    150 symbol_redeclaration (symbol *s, const char *what, location first,
    151                       location second)
    152 {
    153   unsigned i = 0;
    154   complain_at_indent (second, &i, _("%s redeclaration for %s"), what, s->tag);
    155   i += SUB_INDENT;
    156   complain_at_indent (first, &i, _("previous declaration"));
    157 }
    158 
    159 static void
    160 semantic_type_redeclaration (semantic_type *s, const char *what, location first,
    161                              location second)
    162 {
    163   unsigned i = 0;
    164   complain_at_indent (second, &i, _("%s redeclaration for <%s>"), what, s->tag);
    165   i += SUB_INDENT;
    166   complain_at_indent (first, &i, _("previous declaration"));
    167 }
    168 
    169 
    170 
    171 /*-----------------------------------------------------------------.
    172 | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 |
    173 | as TYPE_NAME.                                                    |
    174 `-----------------------------------------------------------------*/
    175 
    176 void
    177 symbol_type_set (symbol *sym, uniqstr type_name, location loc)
    178 {
    179   if (type_name)
    180     {
    181       if (sym->type_name)
    182 	symbol_redeclaration (sym, "%type", sym->type_location, loc);
    183       uniqstr_assert (type_name);
    184       sym->type_name = type_name;
    185       sym->type_location = loc;
    186     }
    187 }
    188 
    189 /*-----------------------------------------.
    190 | Set the DESTRUCTOR associated with SYM.  |
    191 `-----------------------------------------*/
    192 
    193 void
    194 symbol_destructor_set (symbol *sym, code_props const *destructor)
    195 {
    196   if (sym->destructor.code)
    197     symbol_redeclaration (sym, "%destructor", sym->destructor.location,
    198                           destructor->location);
    199   sym->destructor = *destructor;
    200 }
    201 
    202 /*------------------------------------------.
    203 | Set the DESTRUCTOR associated with TYPE.  |
    204 `------------------------------------------*/
    205 
    206 void
    207 semantic_type_destructor_set (semantic_type *type,
    208                               code_props const *destructor)
    209 {
    210   if (type->destructor.code)
    211     semantic_type_redeclaration (type, "%destructor",
    212                                  type->destructor.location,
    213                                  destructor->location);
    214   type->destructor = *destructor;
    215 }
    216 
    217 /*---------------------------------------.
    218 | Get the computed %destructor for SYM.  |
    219 `---------------------------------------*/
    220 
    221 code_props const *
    222 symbol_destructor_get (symbol const *sym)
    223 {
    224   /* Per-symbol %destructor.  */
    225   if (sym->destructor.code)
    226     return &sym->destructor;
    227 
    228   /* Per-type %destructor.  */
    229   if (sym->type_name)
    230     {
    231       code_props const *destructor =
    232         &semantic_type_get (sym->type_name)->destructor;
    233       if (destructor->code)
    234         return destructor;
    235     }
    236 
    237   /* Apply default %destructor's only to user-defined symbols.  */
    238   if (sym->tag[0] == '$' || sym == errtoken)
    239     return &code_props_none;
    240 
    241   if (sym->type_name)
    242     return &default_tagged_destructor;
    243   return &default_tagless_destructor;
    244 }
    245 
    246 /*--------------------------------------.
    247 | Set the PRINTER associated with SYM.  |
    248 `--------------------------------------*/
    249 
    250 void
    251 symbol_printer_set (symbol *sym, code_props const *printer)
    252 {
    253   if (sym->printer.code)
    254     symbol_redeclaration (sym, "%printer",
    255                           sym->printer.location, printer->location);
    256   sym->printer = *printer;
    257 }
    258 
    259 /*---------------------------------------.
    260 | Set the PRINTER associated with TYPE.  |
    261 `---------------------------------------*/
    262 
    263 void
    264 semantic_type_printer_set (semantic_type *type, code_props const *printer)
    265 {
    266   if (type->printer.code)
    267     semantic_type_redeclaration (type, "%printer",
    268                                  type->printer.location, printer->location);
    269   type->printer = *printer;
    270 }
    271 
    272 /*------------------------------------.
    273 | Get the computed %printer for SYM.  |
    274 `------------------------------------*/
    275 
    276 code_props const *
    277 symbol_printer_get (symbol const *sym)
    278 {
    279   /* Per-symbol %printer.  */
    280   if (sym->printer.code)
    281     return &sym->printer;
    282 
    283   /* Per-type %printer.  */
    284   if (sym->type_name)
    285     {
    286       code_props const *printer = &semantic_type_get (sym->type_name)->printer;
    287       if (printer->code)
    288         return printer;
    289     }
    290 
    291   /* Apply the default %printer only to user-defined symbols.  */
    292   if (sym->tag[0] == '$' || sym == errtoken)
    293     return &code_props_none;
    294 
    295   if (sym->type_name)
    296     return &default_tagged_printer;
    297   return &default_tagless_printer;
    298 }
    299 
    300 /*-----------------------------------------------------------------.
    301 | Set the PRECEDENCE associated with SYM.  Does nothing if invoked |
    302 | with UNDEF_ASSOC as ASSOC.                                       |
    303 `-----------------------------------------------------------------*/
    304 
    305 void
    306 symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
    307 {
    308   if (a != undef_assoc)
    309     {
    310       if (sym->prec != 0)
    311 	symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
    312                               loc);
    313       sym->prec = prec;
    314       sym->assoc = a;
    315       sym->prec_location = loc;
    316     }
    317 
    318   /* Only terminals have a precedence. */
    319   symbol_class_set (sym, token_sym, loc, false);
    320 }
    321 
    322 
    323 /*------------------------------------.
    324 | Set the CLASS associated with SYM.  |
    325 `------------------------------------*/
    326 
    327 void
    328 symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
    329 {
    330   if (sym->class != unknown_sym && sym->class != class)
    331     {
    332       complain_at (loc, _("symbol %s redefined"), sym->tag);
    333       sym->declared = false;
    334     }
    335 
    336   if (class == nterm_sym && sym->class != nterm_sym)
    337     sym->number = nvars++;
    338   else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
    339     sym->number = ntokens++;
    340 
    341   sym->class = class;
    342 
    343   if (declaring)
    344     {
    345       if (sym->declared)
    346 	warn_at (loc, _("symbol %s redeclared"), sym->tag);
    347       sym->declared = true;
    348     }
    349 }
    350 
    351 
    352 /*------------------------------------------------.
    353 | Set the USER_TOKEN_NUMBER associated with SYM.  |
    354 `------------------------------------------------*/
    355 
    356 void
    357 symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
    358 {
    359   int *user_token_numberp;
    360 
    361   if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
    362     user_token_numberp = &sym->user_token_number;
    363   else
    364     user_token_numberp = &sym->alias->user_token_number;
    365   if (*user_token_numberp != USER_NUMBER_UNDEFINED
    366       && *user_token_numberp != user_token_number)
    367     complain_at (loc, _("redefining user token number of %s"), sym->tag);
    368 
    369   *user_token_numberp = user_token_number;
    370   /* User defined $end token? */
    371   if (user_token_number == 0)
    372     {
    373       endtoken = sym;
    374       /* It is always mapped to 0, so it was already counted in
    375 	 NTOKENS.  */
    376       if (endtoken->number != NUMBER_UNDEFINED)
    377         --ntokens;
    378       endtoken->number = 0;
    379     }
    380 }
    381 
    382 
    383 /*----------------------------------------------------------.
    384 | If SYM is not defined, report an error, and consider it a |
    385 | nonterminal.                                              |
    386 `----------------------------------------------------------*/
    387 
    388 static inline bool
    389 symbol_check_defined (symbol *sym)
    390 {
    391   if (sym->class == unknown_sym)
    392     {
    393       complain_at
    394 	(sym->location,
    395 	 _("symbol %s is used, but is not defined as a token and has no rules"),
    396 	 sym->tag);
    397       sym->class = nterm_sym;
    398       sym->number = nvars++;
    399     }
    400 
    401   return true;
    402 }
    403 
    404 static bool
    405 symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
    406 {
    407   return symbol_check_defined (sym);
    408 }
    409 
    410 
    411 void
    412 symbol_make_alias (symbol *sym, symbol *str, location loc)
    413 {
    414   if (str->alias)
    415     warn_at (loc, _("symbol %s used more than once as a literal string"),
    416              str->tag);
    417   else if (sym->alias)
    418     warn_at (loc, _("symbol %s given more than one literal string"),
    419              sym->tag);
    420   else
    421     {
    422       str->class = token_sym;
    423       str->user_token_number = sym->user_token_number;
    424       sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
    425       str->alias = sym;
    426       sym->alias = str;
    427       str->number = sym->number;
    428       symbol_type_set (str, sym->type_name, loc);
    429     }
    430 }
    431 
    432 
    433 /*---------------------------------------------------------.
    434 | Check that THIS, and its alias, have same precedence and |
    435 | associativity.                                           |
    436 `---------------------------------------------------------*/
    437 
    438 static inline void
    439 symbol_check_alias_consistency (symbol *this)
    440 {
    441   symbol *sym = this;
    442   symbol *str = this->alias;
    443 
    444   /* Check only the symbol in the symbol-string pair.  */
    445   if (!(this->alias
    446         && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
    447     return;
    448 
    449   if (str->type_name != sym->type_name)
    450     {
    451       if (str->type_name)
    452 	symbol_type_set (sym, str->type_name, str->type_location);
    453       else
    454 	symbol_type_set (str, sym->type_name, sym->type_location);
    455     }
    456 
    457 
    458   if (str->destructor.code || sym->destructor.code)
    459     {
    460       if (str->destructor.code)
    461 	symbol_destructor_set (sym, &str->destructor);
    462       else
    463 	symbol_destructor_set (str, &sym->destructor);
    464     }
    465 
    466   if (str->printer.code || sym->printer.code)
    467     {
    468       if (str->printer.code)
    469 	symbol_printer_set (sym, &str->printer);
    470       else
    471 	symbol_printer_set (str, &sym->printer);
    472     }
    473 
    474   if (sym->prec || str->prec)
    475     {
    476       if (str->prec)
    477 	symbol_precedence_set (sym, str->prec, str->assoc,
    478 			       str->prec_location);
    479       else
    480 	symbol_precedence_set (str, sym->prec, sym->assoc,
    481 			       sym->prec_location);
    482     }
    483 }
    484 
    485 static bool
    486 symbol_check_alias_consistency_processor (void *this,
    487 					  void *null ATTRIBUTE_UNUSED)
    488 {
    489   symbol_check_alias_consistency (this);
    490   return true;
    491 }
    492 
    493 
    494 /*-------------------------------------------------------------------.
    495 | Assign a symbol number, and write the definition of the token name |
    496 | into FDEFINES.  Put in SYMBOLS.                                    |
    497 `-------------------------------------------------------------------*/
    498 
    499 static inline bool
    500 symbol_pack (symbol *this)
    501 {
    502   aver (this->number != NUMBER_UNDEFINED);
    503   if (this->class == nterm_sym)
    504     this->number += ntokens;
    505   else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
    506     return true;
    507 
    508   symbols[this->number] = this;
    509   return true;
    510 }
    511 
    512 static bool
    513 symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
    514 {
    515   return symbol_pack (this);
    516 }
    517 
    518 
    519 static void
    520 user_token_number_redeclaration (int num, symbol *first, symbol *second)
    521 {
    522   unsigned i = 0;
    523   /* User token numbers are not assigned during the parsing, but in a
    524      second step, via a traversal of the symbol table sorted on tag.
    525 
    526      However, error messages make more sense if we keep the first
    527      declaration first.  */
    528   if (location_cmp (first->location, second->location) > 0)
    529     {
    530       symbol* tmp = first;
    531       first = second;
    532       second = tmp;
    533     }
    534   complain_at_indent (second->location, &i,
    535                       _("user token number %d redeclaration for %s"),
    536                       num, second->tag);
    537   i += SUB_INDENT;
    538   complain_at_indent (first->location, &i,
    539                       _("previous declaration for %s"),
    540                       first->tag);
    541 }
    542 
    543 /*--------------------------------------------------.
    544 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
    545 `--------------------------------------------------*/
    546 
    547 static inline bool
    548 symbol_translation (symbol *this)
    549 {
    550   /* Non-terminal? */
    551   if (this->class == token_sym
    552       && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
    553     {
    554       /* A token which translation has already been set? */
    555       if (token_translations[this->user_token_number] != undeftoken->number)
    556 	user_token_number_redeclaration
    557           (this->user_token_number,
    558            symbols[token_translations[this->user_token_number]],
    559            this);
    560 
    561       token_translations[this->user_token_number] = this->number;
    562     }
    563 
    564   return true;
    565 }
    566 
    567 static bool
    568 symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
    569 {
    570   return symbol_translation (this);
    571 }
    572 
    573 
    574 /*---------------------------------------.
    575 | Symbol and semantic type hash tables.  |
    576 `---------------------------------------*/
    577 
    578 /* Initial capacity of symbol and semantic type hash table.  */
    579 #define HT_INITIAL_CAPACITY 257
    580 
    581 static struct hash_table *symbol_table = NULL;
    582 static struct hash_table *semantic_type_table = NULL;
    583 
    584 static inline bool
    585 hash_compare_symbol (const symbol *m1, const symbol *m2)
    586 {
    587   /* Since tags are unique, we can compare the pointers themselves.  */
    588   return UNIQSTR_EQ (m1->tag, m2->tag);
    589 }
    590 
    591 static inline bool
    592 hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
    593 {
    594   /* Since names are unique, we can compare the pointers themselves.  */
    595   return UNIQSTR_EQ (m1->tag, m2->tag);
    596 }
    597 
    598 static bool
    599 hash_symbol_comparator (void const *m1, void const *m2)
    600 {
    601   return hash_compare_symbol (m1, m2);
    602 }
    603 
    604 static bool
    605 hash_semantic_type_comparator (void const *m1, void const *m2)
    606 {
    607   return hash_compare_semantic_type (m1, m2);
    608 }
    609 
    610 static inline size_t
    611 hash_symbol (const symbol *m, size_t tablesize)
    612 {
    613   /* Since tags are unique, we can hash the pointer itself.  */
    614   return ((uintptr_t) m->tag) % tablesize;
    615 }
    616 
    617 static inline size_t
    618 hash_semantic_type (const semantic_type *m, size_t tablesize)
    619 {
    620   /* Since names are unique, we can hash the pointer itself.  */
    621   return ((uintptr_t) m->tag) % tablesize;
    622 }
    623 
    624 static size_t
    625 hash_symbol_hasher (void const *m, size_t tablesize)
    626 {
    627   return hash_symbol (m, tablesize);
    628 }
    629 
    630 static size_t
    631 hash_semantic_type_hasher (void const *m, size_t tablesize)
    632 {
    633   return hash_semantic_type (m, tablesize);
    634 }
    635 
    636 /*-------------------------------.
    637 | Create the symbol hash table.  |
    638 `-------------------------------*/
    639 
    640 void
    641 symbols_new (void)
    642 {
    643   symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
    644 				  NULL,
    645 				  hash_symbol_hasher,
    646 				  hash_symbol_comparator,
    647 				  free);
    648   semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
    649 				         NULL,
    650 				         hash_semantic_type_hasher,
    651 				         hash_semantic_type_comparator,
    652 				         free);
    653 }
    654 
    655 
    656 /*----------------------------------------------------------------.
    657 | Find the symbol named KEY, and return it.  If it does not exist |
    658 | yet, create it.                                                 |
    659 `----------------------------------------------------------------*/
    660 
    661 symbol *
    662 symbol_from_uniqstr (const uniqstr key, location loc)
    663 {
    664   symbol probe;
    665   symbol *entry;
    666 
    667   probe.tag = key;
    668   entry = hash_lookup (symbol_table, &probe);
    669 
    670   if (!entry)
    671     {
    672       /* First insertion in the hash. */
    673       aver (!symbols_sorted);
    674       entry = symbol_new (key, loc);
    675       if (!hash_insert (symbol_table, entry))
    676         xalloc_die ();
    677     }
    678   return entry;
    679 }
    680 
    681 
    682 /*-----------------------------------------------------------------------.
    683 | Find the semantic type named KEY, and return it.  If it does not exist |
    684 | yet, create it.                                                        |
    685 `-----------------------------------------------------------------------*/
    686 
    687 semantic_type *
    688 semantic_type_from_uniqstr (const uniqstr key)
    689 {
    690   semantic_type probe;
    691   semantic_type *entry;
    692 
    693   probe.tag = key;
    694   entry = hash_lookup (semantic_type_table, &probe);
    695 
    696   if (!entry)
    697     {
    698       /* First insertion in the hash. */
    699       entry = semantic_type_new (key);
    700       if (!hash_insert (semantic_type_table, entry))
    701         xalloc_die ();
    702     }
    703   return entry;
    704 }
    705 
    706 
    707 /*----------------------------------------------------------------.
    708 | Find the symbol named KEY, and return it.  If it does not exist |
    709 | yet, create it.                                                 |
    710 `----------------------------------------------------------------*/
    711 
    712 symbol *
    713 symbol_get (const char *key, location loc)
    714 {
    715   return symbol_from_uniqstr (uniqstr_new (key), loc);
    716 }
    717 
    718 
    719 /*-----------------------------------------------------------------------.
    720 | Find the semantic type named KEY, and return it.  If it does not exist |
    721 | yet, create it.                                                        |
    722 `-----------------------------------------------------------------------*/
    723 
    724 semantic_type *
    725 semantic_type_get (const char *key)
    726 {
    727   return semantic_type_from_uniqstr (uniqstr_new (key));
    728 }
    729 
    730 
    731 /*------------------------------------------------------------------.
    732 | Generate a dummy nonterminal, whose name cannot conflict with the |
    733 | user's names.                                                     |
    734 `------------------------------------------------------------------*/
    735 
    736 symbol *
    737 dummy_symbol_get (location loc)
    738 {
    739   /* Incremented for each generated symbol.  */
    740   static int dummy_count = 0;
    741   static char buf[256];
    742 
    743   symbol *sym;
    744 
    745   sprintf (buf, "$@%d", ++dummy_count);
    746   sym = symbol_get (buf, loc);
    747   sym->class = nterm_sym;
    748   sym->number = nvars++;
    749   return sym;
    750 }
    751 
    752 bool
    753 symbol_is_dummy (const symbol *sym)
    754 {
    755   return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
    756 }
    757 
    758 /*-------------------.
    759 | Free the symbols.  |
    760 `-------------------*/
    761 
    762 void
    763 symbols_free (void)
    764 {
    765   hash_free (symbol_table);
    766   hash_free (semantic_type_table);
    767   free (symbols);
    768   free (symbols_sorted);
    769 }
    770 
    771 
    772 /*---------------------------------------------------------------.
    773 | Look for undefined symbols, report an error, and consider them |
    774 | terminals.                                                     |
    775 `---------------------------------------------------------------*/
    776 
    777 static int
    778 symbols_cmp (symbol const *a, symbol const *b)
    779 {
    780   return strcmp (a->tag, b->tag);
    781 }
    782 
    783 static int
    784 symbols_cmp_qsort (void const *a, void const *b)
    785 {
    786   return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
    787 }
    788 
    789 static void
    790 symbols_do (Hash_processor processor, void *processor_data)
    791 {
    792   size_t count = hash_get_n_entries (symbol_table);
    793   if (!symbols_sorted)
    794     {
    795       symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
    796       hash_get_entries (symbol_table, (void**)symbols_sorted, count);
    797       qsort (symbols_sorted, count, sizeof *symbols_sorted,
    798              symbols_cmp_qsort);
    799     }
    800   {
    801     size_t i;
    802     for (i = 0; i < count; ++i)
    803       processor (symbols_sorted[i], processor_data);
    804   }
    805 }
    806 
    807 /*--------------------------------------------------------------.
    808 | Check that all the symbols are defined.  Report any undefined |
    809 | symbols and consider them nonterminals.                       |
    810 `--------------------------------------------------------------*/
    811 
    812 void
    813 symbols_check_defined (void)
    814 {
    815   symbols_do (symbol_check_defined_processor, NULL);
    816 }
    817 
    818 /*------------------------------------------------------------------.
    819 | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same |
    820 | number.                                                           |
    821 `------------------------------------------------------------------*/
    822 
    823 static void
    824 symbols_token_translations_init (void)
    825 {
    826   bool num_256_available_p = true;
    827   int i;
    828 
    829   /* Find the highest user token number, and whether 256, the POSIX
    830      preferred user token number for the error token, is used.  */
    831   max_user_token_number = 0;
    832   for (i = 0; i < ntokens; ++i)
    833     {
    834       symbol *this = symbols[i];
    835       if (this->user_token_number != USER_NUMBER_UNDEFINED)
    836 	{
    837 	  if (this->user_token_number > max_user_token_number)
    838 	    max_user_token_number = this->user_token_number;
    839 	  if (this->user_token_number == 256)
    840 	    num_256_available_p = false;
    841 	}
    842     }
    843 
    844   /* If 256 is not used, assign it to error, to follow POSIX.  */
    845   if (num_256_available_p
    846       && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
    847     errtoken->user_token_number = 256;
    848 
    849   /* Set the missing user numbers. */
    850   if (max_user_token_number < 256)
    851     max_user_token_number = 256;
    852 
    853   for (i = 0; i < ntokens; ++i)
    854     {
    855       symbol *this = symbols[i];
    856       if (this->user_token_number == USER_NUMBER_UNDEFINED)
    857 	this->user_token_number = ++max_user_token_number;
    858       if (this->user_token_number > max_user_token_number)
    859 	max_user_token_number = this->user_token_number;
    860     }
    861 
    862   token_translations = xnmalloc (max_user_token_number + 1,
    863 				 sizeof *token_translations);
    864 
    865   /* Initialize all entries for literal tokens to 2, the internal
    866      token number for $undefined, which represents all invalid inputs.
    867      */
    868   for (i = 0; i < max_user_token_number + 1; i++)
    869     token_translations[i] = undeftoken->number;
    870   symbols_do (symbol_translation_processor, NULL);
    871 }
    872 
    873 
    874 /*----------------------------------------------------------------.
    875 | Assign symbol numbers, and write definition of token names into |
    876 | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        |
    877 `----------------------------------------------------------------*/
    878 
    879 void
    880 symbols_pack (void)
    881 {
    882   symbols_do (symbol_check_alias_consistency_processor, NULL);
    883 
    884   symbols = xcalloc (nsyms, sizeof *symbols);
    885   symbols_do (symbol_pack_processor, NULL);
    886 
    887   /* Aliases leave empty slots in symbols, so remove them.  */
    888   {
    889     int writei;
    890     int readi;
    891     int nsyms_old = nsyms;
    892     for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
    893       {
    894         if (symbols[readi] == NULL)
    895           {
    896             nsyms -= 1;
    897             ntokens -= 1;
    898           }
    899         else
    900           {
    901             symbols[writei] = symbols[readi];
    902             symbols[writei]->number = writei;
    903             if (symbols[writei]->alias)
    904               symbols[writei]->alias->number = writei;
    905             writei += 1;
    906           }
    907       }
    908   }
    909   symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
    910 
    911   symbols_token_translations_init ();
    912 
    913   if (startsymbol->class == unknown_sym)
    914     fatal_at (startsymbol_location,
    915 	      _("the start symbol %s is undefined"),
    916 	      startsymbol->tag);
    917   else if (startsymbol->class == token_sym)
    918     fatal_at (startsymbol_location,
    919 	      _("the start symbol %s is a token"),
    920 	      startsymbol->tag);
    921 }
    922 
    923 
    924 /*--------------------------------------------------.
    925 | Set default tagged/tagless %destructor/%printer.  |
    926 `--------------------------------------------------*/
    927 
    928 void
    929 default_tagged_destructor_set (code_props const *destructor)
    930 {
    931   if (default_tagged_destructor.code)
    932     {
    933       unsigned i = 0;
    934       complain_at_indent (destructor->location, &i,
    935                           _("redeclaration for default tagged %%destructor"));
    936       i += SUB_INDENT;
    937       complain_at_indent (default_tagged_destructor.location, &i,
    938 		          _("previous declaration"));
    939     }
    940   default_tagged_destructor = *destructor;
    941 }
    942 
    943 void
    944 default_tagless_destructor_set (code_props const *destructor)
    945 {
    946   if (default_tagless_destructor.code)
    947     {
    948       unsigned i = 0;
    949       complain_at_indent (destructor->location, &i,
    950                           _("redeclaration for default tagless %%destructor"));
    951       i += SUB_INDENT;
    952       complain_at_indent (default_tagless_destructor.location, &i,
    953                           _("previous declaration"));
    954     }
    955   default_tagless_destructor = *destructor;
    956 }
    957 
    958 void
    959 default_tagged_printer_set (code_props const *printer)
    960 {
    961   if (default_tagged_printer.code)
    962     {
    963       unsigned i = 0;
    964       complain_at_indent (printer->location, &i,
    965                           _("redeclaration for default tagged %%printer"));
    966       i += SUB_INDENT;
    967       complain_at_indent (default_tagged_printer.location, &i,
    968 		          _("previous declaration"));
    969     }
    970   default_tagged_printer = *printer;
    971 }
    972 
    973 void
    974 default_tagless_printer_set (code_props const *printer)
    975 {
    976   if (default_tagless_printer.code)
    977     {
    978       unsigned i = 0;
    979       complain_at_indent (printer->location, &i,
    980                           _("redeclaration for default tagless %%printer"));
    981       i += SUB_INDENT;
    982       complain_at_indent (default_tagless_printer.location, &i,
    983 		          _("previous declaration"));
    984     }
    985   default_tagless_printer = *printer;
    986 }
    987