1 /* Symbol table manager for Bison. 
   3    Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   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. 
  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. 
  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/>.  */ 
  31 /*-------------------------------------------------------------------. 
  32 | Symbols sorted by tag.  Allocated by the first invocation of       | 
  33 | symbols_do, after which no more symbols should be created.         | 
  34 `-------------------------------------------------------------------*/ 
  36 static symbol 
**symbols_sorted 
= NULL
; 
  38 /*------------------------. 
  39 | Distinguished symbols.  | 
  40 `------------------------*/ 
  42 symbol 
*errtoken 
= NULL
; 
  43 symbol 
*undeftoken 
= NULL
; 
  44 symbol 
*endtoken 
= NULL
; 
  45 symbol 
*accept 
= NULL
; 
  46 symbol 
*startsymbol 
= NULL
; 
  47 location startsymbol_location
; 
  49 /*---------------------------------------. 
  50 | Default %destructor's and %printer's.  | 
  51 `---------------------------------------*/ 
  53 static code_props default_tagged_destructor 
= CODE_PROPS_NONE_INIT
; 
  54 static code_props default_tagless_destructor 
= CODE_PROPS_NONE_INIT
; 
  55 static code_props default_tagged_printer 
= CODE_PROPS_NONE_INIT
; 
  56 static code_props default_tagless_printer 
= CODE_PROPS_NONE_INIT
; 
  58 /*---------------------------------. 
  59 | Create a new symbol, named TAG.  | 
  60 `---------------------------------*/ 
  63 symbol_new (uniqstr tag
, location loc
) 
  65   symbol 
*res 
= xmalloc (sizeof *res
); 
  69   /* If the tag is not a string (starts with a double quote), check 
  70      that it is valid for Yacc. */ 
  71   if (tag
[0] != '\"' && tag
[0] != '\'' && mbschr (tag
, '-')) 
  72     yacc_at (loc
, _("POSIX Yacc forbids dashes in symbol names: %s"), 
  78   res
->type_name 
= NULL
; 
  79   code_props_none_init (&res
->destructor
); 
  80   code_props_none_init (&res
->printer
); 
  82   res
->number 
= NUMBER_UNDEFINED
; 
  84   res
->assoc 
= undef_assoc
; 
  85   res
->user_token_number 
= USER_NUMBER_UNDEFINED
; 
  88   res
->class = unknown_sym
; 
  89   res
->declared 
= false; 
  91   if (nsyms 
== SYMBOL_NUMBER_MAXIMUM
) 
  92     fatal (_("too many symbols in input grammar (limit is %d)"), 
  93            SYMBOL_NUMBER_MAXIMUM
); 
  98 /*----------------------------------------. 
  99 | Create a new semantic type, named TAG.  | 
 100 `----------------------------------------*/ 
 102 static semantic_type 
* 
 103 semantic_type_new (uniqstr tag
) 
 105   semantic_type 
*res 
= xmalloc (sizeof *res
); 
 107   uniqstr_assert (tag
); 
 109   code_props_none_init (&res
->destructor
); 
 110   code_props_none_init (&res
->printer
); 
 120 #define SYMBOL_ATTR_PRINT(Attr)                         \ 
 122     fprintf (f, " %s { %s }", #Attr, s->Attr) 
 124 #define SYMBOL_CODE_PRINT(Attr)                         \ 
 126     fprintf (f, " %s { %s }", #Attr, s->Attr.code) 
 129 symbol_print (symbol 
*s
, FILE *f
) 
 133       fprintf (f
, "\"%s\"", s
->tag
); 
 134       SYMBOL_ATTR_PRINT (type_name
); 
 135       SYMBOL_CODE_PRINT (destructor
); 
 136       SYMBOL_CODE_PRINT (printer
); 
 139     fprintf (f
, "<NULL>"); 
 142 #undef SYMBOL_ATTR_PRINT 
 143 #undef SYMBOL_CODE_PRINT 
 145 /*------------------------------------------------------------------. 
 146 | Complain that S's WHAT is redeclared at SECOND, and was first set | 
 148 `------------------------------------------------------------------*/ 
 151 symbol_redeclaration (symbol 
*s
, const char *what
, location first
, 
 154   complain_at (second
, _("%s redeclaration for %s"), what
, s
->tag
); 
 155   complain_at (first
, _("previous declaration")); 
 159 semantic_type_redeclaration (semantic_type 
*s
, const char *what
, location first
, 
 162   complain_at (second
, _("%s redeclaration for <%s>"), what
, s
->tag
); 
 163   complain_at (first
, _("previous declaration")); 
 168 /*-----------------------------------------------------------------. 
 169 | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 | 
 171 `-----------------------------------------------------------------*/ 
 174 symbol_type_set (symbol 
*sym
, uniqstr type_name
, location loc
) 
 179         symbol_redeclaration (sym
, "%type", sym
->type_location
, loc
); 
 180       uniqstr_assert (type_name
); 
 181       sym
->type_name 
= type_name
; 
 182       sym
->type_location 
= loc
; 
 186 /*-----------------------------------------. 
 187 | Set the DESTRUCTOR associated with SYM.  | 
 188 `-----------------------------------------*/ 
 191 symbol_destructor_set (symbol 
*sym
, code_props 
const *destructor
) 
 193   if (sym
->destructor
.code
) 
 194     symbol_redeclaration (sym
, "%destructor", sym
->destructor
.location
, 
 195                           destructor
->location
); 
 196   sym
->destructor 
= *destructor
; 
 199 /*------------------------------------------. 
 200 | Set the DESTRUCTOR associated with TYPE.  | 
 201 `------------------------------------------*/ 
 204 semantic_type_destructor_set (semantic_type 
*type
, 
 205                               code_props 
const *destructor
) 
 207   if (type
->destructor
.code
) 
 208     semantic_type_redeclaration (type
, "%destructor", 
 209                                  type
->destructor
.location
, 
 210                                  destructor
->location
); 
 211   type
->destructor 
= *destructor
; 
 214 /*---------------------------------------. 
 215 | Get the computed %destructor for SYM.  | 
 216 `---------------------------------------*/ 
 219 symbol_destructor_get (symbol 
const *sym
) 
 221   /* Per-symbol %destructor.  */ 
 222   if (sym
->destructor
.code
) 
 223     return &sym
->destructor
; 
 225   /* Per-type %destructor.  */ 
 228       code_props 
const *destructor 
= 
 229         &semantic_type_get (sym
->type_name
)->destructor
; 
 230       if (destructor
->code
) 
 234   /* Apply default %destructor's only to user-defined symbols.  */ 
 235   if (sym
->tag
[0] == '$' || sym 
== errtoken
) 
 236     return &code_props_none
; 
 239     return &default_tagged_destructor
; 
 240   return &default_tagless_destructor
; 
 243 /*--------------------------------------. 
 244 | Set the PRINTER associated with SYM.  | 
 245 `--------------------------------------*/ 
 248 symbol_printer_set (symbol 
*sym
, code_props 
const *printer
) 
 250   if (sym
->printer
.code
) 
 251     symbol_redeclaration (sym
, "%printer", 
 252                           sym
->printer
.location
, printer
->location
); 
 253   sym
->printer 
= *printer
; 
 256 /*---------------------------------------. 
 257 | Set the PRINTER associated with TYPE.  | 
 258 `---------------------------------------*/ 
 261 semantic_type_printer_set (semantic_type 
*type
, code_props 
const *printer
) 
 263   if (type
->printer
.code
) 
 264     semantic_type_redeclaration (type
, "%printer", 
 265                                  type
->printer
.location
, printer
->location
); 
 266   type
->printer 
= *printer
; 
 269 /*------------------------------------. 
 270 | Get the computed %printer for SYM.  | 
 271 `------------------------------------*/ 
 274 symbol_printer_get (symbol 
const *sym
) 
 276   /* Per-symbol %printer.  */ 
 277   if (sym
->printer
.code
) 
 278     return &sym
->printer
; 
 280   /* Per-type %printer.  */ 
 283       code_props 
const *printer 
= &semantic_type_get (sym
->type_name
)->printer
; 
 288   /* Apply the default %printer only to user-defined symbols.  */ 
 289   if (sym
->tag
[0] == '$' || sym 
== errtoken
) 
 290     return &code_props_none
; 
 293     return &default_tagged_printer
; 
 294   return &default_tagless_printer
; 
 297 /*-----------------------------------------------------------------. 
 298 | Set the PRECEDENCE associated with SYM.  Does nothing if invoked | 
 299 | with UNDEF_ASSOC as ASSOC.                                       | 
 300 `-----------------------------------------------------------------*/ 
 303 symbol_precedence_set (symbol 
*sym
, int prec
, assoc a
, location loc
) 
 305   if (a 
!= undef_assoc
) 
 308         symbol_redeclaration (sym
, assoc_to_string (a
), sym
->prec_location
, 
 312       sym
->prec_location 
= loc
; 
 315   /* Only terminals have a precedence. */ 
 316   symbol_class_set (sym
, token_sym
, loc
, false); 
 320 /*------------------------------------. 
 321 | Set the CLASS associated with SYM.  | 
 322 `------------------------------------*/ 
 325 symbol_class_set (symbol 
*sym
, symbol_class 
class, location loc
, bool declaring
) 
 327   if (sym
->class != unknown_sym 
&& sym
->class != class) 
 329       complain_at (loc
, _("symbol %s redefined"), sym
->tag
); 
 330       sym
->declared 
= false; 
 333   if (class == nterm_sym 
&& sym
->class != nterm_sym
) 
 334     sym
->number 
= nvars
++; 
 335   else if (class == token_sym 
&& sym
->number 
== NUMBER_UNDEFINED
) 
 336     sym
->number 
= ntokens
++; 
 343         warn_at (loc
, _("symbol %s redeclared"), sym
->tag
); 
 344       sym
->declared 
= true; 
 349 /*------------------------------------------------. 
 350 | Set the USER_TOKEN_NUMBER associated with SYM.  | 
 351 `------------------------------------------------*/ 
 354 symbol_user_token_number_set (symbol 
*sym
, int user_token_number
, location loc
) 
 356   int *user_token_numberp
; 
 358   if (sym
->user_token_number 
!= USER_NUMBER_HAS_STRING_ALIAS
) 
 359     user_token_numberp 
= &sym
->user_token_number
; 
 361     user_token_numberp 
= &sym
->alias
->user_token_number
; 
 362   if (*user_token_numberp 
!= USER_NUMBER_UNDEFINED
 
 363       && *user_token_numberp 
!= user_token_number
) 
 364     complain_at (loc
, _("redefining user token number of %s"), sym
->tag
); 
 366   *user_token_numberp 
= user_token_number
; 
 367   /* User defined $end token? */ 
 368   if (user_token_number 
== 0) 
 371       /* It is always mapped to 0, so it was already counted in 
 373       if (endtoken
->number 
!= NUMBER_UNDEFINED
) 
 375       endtoken
->number 
= 0; 
 380 /*----------------------------------------------------------. 
 381 | If SYM is not defined, report an error, and consider it a | 
 383 `----------------------------------------------------------*/ 
 386 symbol_check_defined (symbol 
*sym
) 
 388   if (sym
->class == unknown_sym
) 
 392          _("symbol %s is used, but is not defined as a token and has no rules"), 
 394       sym
->class = nterm_sym
; 
 395       sym
->number 
= nvars
++; 
 402 symbol_check_defined_processor (void *sym
, void *null ATTRIBUTE_UNUSED
) 
 404   return symbol_check_defined (sym
); 
 409 symbol_make_alias (symbol 
*sym
, symbol 
*str
, location loc
) 
 412     warn_at (loc
, _("symbol `%s' used more than once as a literal string"), 
 415     warn_at (loc
, _("symbol `%s' given more than one literal string"), 
 419       str
->class = token_sym
; 
 420       str
->user_token_number 
= sym
->user_token_number
; 
 421       sym
->user_token_number 
= USER_NUMBER_HAS_STRING_ALIAS
; 
 424       str
->number 
= sym
->number
; 
 425       symbol_type_set (str
, sym
->type_name
, loc
); 
 430 /*---------------------------------------------------------. 
 431 | Check that THIS, and its alias, have same precedence and | 
 433 `---------------------------------------------------------*/ 
 436 symbol_check_alias_consistency (symbol 
*this) 
 439   symbol 
*str 
= this->alias
; 
 441   /* Check only the symbol in the symbol-string pair.  */ 
 443         && this->user_token_number 
== USER_NUMBER_HAS_STRING_ALIAS
)) 
 446   if (str
->type_name 
!= sym
->type_name
) 
 449         symbol_type_set (sym
, str
->type_name
, str
->type_location
); 
 451         symbol_type_set (str
, sym
->type_name
, sym
->type_location
); 
 455   if (str
->destructor
.code 
|| sym
->destructor
.code
) 
 457       if (str
->destructor
.code
) 
 458         symbol_destructor_set (sym
, &str
->destructor
); 
 460         symbol_destructor_set (str
, &sym
->destructor
); 
 463   if (str
->printer
.code 
|| sym
->printer
.code
) 
 465       if (str
->printer
.code
) 
 466         symbol_printer_set (sym
, &str
->printer
); 
 468         symbol_printer_set (str
, &sym
->printer
); 
 471   if (sym
->prec 
|| str
->prec
) 
 474         symbol_precedence_set (sym
, str
->prec
, str
->assoc
, 
 477         symbol_precedence_set (str
, sym
->prec
, sym
->assoc
, 
 483 symbol_check_alias_consistency_processor (void *this, 
 484                                           void *null ATTRIBUTE_UNUSED
) 
 486   symbol_check_alias_consistency (this); 
 491 /*-------------------------------------------------------------------. 
 492 | Assign a symbol number, and write the definition of the token name | 
 493 | into FDEFINES.  Put in SYMBOLS.                                    | 
 494 `-------------------------------------------------------------------*/ 
 497 symbol_pack (symbol 
*this) 
 499   aver (this->number 
!= NUMBER_UNDEFINED
); 
 500   if (this->class == nterm_sym
) 
 501     this->number 
+= ntokens
; 
 502   else if (this->user_token_number 
== USER_NUMBER_HAS_STRING_ALIAS
) 
 505   symbols
[this->number
] = this; 
 510 symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 512   return symbol_pack (this); 
 517 user_token_number_redeclaration (int num
, symbol 
*first
, symbol 
*second
) 
 519   /* User token numbers are not assigned during the parsing, but in a 
 520      second step, via a traversal of the symbol table sorted on tag. 
 522      However, error messages make more sense if we keep the first 
 523      declaration first.  */ 
 524   if (location_cmp (first
->location
, second
->location
) > 0) 
 530   complain_at (second
->location
, 
 531                _("user token number %d redeclaration for %s"), 
 533   complain_at (first
->location
, _("previous declaration for %s"), 
 537 /*--------------------------------------------------. 
 538 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  | 
 539 `--------------------------------------------------*/ 
 542 symbol_translation (symbol 
*this) 
 545   if (this->class == token_sym
 
 546       && this->user_token_number 
!= USER_NUMBER_HAS_STRING_ALIAS
) 
 548       /* A token which translation has already been set? */ 
 549       if (token_translations
[this->user_token_number
] != undeftoken
->number
) 
 550         user_token_number_redeclaration
 
 551           (this->user_token_number
, 
 552            symbols
[token_translations
[this->user_token_number
]], 
 555       token_translations
[this->user_token_number
] = this->number
; 
 562 symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 564   return symbol_translation (this); 
 568 /*---------------------------------------. 
 569 | Symbol and semantic type hash tables.  | 
 570 `---------------------------------------*/ 
 572 /* Initial capacity of symbol and semantic type hash table.  */ 
 573 #define HT_INITIAL_CAPACITY 257 
 575 static struct hash_table 
*symbol_table 
= NULL
; 
 576 static struct hash_table 
*semantic_type_table 
= NULL
; 
 579 hash_compare_symbol (const symbol 
*m1
, const symbol 
*m2
) 
 581   /* Since tags are unique, we can compare the pointers themselves.  */ 
 582   return UNIQSTR_EQ (m1
->tag
, m2
->tag
); 
 586 hash_compare_semantic_type (const semantic_type 
*m1
, const semantic_type 
*m2
) 
 588   /* Since names are unique, we can compare the pointers themselves.  */ 
 589   return UNIQSTR_EQ (m1
->tag
, m2
->tag
); 
 593 hash_symbol_comparator (void const *m1
, void const *m2
) 
 595   return hash_compare_symbol (m1
, m2
); 
 599 hash_semantic_type_comparator (void const *m1
, void const *m2
) 
 601   return hash_compare_semantic_type (m1
, m2
); 
 605 hash_symbol (const symbol 
*m
, size_t tablesize
) 
 607   /* Since tags are unique, we can hash the pointer itself.  */ 
 608   return ((uintptr_t) m
->tag
) % tablesize
; 
 612 hash_semantic_type (const semantic_type 
*m
, size_t tablesize
) 
 614   /* Since names are unique, we can hash the pointer itself.  */ 
 615   return ((uintptr_t) m
->tag
) % tablesize
; 
 619 hash_symbol_hasher (void const *m
, size_t tablesize
) 
 621   return hash_symbol (m
, tablesize
); 
 625 hash_semantic_type_hasher (void const *m
, size_t tablesize
) 
 627   return hash_semantic_type (m
, tablesize
); 
 630 /*-------------------------------. 
 631 | Create the symbol hash table.  | 
 632 `-------------------------------*/ 
 637   symbol_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 640                                   hash_symbol_comparator
, 
 642   semantic_type_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 644                                          hash_semantic_type_hasher
, 
 645                                          hash_semantic_type_comparator
, 
 650 /*----------------------------------------------------------------. 
 651 | Find the symbol named KEY, and return it.  If it does not exist | 
 653 `----------------------------------------------------------------*/ 
 656 symbol_from_uniqstr (const uniqstr key
, location loc
) 
 662   entry 
= hash_lookup (symbol_table
, &probe
); 
 666       /* First insertion in the hash. */ 
 667       aver (!symbols_sorted
); 
 668       entry 
= symbol_new (key
, loc
); 
 669       if (!hash_insert (symbol_table
, entry
)) 
 676 /*-----------------------------------------------------------------------. 
 677 | Find the semantic type named KEY, and return it.  If it does not exist | 
 679 `-----------------------------------------------------------------------*/ 
 682 semantic_type_from_uniqstr (const uniqstr key
) 
 685   semantic_type 
*entry
; 
 688   entry 
= hash_lookup (semantic_type_table
, &probe
); 
 692       /* First insertion in the hash. */ 
 693       entry 
= semantic_type_new (key
); 
 694       if (!hash_insert (semantic_type_table
, entry
)) 
 701 /*----------------------------------------------------------------. 
 702 | Find the symbol named KEY, and return it.  If it does not exist | 
 704 `----------------------------------------------------------------*/ 
 707 symbol_get (const char *key
, location loc
) 
 709   return symbol_from_uniqstr (uniqstr_new (key
), loc
); 
 713 /*-----------------------------------------------------------------------. 
 714 | Find the semantic type named KEY, and return it.  If it does not exist | 
 716 `-----------------------------------------------------------------------*/ 
 719 semantic_type_get (const char *key
) 
 721   return semantic_type_from_uniqstr (uniqstr_new (key
)); 
 725 /*------------------------------------------------------------------. 
 726 | Generate a dummy nonterminal, whose name cannot conflict with the | 
 728 `------------------------------------------------------------------*/ 
 731 dummy_symbol_get (location loc
) 
 733   /* Incremented for each generated symbol.  */ 
 734   static int dummy_count 
= 0; 
 735   static char buf
[256]; 
 739   sprintf (buf
, "$@%d", ++dummy_count
); 
 740   sym 
= symbol_get (buf
, loc
); 
 741   sym
->class = nterm_sym
; 
 742   sym
->number 
= nvars
++; 
 747 symbol_is_dummy (const symbol 
*sym
) 
 749   return sym
->tag
[0] == '@' || (sym
->tag
[0] == '$' && sym
->tag
[1] == '@'); 
 752 /*-------------------. 
 753 | Free the symbols.  | 
 754 `-------------------*/ 
 759   hash_free (symbol_table
); 
 760   hash_free (semantic_type_table
); 
 762   free (symbols_sorted
); 
 766 /*---------------------------------------------------------------. 
 767 | Look for undefined symbols, report an error, and consider them | 
 769 `---------------------------------------------------------------*/ 
 772 symbols_cmp (symbol 
const *a
, symbol 
const *b
) 
 774   return strcmp (a
->tag
, b
->tag
); 
 778 symbols_cmp_qsort (void const *a
, void const *b
) 
 780   return symbols_cmp (*(symbol 
* const *)a
, *(symbol 
* const *)b
); 
 784 symbols_do (Hash_processor processor
, void *processor_data
) 
 786   size_t count 
= hash_get_n_entries (symbol_table
); 
 789       symbols_sorted 
= xnmalloc (count
, sizeof *symbols_sorted
); 
 790       hash_get_entries (symbol_table
, (void**)symbols_sorted
, count
); 
 791       qsort (symbols_sorted
, count
, sizeof *symbols_sorted
, 
 796     for (i 
= 0; i 
< count
; ++i
) 
 797       processor (symbols_sorted
[i
], processor_data
); 
 801 /*--------------------------------------------------------------. 
 802 | Check that all the symbols are defined.  Report any undefined | 
 803 | symbols and consider them nonterminals.                       | 
 804 `--------------------------------------------------------------*/ 
 807 symbols_check_defined (void) 
 809   symbols_do (symbol_check_defined_processor
, NULL
); 
 812 /*------------------------------------------------------------------. 
 813 | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same | 
 815 `------------------------------------------------------------------*/ 
 818 symbols_token_translations_init (void) 
 820   bool num_256_available_p 
= true; 
 823   /* Find the highest user token number, and whether 256, the POSIX 
 824      preferred user token number for the error token, is used.  */ 
 825   max_user_token_number 
= 0; 
 826   for (i 
= 0; i 
< ntokens
; ++i
) 
 828       symbol 
*this = symbols
[i
]; 
 829       if (this->user_token_number 
!= USER_NUMBER_UNDEFINED
) 
 831           if (this->user_token_number 
> max_user_token_number
) 
 832             max_user_token_number 
= this->user_token_number
; 
 833           if (this->user_token_number 
== 256) 
 834             num_256_available_p 
= false; 
 838   /* If 256 is not used, assign it to error, to follow POSIX.  */ 
 839   if (num_256_available_p
 
 840       && errtoken
->user_token_number 
== USER_NUMBER_UNDEFINED
) 
 841     errtoken
->user_token_number 
= 256; 
 843   /* Set the missing user numbers. */ 
 844   if (max_user_token_number 
< 256) 
 845     max_user_token_number 
= 256; 
 847   for (i 
= 0; i 
< ntokens
; ++i
) 
 849       symbol 
*this = symbols
[i
]; 
 850       if (this->user_token_number 
== USER_NUMBER_UNDEFINED
) 
 851         this->user_token_number 
= ++max_user_token_number
; 
 852       if (this->user_token_number 
> max_user_token_number
) 
 853         max_user_token_number 
= this->user_token_number
; 
 856   token_translations 
= xnmalloc (max_user_token_number 
+ 1, 
 857                                  sizeof *token_translations
); 
 859   /* Initialize all entries for literal tokens to 2, the internal 
 860      token number for $undefined, which represents all invalid inputs. 
 862   for (i 
= 0; i 
< max_user_token_number 
+ 1; i
++) 
 863     token_translations
[i
] = undeftoken
->number
; 
 864   symbols_do (symbol_translation_processor
, NULL
); 
 868 /*----------------------------------------------------------------. 
 869 | Assign symbol numbers, and write definition of token names into | 
 870 | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        | 
 871 `----------------------------------------------------------------*/ 
 876   symbols_do (symbol_check_alias_consistency_processor
, NULL
); 
 878   symbols 
= xcalloc (nsyms
, sizeof *symbols
); 
 879   symbols_do (symbol_pack_processor
, NULL
); 
 881   /* Aliases leave empty slots in symbols, so remove them.  */ 
 885     int nsyms_old 
= nsyms
; 
 886     for (writei 
= 0, readi 
= 0; readi 
< nsyms_old
; readi 
+= 1) 
 888         if (symbols
[readi
] == NULL
) 
 895             symbols
[writei
] = symbols
[readi
]; 
 896             symbols
[writei
]->number 
= writei
; 
 897             if (symbols
[writei
]->alias
) 
 898               symbols
[writei
]->alias
->number 
= writei
; 
 903   symbols 
= xnrealloc (symbols
, nsyms
, sizeof *symbols
); 
 905   symbols_token_translations_init (); 
 907   if (startsymbol
->class == unknown_sym
) 
 908     fatal_at (startsymbol_location
, 
 909               _("the start symbol %s is undefined"), 
 911   else if (startsymbol
->class == token_sym
) 
 912     fatal_at (startsymbol_location
, 
 913               _("the start symbol %s is a token"), 
 918 /*--------------------------------------------------. 
 919 | Set default tagged/tagless %destructor/%printer.  | 
 920 `--------------------------------------------------*/ 
 923 default_tagged_destructor_set (code_props 
const *destructor
) 
 925   if (default_tagged_destructor
.code
) 
 927       complain_at (destructor
->location
, 
 928                    _("redeclaration for default tagged %%destructor")); 
 929       complain_at (default_tagged_destructor
.location
, 
 930                    _("previous declaration")); 
 932   default_tagged_destructor 
= *destructor
; 
 936 default_tagless_destructor_set (code_props 
const *destructor
) 
 938   if (default_tagless_destructor
.code
) 
 940       complain_at (destructor
->location
, 
 941                    _("redeclaration for default tagless %%destructor")); 
 942       complain_at (default_tagless_destructor
.location
, 
 943                    _("previous declaration")); 
 945   default_tagless_destructor 
= *destructor
; 
 949 default_tagged_printer_set (code_props 
const *printer
) 
 951   if (default_tagged_printer
.code
) 
 953       complain_at (printer
->location
, 
 954                    _("redeclaration for default tagged %%printer")); 
 955       complain_at (default_tagged_printer
.location
, 
 956                    _("previous declaration")); 
 958   default_tagged_printer 
= *printer
; 
 962 default_tagless_printer_set (code_props 
const *printer
) 
 964   if (default_tagless_printer
.code
) 
 966       complain_at (printer
->location
, 
 967                    _("redeclaration for default tagless %%printer")); 
 968       complain_at (default_tagless_printer
.location
, 
 969                    _("previous declaration")); 
 971   default_tagless_printer 
= *printer
;