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