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