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 35static symbol **symbols_sorted = NULL; 36 37/*------------------------. 38| Distinguished symbols. | 39`------------------------*/ 40 41symbol *errtoken = NULL; 42symbol *undeftoken = NULL; 43symbol *endtoken = NULL; 44symbol *accept = NULL; 45symbol *startsymbol = NULL; 46location startsymbol_location; 47 48/*---------------------------------------. 49| Default %destructor's and %printer's. | 50`---------------------------------------*/ 51 52static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT; 53static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT; 54static code_props default_tagged_printer = CODE_PROPS_NONE_INIT; 55static code_props default_tagless_printer = CODE_PROPS_NONE_INIT; 56 57/*---------------------------------. 58| Create a new symbol, named TAG. | 59`---------------------------------*/ 60 61static symbol * 62symbol_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 101static semantic_type * 102semantic_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 127void 128symbol_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 149static void 150symbol_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 159static void 160semantic_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 176void 177symbol_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 193void 194symbol_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 206void 207semantic_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 221code_props const * 222symbol_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 250void 251symbol_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 263void 264semantic_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 276code_props const * 277symbol_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 305void 306symbol_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 327void 328symbol_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 356void 357symbol_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 388static inline bool 389symbol_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 404static bool 405symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED) 406{ 407 return symbol_check_defined (sym); 408} 409 410 411void 412symbol_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 438static inline void 439symbol_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 485static bool 486symbol_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 499static inline bool 500symbol_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 512static bool 513symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED) 514{ 515 return symbol_pack (this); 516} 517 518 519static void 520user_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 547static inline bool 548symbol_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 567static bool 568symbol_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 581static struct hash_table *symbol_table = NULL; 582static struct hash_table *semantic_type_table = NULL; 583 584static inline bool 585hash_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 591static inline bool 592hash_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 598static bool 599hash_symbol_comparator (void const *m1, void const *m2) 600{ 601 return hash_compare_symbol (m1, m2); 602} 603 604static bool 605hash_semantic_type_comparator (void const *m1, void const *m2) 606{ 607 return hash_compare_semantic_type (m1, m2); 608} 609 610static inline size_t 611hash_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 617static inline size_t 618hash_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 624static size_t 625hash_symbol_hasher (void const *m, size_t tablesize) 626{ 627 return hash_symbol (m, tablesize); 628} 629 630static size_t 631hash_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 640void 641symbols_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 661symbol * 662symbol_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 687semantic_type * 688semantic_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 712symbol * 713symbol_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 724semantic_type * 725semantic_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 736symbol * 737dummy_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 752bool 753symbol_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 762void 763symbols_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 777static int 778symbols_cmp (symbol const *a, symbol const *b) 779{ 780 return strcmp (a->tag, b->tag); 781} 782 783static int 784symbols_cmp_qsort (void const *a, void const *b) 785{ 786 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b); 787} 788 789static void 790symbols_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 812void 813symbols_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 823static void 824symbols_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 879void 880symbols_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 928void 929default_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 943void 944default_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 958void 959default_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 973void 974default_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