1 /* Symbol table manager for Bison. 
   3    Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 
   5    Free Software Foundation, Inc. 
   7    This file is part of Bison, the GNU Compiler Compiler. 
   9    This program is free software: you can redistribute it and/or modify 
  10    it under the terms of the GNU General Public License as published by 
  11    the Free Software Foundation, either version 3 of the License, or 
  12    (at your option) any later version. 
  14    This program is distributed in the hope that it will be useful, 
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  17    GNU General Public License for more details. 
  19    You should have received a copy of the GNU General Public License 
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ 
  32 /*------------------------. 
  33 | Distinguished symbols.  | 
  34 `------------------------*/ 
  36 symbol 
*errtoken 
= NULL
; 
  37 symbol 
*undeftoken 
= NULL
; 
  38 symbol 
*endtoken 
= NULL
; 
  39 symbol 
*accept 
= NULL
; 
  40 symbol 
*startsymbol 
= NULL
; 
  41 location startsymbol_location
; 
  43 /*---------------------------------------. 
  44 | Default %destructor's and %printer's.  | 
  45 `---------------------------------------*/ 
  47 static code_props default_tagged_destructor 
= CODE_PROPS_NONE_INIT
; 
  48 static code_props default_tagless_destructor 
= CODE_PROPS_NONE_INIT
; 
  49 static code_props default_tagged_printer 
= CODE_PROPS_NONE_INIT
; 
  50 static code_props default_tagless_printer 
= CODE_PROPS_NONE_INIT
; 
  52 /*---------------------------------. 
  53 | Create a new symbol, named TAG.  | 
  54 `---------------------------------*/ 
  57 symbol_new (uniqstr tag
, location loc
) 
  59   symbol 
*res 
= xmalloc (sizeof *res
); 
  63   /* If the tag is not a string (starts with a double quote), check 
  64      that it is valid for Yacc. */ 
  65   if (tag
[0] != '\"' && tag
[0] != '\'' && strchr (tag
, '-')) 
  66     yacc_at (loc
, _("POSIX Yacc forbids dashes in symbol names: %s"), 
  72   res
->type_name 
= NULL
; 
  73   code_props_none_init (&res
->destructor
); 
  74   code_props_none_init (&res
->printer
); 
  76   res
->number 
= NUMBER_UNDEFINED
; 
  78   res
->assoc 
= undef_assoc
; 
  79   res
->user_token_number 
= USER_NUMBER_UNDEFINED
; 
  82   res
->class = unknown_sym
; 
  83   res
->declared 
= false; 
  85   if (nsyms 
== SYMBOL_NUMBER_MAXIMUM
) 
  86     fatal (_("too many symbols in input grammar (limit is %d)"), 
  87            SYMBOL_NUMBER_MAXIMUM
); 
  92 /*----------------------------------------. 
  93 | Create a new semantic type, named TAG.  | 
  94 `----------------------------------------*/ 
  96 static semantic_type 
* 
  97 semantic_type_new (uniqstr tag
) 
  99   semantic_type 
*res 
= xmalloc (sizeof *res
); 
 101   uniqstr_assert (tag
); 
 103   code_props_none_init (&res
->destructor
); 
 104   code_props_none_init (&res
->printer
); 
 114 #define SYMBOL_ATTR_PRINT(Attr)                         \ 
 116     fprintf (f, " %s { %s }", #Attr, s->Attr) 
 118 #define SYMBOL_CODE_PRINT(Attr)                         \ 
 120     fprintf (f, " %s { %s }", #Attr, s->Attr.code) 
 123 symbol_print (symbol 
*s
, FILE *f
) 
 127       fprintf (f
, "\"%s\"", s
->tag
); 
 128       SYMBOL_ATTR_PRINT (type_name
); 
 129       SYMBOL_CODE_PRINT (destructor
); 
 130       SYMBOL_CODE_PRINT (printer
); 
 133     fprintf (f
, "<NULL>"); 
 136 #undef SYMBOL_ATTR_PRINT 
 137 #undef SYMBOL_CODE_PRINT 
 139 /*------------------------------------------------------------------. 
 140 | Complain that S's WHAT is redeclared at SECOND, and was first set | 
 142 `------------------------------------------------------------------*/ 
 145 symbol_redeclaration (symbol 
*s
, const char *what
, location first
, 
 148   complain_at (second
, _("%s redeclaration for %s"), what
, s
->tag
); 
 149   complain_at (first
, _("previous declaration")); 
 153 semantic_type_redeclaration (semantic_type 
*s
, const char *what
, location first
, 
 156   complain_at (second
, _("%s redeclaration for <%s>"), what
, s
->tag
); 
 157   complain_at (first
, _("previous declaration")); 
 162 /*-----------------------------------------------------------------. 
 163 | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 | 
 165 `-----------------------------------------------------------------*/ 
 168 symbol_type_set (symbol 
*sym
, uniqstr type_name
, location loc
) 
 173         symbol_redeclaration (sym
, "%type", sym
->type_location
, loc
); 
 174       uniqstr_assert (type_name
); 
 175       sym
->type_name 
= type_name
; 
 176       sym
->type_location 
= loc
; 
 180 /*-----------------------------------. 
 181 | Get the CLASS associated with SYM. | 
 182 `-----------------------------------*/ 
 185 symbol_class_get_string (symbol 
*sym
) 
 189       if (sym
->class == token_sym
) 
 191       else if (sym
->class == nterm_sym
) 
 192         return "nonterminal"; 
 198 /*-----------------------------------------. 
 199 | Set the DESTRUCTOR associated with SYM.  | 
 200 `-----------------------------------------*/ 
 203 symbol_destructor_set (symbol 
*sym
, code_props 
const *destructor
) 
 205   if (sym
->destructor
.code
) 
 206     symbol_redeclaration (sym
, "%destructor", sym
->destructor
.location
, 
 207                           destructor
->location
); 
 208   sym
->destructor 
= *destructor
; 
 211 /*------------------------------------------. 
 212 | Set the DESTRUCTOR associated with TYPE.  | 
 213 `------------------------------------------*/ 
 216 semantic_type_destructor_set (semantic_type 
*type
, 
 217                               code_props 
const *destructor
) 
 219   if (type
->destructor
.code
) 
 220     semantic_type_redeclaration (type
, "%destructor", 
 221                                  type
->destructor
.location
, 
 222                                  destructor
->location
); 
 223   type
->destructor 
= *destructor
; 
 226 /*---------------------------------------. 
 227 | Get the computed %destructor for SYM.  | 
 228 `---------------------------------------*/ 
 231 symbol_destructor_get (symbol 
const *sym
) 
 233   /* Per-symbol %destructor.  */ 
 234   if (sym
->destructor
.code
) 
 235     return &sym
->destructor
; 
 237   /* Per-type %destructor.  */ 
 240       code_props 
const *destructor 
= 
 241         &semantic_type_get (sym
->type_name
)->destructor
; 
 242       if (destructor
->code
) 
 246   /* Apply default %destructor's only to user-defined symbols.  */ 
 247   if (sym
->tag
[0] == '$' || sym 
== errtoken
) 
 248     return &code_props_none
; 
 251     return &default_tagged_destructor
; 
 252   return &default_tagless_destructor
; 
 255 /*--------------------------------------. 
 256 | Set the PRINTER associated with SYM.  | 
 257 `--------------------------------------*/ 
 260 symbol_printer_set (symbol 
*sym
, code_props 
const *printer
) 
 262   if (sym
->printer
.code
) 
 263     symbol_redeclaration (sym
, "%printer", 
 264                           sym
->printer
.location
, printer
->location
); 
 265   sym
->printer 
= *printer
; 
 268 /*---------------------------------------. 
 269 | Set the PRINTER associated with TYPE.  | 
 270 `---------------------------------------*/ 
 273 semantic_type_printer_set (semantic_type 
*type
, code_props 
const *printer
) 
 275   if (type
->printer
.code
) 
 276     semantic_type_redeclaration (type
, "%printer", 
 277                                  type
->printer
.location
, printer
->location
); 
 278   type
->printer 
= *printer
; 
 281 /*------------------------------------. 
 282 | Get the computed %printer for SYM.  | 
 283 `------------------------------------*/ 
 286 symbol_printer_get (symbol 
const *sym
) 
 288   /* Per-symbol %printer.  */ 
 289   if (sym
->printer
.code
) 
 290     return &sym
->printer
; 
 292   /* Per-type %printer.  */ 
 295       code_props 
const *printer 
= &semantic_type_get (sym
->type_name
)->printer
; 
 300   /* Apply the default %printer only to user-defined symbols.  */ 
 301   if (sym
->tag
[0] == '$' || sym 
== errtoken
) 
 302     return &code_props_none
; 
 305     return &default_tagged_printer
; 
 306   return &default_tagless_printer
; 
 309 /*-----------------------------------------------------------------. 
 310 | Set the PRECEDENCE associated with SYM.  Does nothing if invoked | 
 311 | with UNDEF_ASSOC as ASSOC.                                       | 
 312 `-----------------------------------------------------------------*/ 
 315 symbol_precedence_set (symbol 
*sym
, int prec
, assoc a
, location loc
) 
 317   if (a 
!= undef_assoc
) 
 320         symbol_redeclaration (sym
, assoc_to_string (a
), sym
->prec_location
, 
 324       sym
->prec_location 
= loc
; 
 327   /* Only terminals have a precedence. */ 
 328   symbol_class_set (sym
, token_sym
, loc
, false); 
 332 /*------------------------------------. 
 333 | Set the CLASS associated with SYM.  | 
 334 `------------------------------------*/ 
 337 symbol_class_set (symbol 
*sym
, symbol_class 
class, location loc
, bool declaring
) 
 339   if (sym
->class != unknown_sym 
&& sym
->class != class) 
 341       complain_at (loc
, _("symbol %s redefined"), sym
->tag
); 
 342       sym
->declared 
= false; 
 345   if (class == nterm_sym 
&& sym
->class != nterm_sym
) 
 346     sym
->number 
= nvars
++; 
 347   else if (class == token_sym 
&& sym
->number 
== NUMBER_UNDEFINED
) 
 348     sym
->number 
= ntokens
++; 
 355         warn_at (loc
, _("symbol %s redeclared"), sym
->tag
); 
 356       sym
->declared 
= true; 
 361 /*------------------------------------------------. 
 362 | Set the USER_TOKEN_NUMBER associated with SYM.  | 
 363 `------------------------------------------------*/ 
 366 symbol_user_token_number_set (symbol 
*sym
, int user_token_number
, location loc
) 
 368   int *user_token_numberp
; 
 370   if (sym
->user_token_number 
!= USER_NUMBER_HAS_STRING_ALIAS
) 
 371     user_token_numberp 
= &sym
->user_token_number
; 
 373     user_token_numberp 
= &sym
->alias
->user_token_number
; 
 374   if (*user_token_numberp 
!= USER_NUMBER_UNDEFINED
 
 375       && *user_token_numberp 
!= user_token_number
) 
 376     complain_at (loc
, _("redefining user token number of %s"), sym
->tag
); 
 378   *user_token_numberp 
= user_token_number
; 
 379   /* User defined $end token? */ 
 380   if (user_token_number 
== 0) 
 383       endtoken
->number 
= 0; 
 384       /* It is always mapped to 0, so it was already counted in 
 391 /*----------------------------------------------------------. 
 392 | If SYM is not defined, report an error, and consider it a | 
 394 `----------------------------------------------------------*/ 
 397 symbol_check_defined (symbol 
*sym
) 
 399   if (sym
->class == unknown_sym
) 
 403          _("symbol %s is used, but is not defined as a token and has no rules"), 
 405       sym
->class = nterm_sym
; 
 406       sym
->number 
= nvars
++; 
 413 symbol_check_defined_processor (void *sym
, void *null ATTRIBUTE_UNUSED
) 
 415   return symbol_check_defined (sym
); 
 420 symbol_make_alias (symbol 
*sym
, symbol 
*str
, location loc
) 
 423     warn_at (loc
, _("symbol `%s' used more than once as a literal string"), 
 426     warn_at (loc
, _("symbol `%s' given more than one literal string"), 
 430       str
->class = token_sym
; 
 431       str
->user_token_number 
= sym
->user_token_number
; 
 432       sym
->user_token_number 
= USER_NUMBER_HAS_STRING_ALIAS
; 
 435       str
->number 
= sym
->number
; 
 436       symbol_type_set (str
, sym
->type_name
, loc
); 
 441 /*---------------------------------------------------------. 
 442 | Check that THIS, and its alias, have same precedence and | 
 444 `---------------------------------------------------------*/ 
 447 symbol_check_alias_consistency (symbol 
*this) 
 450   symbol 
*str  
= this->alias
; 
 452   /* Check only the symbol in the symbol-string pair.  */ 
 454         && this->user_token_number 
== USER_NUMBER_HAS_STRING_ALIAS
)) 
 457   if (str
->type_name 
!= sym
->type_name
) 
 460         symbol_type_set (sym
, str
->type_name
, str
->type_location
); 
 462         symbol_type_set (str
, sym
->type_name
, sym
->type_location
); 
 466   if (str
->destructor
.code 
|| sym
->destructor
.code
) 
 468       if (str
->destructor
.code
) 
 469         symbol_destructor_set (sym
, &str
->destructor
); 
 471         symbol_destructor_set (str
, &sym
->destructor
); 
 474   if (str
->printer
.code 
|| sym
->printer
.code
) 
 476       if (str
->printer
.code
) 
 477         symbol_printer_set (sym
, &str
->printer
); 
 479         symbol_printer_set (str
, &sym
->printer
); 
 482   if (sym
->prec 
|| str
->prec
) 
 485         symbol_precedence_set (sym
, str
->prec
, str
->assoc
, 
 488         symbol_precedence_set (str
, sym
->prec
, sym
->assoc
, 
 494 symbol_check_alias_consistency_processor (void *this, 
 495                                           void *null ATTRIBUTE_UNUSED
) 
 497   symbol_check_alias_consistency (this); 
 502 /*-------------------------------------------------------------------. 
 503 | Assign a symbol number, and write the definition of the token name | 
 504 | into FDEFINES.  Put in SYMBOLS.                                    | 
 505 `-------------------------------------------------------------------*/ 
 508 symbol_pack (symbol 
*this) 
 510   if (this->class == nterm_sym
) 
 512       this->number 
+= ntokens
; 
 514   else if (this->alias
) 
 516       /* This symbol and its alias are a single token defn. 
 517          Allocate a tokno, and assign to both check agreement of 
 518          prec and assoc fields and make both the same */ 
 519       if (this->number 
== NUMBER_UNDEFINED
) 
 521           if (this == endtoken 
|| this->alias 
== endtoken
) 
 522             this->number 
= this->alias
->number 
= 0; 
 525               aver (this->alias
->number 
!= NUMBER_UNDEFINED
); 
 526               this->number 
= this->alias
->number
; 
 529       /* Do not do processing below for USER_NUMBER_HAS_STRING_ALIASes.  */ 
 530       if (this->user_token_number 
== USER_NUMBER_HAS_STRING_ALIAS
) 
 533   else /* this->class == token_sym */ 
 534     aver (this->number 
!= NUMBER_UNDEFINED
); 
 536   symbols
[this->number
] = this; 
 541 symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 543   return symbol_pack (this); 
 548 user_token_number_redeclaration (int num
, symbol 
*first
, symbol 
*second
) 
 550   /* User token numbers are not assigned during the parsing, but in a 
 551      second step, via a (nondeterministic) traversal of the symbol 
 554      Make errors deterministic: keep the first declaration first.  */ 
 555   if (location_cmp (first
->location
, second
->location
) > 0) 
 561   complain_at (second
->location
, 
 562                _("user token number %d redeclaration for %s"), 
 564   complain_at (first
->location
, _("previous declaration for %s"), 
 568 /*--------------------------------------------------. 
 569 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  | 
 570 `--------------------------------------------------*/ 
 573 symbol_translation (symbol 
*this) 
 576   if (this->class == token_sym
 
 577       && this->user_token_number 
!= USER_NUMBER_HAS_STRING_ALIAS
) 
 579       /* A token which translation has already been set? */ 
 580       if (token_translations
[this->user_token_number
] != undeftoken
->number
) 
 581         user_token_number_redeclaration
 
 582           (this->user_token_number
, 
 583            symbols
[token_translations
[this->user_token_number
]], 
 586       token_translations
[this->user_token_number
] = this->number
; 
 593 symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED
) 
 595   return symbol_translation (this); 
 599 /*---------------------------------------. 
 600 | Symbol and semantic type hash tables.  | 
 601 `---------------------------------------*/ 
 603 /* Initial capacity of symbol and semantic type hash table.  */ 
 604 #define HT_INITIAL_CAPACITY 257 
 606 static struct hash_table 
*symbol_table 
= NULL
; 
 607 static struct hash_table 
*semantic_type_table 
= NULL
; 
 610 hash_compare_symbol (const symbol 
*m1
, const symbol 
*m2
) 
 612   /* Since tags are unique, we can compare the pointers themselves.  */ 
 613   return UNIQSTR_EQ (m1
->tag
, m2
->tag
); 
 617 hash_compare_semantic_type (const semantic_type 
*m1
, const semantic_type 
*m2
) 
 619   /* Since names are unique, we can compare the pointers themselves.  */ 
 620   return UNIQSTR_EQ (m1
->tag
, m2
->tag
); 
 624 hash_symbol_comparator (void const *m1
, void const *m2
) 
 626   return hash_compare_symbol (m1
, m2
); 
 630 hash_semantic_type_comparator (void const *m1
, void const *m2
) 
 632   return hash_compare_semantic_type (m1
, m2
); 
 636 hash_symbol (const symbol 
*m
, size_t tablesize
) 
 638   /* Since tags are unique, we can hash the pointer itself.  */ 
 639   return ((uintptr_t) m
->tag
) % tablesize
; 
 643 hash_semantic_type (const semantic_type 
*m
, size_t tablesize
) 
 645   /* Since names are unique, we can hash the pointer itself.  */ 
 646   return ((uintptr_t) m
->tag
) % tablesize
; 
 650 hash_symbol_hasher (void const *m
, size_t tablesize
) 
 652   return hash_symbol (m
, tablesize
); 
 656 hash_semantic_type_hasher (void const *m
, size_t tablesize
) 
 658   return hash_semantic_type (m
, tablesize
); 
 661 /*-------------------------------. 
 662 | Create the symbol hash table.  | 
 663 `-------------------------------*/ 
 668   symbol_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 671                                   hash_symbol_comparator
, 
 673   semantic_type_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 675                                          hash_semantic_type_hasher
, 
 676                                          hash_semantic_type_comparator
, 
 681 /*----------------------------------------------------------------. 
 682 | Find the symbol named KEY, and return it.  If it does not exist | 
 684 `----------------------------------------------------------------*/ 
 687 symbol_from_uniqstr (const uniqstr key
, location loc
) 
 693   entry 
= hash_lookup (symbol_table
, &probe
); 
 697       /* First insertion in the hash. */ 
 698       entry 
= symbol_new (key
, loc
); 
 699       if (!hash_insert (symbol_table
, entry
)) 
 706 /*-----------------------------------------------------------------------. 
 707 | Find the semantic type named KEY, and return it.  If it does not exist | 
 709 `-----------------------------------------------------------------------*/ 
 712 semantic_type_from_uniqstr (const uniqstr key
) 
 715   semantic_type 
*entry
; 
 718   entry 
= hash_lookup (semantic_type_table
, &probe
); 
 722       /* First insertion in the hash. */ 
 723       entry 
= semantic_type_new (key
); 
 724       if (!hash_insert (semantic_type_table
, entry
)) 
 731 /*----------------------------------------------------------------. 
 732 | Find the symbol named KEY, and return it.  If it does not exist | 
 734 `----------------------------------------------------------------*/ 
 737 symbol_get (const char *key
, location loc
) 
 739   return symbol_from_uniqstr (uniqstr_new (key
), loc
); 
 743 /*-----------------------------------------------------------------------. 
 744 | Find the semantic type named KEY, and return it.  If it does not exist | 
 746 `-----------------------------------------------------------------------*/ 
 749 semantic_type_get (const char *key
) 
 751   return semantic_type_from_uniqstr (uniqstr_new (key
)); 
 755 /*------------------------------------------------------------------. 
 756 | Generate a dummy nonterminal, whose name cannot conflict with the | 
 758 `------------------------------------------------------------------*/ 
 761 dummy_symbol_get (location loc
) 
 763   /* Incremented for each generated symbol.  */ 
 764   static int dummy_count 
= 0; 
 765   static char buf
[256]; 
 769   sprintf (buf
, "$@%d", ++dummy_count
); 
 770   sym 
= symbol_get (buf
, loc
); 
 771   sym
->class = nterm_sym
; 
 772   sym
->number 
= nvars
++; 
 777 symbol_is_dummy (const symbol 
*sym
) 
 779   return sym
->tag
[0] == '@' || (sym
->tag
[0] == '$' && sym
->tag
[1] == '@'); 
 782 /*-------------------. 
 783 | Free the symbols.  | 
 784 `-------------------*/ 
 789   hash_free (symbol_table
); 
 790   hash_free (semantic_type_table
); 
 795 /*---------------------------------------------------------------. 
 796 | Look for undefined symbols, report an error, and consider them | 
 798 `---------------------------------------------------------------*/ 
 801 symbols_do (Hash_processor processor
, void *processor_data
) 
 803   hash_do_for_each (symbol_table
, processor
, processor_data
); 
 807 /*--------------------------------------------------------------. 
 808 | Check that all the symbols are defined.  Report any undefined | 
 809 | symbols and consider them nonterminals.                       | 
 810 `--------------------------------------------------------------*/ 
 813 symbols_check_defined (void) 
 815   symbols_do (symbol_check_defined_processor
, NULL
); 
 818 /*------------------------------------------------------------------. 
 819 | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same | 
 821 `------------------------------------------------------------------*/ 
 824 symbols_token_translations_init (void) 
 826   bool num_256_available_p 
= true; 
 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
) 
 834       symbol 
*this = symbols
[i
]; 
 835       if (this->user_token_number 
!= USER_NUMBER_UNDEFINED
) 
 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; 
 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; 
 849   /* Set the missing user numbers. */ 
 850   if (max_user_token_number 
< 256) 
 851     max_user_token_number 
= 256; 
 853   for (i 
= 0; i 
< ntokens
; ++i
) 
 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
; 
 862   token_translations 
= xnmalloc (max_user_token_number 
+ 1, 
 863                                  sizeof *token_translations
); 
 865   /* Initialize all entries for literal tokens to 2, the internal 
 866      token number for $undefined, which represents all invalid inputs. 
 868   for (i 
= 0; i 
< max_user_token_number 
+ 1; i
++) 
 869     token_translations
[i
] = undeftoken
->number
; 
 870   symbols_do (symbol_translation_processor
, NULL
); 
 874 /*----------------------------------------------------------------. 
 875 | Assign symbol numbers, and write definition of token names into | 
 876 | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        | 
 877 `----------------------------------------------------------------*/ 
 882   symbols_do (symbol_check_alias_consistency_processor
, NULL
); 
 884   symbols 
= xcalloc (nsyms
, sizeof *symbols
); 
 885   symbols_do (symbol_pack_processor
, NULL
); 
 887   /* Aliases leave empty slots in symbols, so remove them.  */ 
 891     int nsyms_old 
= nsyms
; 
 892     for (writei 
= 0, readi 
= 0; readi 
< nsyms_old
; readi 
+= 1) 
 894         if (symbols
[readi
] == NULL
) 
 901             symbols
[writei
] = symbols
[readi
]; 
 902             symbols
[writei
]->number 
= writei
; 
 903             if (symbols
[writei
]->alias
) 
 904               symbols
[writei
]->alias
->number 
= writei
; 
 909   symbols 
= xnrealloc (symbols
, nsyms
, sizeof *symbols
); 
 911   symbols_token_translations_init (); 
 913   if (startsymbol
->class == unknown_sym
) 
 914     fatal_at (startsymbol_location
, 
 915               _("the start symbol %s is undefined"), 
 917   else if (startsymbol
->class == token_sym
) 
 918     fatal_at (startsymbol_location
, 
 919               _("the start symbol %s is a token"), 
 924 /*--------------------------------------------------. 
 925 | Set default tagged/tagless %destructor/%printer.  | 
 926 `--------------------------------------------------*/ 
 929 default_tagged_destructor_set (code_props 
const *destructor
) 
 931   if (default_tagged_destructor
.code
) 
 933       complain_at (destructor
->location
, 
 934                    _("redeclaration for default tagged %%destructor")); 
 935       complain_at (default_tagged_destructor
.location
, 
 936                    _("previous declaration")); 
 938   default_tagged_destructor 
= *destructor
; 
 942 default_tagless_destructor_set (code_props 
const *destructor
) 
 944   if (default_tagless_destructor
.code
) 
 946       complain_at (destructor
->location
, 
 947                    _("redeclaration for default tagless %%destructor")); 
 948       complain_at (default_tagless_destructor
.location
, 
 949                    _("previous declaration")); 
 951   default_tagless_destructor 
= *destructor
; 
 955 default_tagged_printer_set (code_props 
const *printer
) 
 957   if (default_tagged_printer
.code
) 
 959       complain_at (printer
->location
, 
 960                    _("redeclaration for default tagged %%printer")); 
 961       complain_at (default_tagged_printer
.location
, 
 962                    _("previous declaration")); 
 964   default_tagged_printer 
= *printer
; 
 968 default_tagless_printer_set (code_props 
const *printer
) 
 970   if (default_tagless_printer
.code
) 
 972       complain_at (printer
->location
, 
 973                    _("redeclaration for default tagless %%printer")); 
 974       complain_at (default_tagless_printer
.location
, 
 975                    _("previous declaration")); 
 977   default_tagless_printer 
= *printer
;