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