]> git.saurik.com Git - bison.git/blame_incremental - src/symtab.c
style: minor changes
[bison.git] / src / symtab.c
... / ...
CommitLineData
1/* Symbol table manager for Bison.
2
3 Copyright (C) 1984, 1989, 2000-2002, 2004-2013 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;
36static symbol **semantic_types_sorted = NULL;
37
38/*------------------------.
39| Distinguished symbols. |
40`------------------------*/
41
42symbol *errtoken = NULL;
43symbol *undeftoken = NULL;
44symbol *endtoken = NULL;
45symbol *accept = NULL;
46symbol *startsymbol = NULL;
47location startsymbol_location;
48
49/*---------------------------.
50| Precedence relation graph. |
51`---------------------------*/
52
53static symgraph **prec_nodes;
54
55/*-----------------------------------.
56| Store which associativity is used. |
57`-----------------------------------*/
58
59bool *used_assoc = NULL;
60
61/*---------------------------------.
62| Create a new symbol, named TAG. |
63`---------------------------------*/
64
65static symbol *
66symbol_new (uniqstr tag, location loc)
67{
68 symbol *res = xmalloc (sizeof *res);
69 uniqstr_assert (tag);
70
71 /* If the tag is not a string (starts with a double quote), check
72 that it is valid for Yacc. */
73 if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-'))
74 complain (&loc, Wyacc,
75 _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
76
77 res->tag = tag;
78 res->location = loc;
79
80 res->type_name = NULL;
81 {
82 int i;
83 for (i = 0; i < CODE_PROPS_SIZE; ++i)
84 code_props_none_init (&res->props[i]);
85 }
86
87 res->number = NUMBER_UNDEFINED;
88 res->prec = 0;
89 res->assoc = undef_assoc;
90 res->user_token_number = USER_NUMBER_UNDEFINED;
91
92 res->alias = NULL;
93 res->class = unknown_sym;
94 res->status = undeclared;
95
96 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
97 complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
98 SYMBOL_NUMBER_MAXIMUM);
99 nsyms++;
100 return res;
101}
102
103char const *
104code_props_type_string (code_props_type kind)
105{
106 switch (kind)
107 {
108 case destructor:
109 return "%destructor";
110 case printer:
111 return "%printer";
112 }
113 assert (0);
114}
115
116/*----------------------------------------.
117| Create a new semantic type, named TAG. |
118`----------------------------------------*/
119
120static semantic_type *
121semantic_type_new (uniqstr tag, const location *loc)
122{
123 semantic_type *res = xmalloc (sizeof *res);
124
125 uniqstr_assert (tag);
126 res->tag = tag;
127 res->location = loc ? *loc : empty_location;
128 res->status = undeclared;
129 {
130 int i;
131 for (i = 0; i < CODE_PROPS_SIZE; ++i)
132 code_props_none_init (&res->props[i]);
133 }
134
135 return res;
136}
137
138
139/*-----------------.
140| Print a symbol. |
141`-----------------*/
142
143#define SYMBOL_ATTR_PRINT(Attr) \
144 if (s->Attr) \
145 fprintf (f, " %s { %s }", #Attr, s->Attr)
146
147#define SYMBOL_CODE_PRINT(Attr) \
148 if (s->props[Attr].code) \
149 fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
150
151void
152symbol_print (symbol const *s, FILE *f)
153{
154 if (s)
155 {
156 fprintf (f, "\"%s\"", s->tag);
157 SYMBOL_ATTR_PRINT (type_name);
158 SYMBOL_CODE_PRINT (destructor);
159 SYMBOL_CODE_PRINT (printer);
160 }
161 else
162 fprintf (f, "<NULL>");
163}
164
165#undef SYMBOL_ATTR_PRINT
166#undef SYMBOL_CODE_PRINT
167
168
169/*----------------------------------.
170| Whether S is a valid identifier. |
171`----------------------------------*/
172
173static bool
174is_identifier (uniqstr s)
175{
176 static char const alphanum[26 + 26 + 1 + 10] =
177 "abcdefghijklmnopqrstuvwxyz"
178 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
179 "_"
180 "0123456789";
181 if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
182 return false;
183 for (++s; *s; ++s)
184 if (! memchr (alphanum, *s, sizeof alphanum))
185 return false;
186 return true;
187}
188
189
190/*-----------------------------------------------.
191| Get the identifier associated to this symbol. |
192`-----------------------------------------------*/
193uniqstr
194symbol_id_get (symbol const *sym)
195{
196 aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
197 if (sym->alias)
198 sym = sym->alias;
199 return is_identifier (sym->tag) ? sym->tag : 0;
200}
201
202
203/*------------------------------------------------------------------.
204| Complain that S's WHAT is redeclared at SECOND, and was first set |
205| at FIRST. |
206`------------------------------------------------------------------*/
207
208static void
209symbol_redeclaration (symbol *s, const char *what, location first,
210 location second)
211{
212 unsigned i = 0;
213 complain_indent (&second, complaint, &i,
214 _("%s redeclaration for %s"), what, s->tag);
215 i += SUB_INDENT;
216 complain_indent (&first, complaint, &i,
217 _("previous declaration"));
218}
219
220static void
221semantic_type_redeclaration (semantic_type *s, const char *what, location first,
222 location second)
223{
224 unsigned i = 0;
225 complain_indent (&second, complaint, &i,
226 _("%s redeclaration for <%s>"), what, s->tag);
227 i += SUB_INDENT;
228 complain_indent (&first, complaint, &i,
229 _("previous declaration"));
230}
231
232
233
234/*-----------------------------------------------------------------.
235| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
236| as TYPE_NAME. |
237`-----------------------------------------------------------------*/
238
239void
240symbol_type_set (symbol *sym, uniqstr type_name, location loc)
241{
242 if (type_name)
243 {
244 if (sym->type_name)
245 symbol_redeclaration (sym, "%type", sym->type_location, loc);
246 uniqstr_assert (type_name);
247 sym->type_name = type_name;
248 sym->type_location = loc;
249 }
250}
251
252/*--------------------------------------------------------.
253| Set the DESTRUCTOR or PRINTER associated with the SYM. |
254`--------------------------------------------------------*/
255
256void
257symbol_code_props_set (symbol *sym, code_props_type kind,
258 code_props const *code)
259{
260 if (sym->props[kind].code)
261 symbol_redeclaration (sym, code_props_type_string (kind),
262 sym->props[kind].location,
263 code->location);
264 sym->props[kind] = *code;
265}
266
267/*-----------------------------------------------------.
268| Set the DESTRUCTOR or PRINTER associated with TYPE. |
269`-----------------------------------------------------*/
270
271void
272semantic_type_code_props_set (semantic_type *type,
273 code_props_type kind,
274 code_props const *code)
275{
276 if (type->props[kind].code)
277 semantic_type_redeclaration (type, code_props_type_string (kind),
278 type->props[kind].location,
279 code->location);
280 type->props[kind] = *code;
281}
282
283/*---------------------------------------------------.
284| Get the computed %destructor or %printer for SYM. |
285`---------------------------------------------------*/
286
287code_props *
288symbol_code_props_get (symbol *sym, code_props_type kind)
289{
290 /* Per-symbol code props. */
291 if (sym->props[kind].code)
292 return &sym->props[kind];
293
294 /* Per-type code props. */
295 if (sym->type_name)
296 {
297 code_props *code =
298 &semantic_type_get (sym->type_name, NULL)->props[kind];
299 if (code->code)
300 return code;
301 }
302
303 /* Apply default code props's only to user-defined symbols. */
304 if (sym->tag[0] != '$' && sym != errtoken)
305 {
306 code_props *code =
307 &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
308 if (code->code)
309 return code;
310 }
311 return &code_props_none;
312}
313
314/*-----------------------------------------------------------------.
315| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
316| with UNDEF_ASSOC as ASSOC. |
317`-----------------------------------------------------------------*/
318
319void
320symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
321{
322 if (a != undef_assoc)
323 {
324 if (sym->prec != 0)
325 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
326 loc);
327 sym->prec = prec;
328 sym->assoc = a;
329 sym->prec_location = loc;
330 }
331
332 /* Only terminals have a precedence. */
333 symbol_class_set (sym, token_sym, loc, false);
334}
335
336
337/*------------------------------------.
338| Set the CLASS associated with SYM. |
339`------------------------------------*/
340
341void
342symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
343{
344 bool warned = false;
345 if (sym->class != unknown_sym && sym->class != class)
346 {
347 complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
348 /* Don't report both "redefined" and "redeclared". */
349 warned = true;
350 }
351
352 if (class == nterm_sym && sym->class != nterm_sym)
353 sym->number = nvars++;
354 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
355 sym->number = ntokens++;
356
357 sym->class = class;
358
359 if (declaring)
360 {
361 if (sym->status == declared && !warned)
362 complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
363 sym->status = declared;
364 }
365}
366
367
368/*------------------------------------------------.
369| Set the USER_TOKEN_NUMBER associated with SYM. |
370`------------------------------------------------*/
371
372void
373symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
374{
375 int *user_token_numberp;
376
377 if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
378 user_token_numberp = &sym->user_token_number;
379 else
380 user_token_numberp = &sym->alias->user_token_number;
381 if (*user_token_numberp != USER_NUMBER_UNDEFINED
382 && *user_token_numberp != user_token_number)
383 complain (&loc, complaint, _("redefining user token number of %s"),
384 sym->tag);
385
386 *user_token_numberp = user_token_number;
387 /* User defined $end token? */
388 if (user_token_number == 0)
389 {
390 endtoken = sym;
391 /* It is always mapped to 0, so it was already counted in
392 NTOKENS. */
393 if (endtoken->number != NUMBER_UNDEFINED)
394 --ntokens;
395 endtoken->number = 0;
396 }
397}
398
399
400/*----------------------------------------------------------.
401| If SYM is not defined, report an error, and consider it a |
402| nonterminal. |
403`----------------------------------------------------------*/
404
405static inline bool
406symbol_check_defined (symbol *sym)
407{
408 if (sym->class == unknown_sym)
409 {
410 assert (sym->status != declared);
411 complain (&sym->location,
412 sym->status == needed ? complaint : Wother,
413 _("symbol %s is used, but is not defined as a token"
414 " and has no rules"),
415 sym->tag);
416 sym->class = nterm_sym;
417 sym->number = nvars++;
418 }
419
420 {
421 int i;
422 for (i = 0; i < 2; ++i)
423 symbol_code_props_get (sym, i)->is_used = true;
424 }
425
426 /* Set the semantic type status associated to the current symbol to
427 'declared' so that we could check semantic types unnecessary uses. */
428 if (sym->type_name)
429 {
430 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
431 if (sem_type)
432 sem_type->status = declared;
433 }
434
435 return true;
436}
437
438static inline bool
439semantic_type_check_defined (semantic_type *sem_type)
440{
441 /* <*> and <> do not have to be "declared". */
442 if (sem_type->status == declared
443 || !*sem_type->tag
444 || STREQ(sem_type->tag, "*"))
445 {
446 int i;
447 for (i = 0; i < 2; ++i)
448 if (sem_type->props[i].kind != CODE_PROPS_NONE
449 && ! sem_type->props[i].is_used)
450 complain (&sem_type->location, Wother,
451 _("useless %s for type <%s>"),
452 code_props_type_string (i), sem_type->tag);
453 }
454 else
455 complain (&sem_type->location, Wother,
456 _("type <%s> is used, but is not associated to any symbol"),
457 sem_type->tag);
458
459 return true;
460}
461
462static bool
463symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
464{
465 return symbol_check_defined (sym);
466}
467
468static bool
469semantic_type_check_defined_processor (void *sem_type,
470 void *null ATTRIBUTE_UNUSED)
471{
472 return semantic_type_check_defined (sem_type);
473}
474
475
476void
477symbol_make_alias (symbol *sym, symbol *str, location loc)
478{
479 if (str->alias)
480 complain (&loc, Wother,
481 _("symbol %s used more than once as a literal string"), str->tag);
482 else if (sym->alias)
483 complain (&loc, Wother,
484 _("symbol %s given more than one literal string"), sym->tag);
485 else
486 {
487 str->class = token_sym;
488 str->user_token_number = sym->user_token_number;
489 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
490 str->alias = sym;
491 sym->alias = str;
492 str->number = sym->number;
493 symbol_type_set (str, sym->type_name, loc);
494 }
495}
496
497
498/*---------------------------------------------------------.
499| Check that THIS, and its alias, have same precedence and |
500| associativity. |
501`---------------------------------------------------------*/
502
503static inline void
504symbol_check_alias_consistency (symbol *this)
505{
506 symbol *sym = this;
507 symbol *str = this->alias;
508
509 /* Check only the symbol in the symbol-string pair. */
510 if (!(this->alias
511 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
512 return;
513
514 if (str->type_name != sym->type_name)
515 {
516 if (str->type_name)
517 symbol_type_set (sym, str->type_name, str->type_location);
518 else
519 symbol_type_set (str, sym->type_name, sym->type_location);
520 }
521
522
523 {
524 int i;
525 for (i = 0; i < CODE_PROPS_SIZE; ++i)
526 if (str->props[i].code)
527 symbol_code_props_set (sym, i, &str->props[i]);
528 else if (sym->props[i].code)
529 symbol_code_props_set (str, i, &sym->props[i]);
530 }
531
532 if (sym->prec || str->prec)
533 {
534 if (str->prec)
535 symbol_precedence_set (sym, str->prec, str->assoc,
536 str->prec_location);
537 else
538 symbol_precedence_set (str, sym->prec, sym->assoc,
539 sym->prec_location);
540 }
541}
542
543static bool
544symbol_check_alias_consistency_processor (void *this,
545 void *null ATTRIBUTE_UNUSED)
546{
547 symbol_check_alias_consistency (this);
548 return true;
549}
550
551
552/*-------------------------------------------------------------------.
553| Assign a symbol number, and write the definition of the token name |
554| into FDEFINES. Put in SYMBOLS. |
555`-------------------------------------------------------------------*/
556
557static inline bool
558symbol_pack (symbol *this)
559{
560 aver (this->number != NUMBER_UNDEFINED);
561 if (this->class == nterm_sym)
562 this->number += ntokens;
563 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
564 return true;
565
566 symbols[this->number] = this;
567 return true;
568}
569
570static bool
571symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
572{
573 return symbol_pack (this);
574}
575
576
577static void
578user_token_number_redeclaration (int num, symbol *first, symbol *second)
579{
580 unsigned i = 0;
581 /* User token numbers are not assigned during the parsing, but in a
582 second step, via a traversal of the symbol table sorted on tag.
583
584 However, error messages make more sense if we keep the first
585 declaration first. */
586 if (location_cmp (first->location, second->location) > 0)
587 {
588 symbol* tmp = first;
589 first = second;
590 second = tmp;
591 }
592 complain_indent (&second->location, complaint, &i,
593 _("user token number %d redeclaration for %s"),
594 num, second->tag);
595 i += SUB_INDENT;
596 complain_indent (&first->location, complaint, &i,
597 _("previous declaration for %s"),
598 first->tag);
599}
600
601/*--------------------------------------------------.
602| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
603`--------------------------------------------------*/
604
605static inline bool
606symbol_translation (symbol *this)
607{
608 /* Non-terminal? */
609 if (this->class == token_sym
610 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
611 {
612 /* A token which translation has already been set? */
613 if (token_translations[this->user_token_number] != undeftoken->number)
614 user_token_number_redeclaration
615 (this->user_token_number,
616 symbols[token_translations[this->user_token_number]],
617 this);
618
619 token_translations[this->user_token_number] = this->number;
620 }
621
622 return true;
623}
624
625static bool
626symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
627{
628 return symbol_translation (this);
629}
630
631
632/*---------------------------------------.
633| Symbol and semantic type hash tables. |
634`---------------------------------------*/
635
636/* Initial capacity of symbol and semantic type hash table. */
637#define HT_INITIAL_CAPACITY 257
638
639static struct hash_table *symbol_table = NULL;
640static struct hash_table *semantic_type_table = NULL;
641
642static inline bool
643hash_compare_symbol (const symbol *m1, const symbol *m2)
644{
645 /* Since tags are unique, we can compare the pointers themselves. */
646 return UNIQSTR_EQ (m1->tag, m2->tag);
647}
648
649static inline bool
650hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
651{
652 /* Since names are unique, we can compare the pointers themselves. */
653 return UNIQSTR_EQ (m1->tag, m2->tag);
654}
655
656static bool
657hash_symbol_comparator (void const *m1, void const *m2)
658{
659 return hash_compare_symbol (m1, m2);
660}
661
662static bool
663hash_semantic_type_comparator (void const *m1, void const *m2)
664{
665 return hash_compare_semantic_type (m1, m2);
666}
667
668static inline size_t
669hash_symbol (const symbol *m, size_t tablesize)
670{
671 /* Since tags are unique, we can hash the pointer itself. */
672 return ((uintptr_t) m->tag) % tablesize;
673}
674
675static inline size_t
676hash_semantic_type (const semantic_type *m, size_t tablesize)
677{
678 /* Since names are unique, we can hash the pointer itself. */
679 return ((uintptr_t) m->tag) % tablesize;
680}
681
682static size_t
683hash_symbol_hasher (void const *m, size_t tablesize)
684{
685 return hash_symbol (m, tablesize);
686}
687
688static size_t
689hash_semantic_type_hasher (void const *m, size_t tablesize)
690{
691 return hash_semantic_type (m, tablesize);
692}
693
694/*-------------------------------.
695| Create the symbol hash table. |
696`-------------------------------*/
697
698void
699symbols_new (void)
700{
701 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
702 NULL,
703 hash_symbol_hasher,
704 hash_symbol_comparator,
705 free);
706 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
707 NULL,
708 hash_semantic_type_hasher,
709 hash_semantic_type_comparator,
710 free);
711}
712
713
714/*----------------------------------------------------------------.
715| Find the symbol named KEY, and return it. If it does not exist |
716| yet, create it. |
717`----------------------------------------------------------------*/
718
719symbol *
720symbol_from_uniqstr (const uniqstr key, location loc)
721{
722 symbol probe;
723 symbol *entry;
724
725 probe.tag = key;
726 entry = hash_lookup (symbol_table, &probe);
727
728 if (!entry)
729 {
730 /* First insertion in the hash. */
731 aver (!symbols_sorted);
732 entry = symbol_new (key, loc);
733 if (!hash_insert (symbol_table, entry))
734 xalloc_die ();
735 }
736 return entry;
737}
738
739
740/*-----------------------------------------------------------------------.
741| Find the semantic type named KEY, and return it. If it does not exist |
742| yet, create it. |
743`-----------------------------------------------------------------------*/
744
745semantic_type *
746semantic_type_from_uniqstr (const uniqstr key, const location *loc)
747{
748 semantic_type probe;
749 semantic_type *entry;
750
751 probe.tag = key;
752 entry = hash_lookup (semantic_type_table, &probe);
753
754 if (!entry)
755 {
756 /* First insertion in the hash. */
757 entry = semantic_type_new (key, loc);
758 if (!hash_insert (semantic_type_table, entry))
759 xalloc_die ();
760 }
761 return entry;
762}
763
764
765/*----------------------------------------------------------------.
766| Find the symbol named KEY, and return it. If it does not exist |
767| yet, create it. |
768`----------------------------------------------------------------*/
769
770symbol *
771symbol_get (const char *key, location loc)
772{
773 return symbol_from_uniqstr (uniqstr_new (key), loc);
774}
775
776
777/*-----------------------------------------------------------------------.
778| Find the semantic type named KEY, and return it. If it does not exist |
779| yet, create it. |
780`-----------------------------------------------------------------------*/
781
782semantic_type *
783semantic_type_get (const char *key, const location *loc)
784{
785 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
786}
787
788
789/*------------------------------------------------------------------.
790| Generate a dummy nonterminal, whose name cannot conflict with the |
791| user's names. |
792`------------------------------------------------------------------*/
793
794symbol *
795dummy_symbol_get (location loc)
796{
797 /* Incremented for each generated symbol. */
798 static int dummy_count = 0;
799 static char buf[256];
800
801 symbol *sym;
802
803 sprintf (buf, "$@%d", ++dummy_count);
804 sym = symbol_get (buf, loc);
805 sym->class = nterm_sym;
806 sym->number = nvars++;
807 return sym;
808}
809
810bool
811symbol_is_dummy (const symbol *sym)
812{
813 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
814}
815
816/*-------------------.
817| Free the symbols. |
818`-------------------*/
819
820void
821symbols_free (void)
822{
823 hash_free (symbol_table);
824 hash_free (semantic_type_table);
825 free (symbols);
826 free (symbols_sorted);
827 free (semantic_types_sorted);
828}
829
830
831/*---------------------------------------------------------------.
832| Look for undefined symbols, report an error, and consider them |
833| terminals. |
834`---------------------------------------------------------------*/
835
836static int
837symbols_cmp (symbol const *a, symbol const *b)
838{
839 return strcmp (a->tag, b->tag);
840}
841
842static int
843symbols_cmp_qsort (void const *a, void const *b)
844{
845 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
846}
847
848static void
849symbols_do (Hash_processor processor, void *processor_data,
850 struct hash_table *table, symbol ***sorted)
851{
852 size_t count = hash_get_n_entries (table);
853 if (!*sorted)
854 {
855 *sorted = xnmalloc (count, sizeof **sorted);
856 hash_get_entries (table, (void**)*sorted, count);
857 qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
858 }
859 {
860 size_t i;
861 for (i = 0; i < count; ++i)
862 processor ((*sorted)[i], processor_data);
863 }
864}
865
866/*--------------------------------------------------------------.
867| Check that all the symbols are defined. Report any undefined |
868| symbols and consider them nonterminals. |
869`--------------------------------------------------------------*/
870
871void
872symbols_check_defined (void)
873{
874 symbols_do (symbol_check_defined_processor, NULL,
875 symbol_table, &symbols_sorted);
876 symbols_do (semantic_type_check_defined_processor, NULL,
877 semantic_type_table, &semantic_types_sorted);
878}
879
880/*------------------------------------------------------------------.
881| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
882| number. |
883`------------------------------------------------------------------*/
884
885static void
886symbols_token_translations_init (void)
887{
888 bool num_256_available_p = true;
889 int i;
890
891 /* Find the highest user token number, and whether 256, the POSIX
892 preferred user token number for the error token, is used. */
893 max_user_token_number = 0;
894 for (i = 0; i < ntokens; ++i)
895 {
896 symbol *this = symbols[i];
897 if (this->user_token_number != USER_NUMBER_UNDEFINED)
898 {
899 if (this->user_token_number > max_user_token_number)
900 max_user_token_number = this->user_token_number;
901 if (this->user_token_number == 256)
902 num_256_available_p = false;
903 }
904 }
905
906 /* If 256 is not used, assign it to error, to follow POSIX. */
907 if (num_256_available_p
908 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
909 errtoken->user_token_number = 256;
910
911 /* Set the missing user numbers. */
912 if (max_user_token_number < 256)
913 max_user_token_number = 256;
914
915 for (i = 0; i < ntokens; ++i)
916 {
917 symbol *this = symbols[i];
918 if (this->user_token_number == USER_NUMBER_UNDEFINED)
919 this->user_token_number = ++max_user_token_number;
920 if (this->user_token_number > max_user_token_number)
921 max_user_token_number = this->user_token_number;
922 }
923
924 token_translations = xnmalloc (max_user_token_number + 1,
925 sizeof *token_translations);
926
927 /* Initialize all entries for literal tokens to the internal token
928 number for $undefined, which represents all invalid inputs. */
929 for (i = 0; i < max_user_token_number + 1; i++)
930 token_translations[i] = undeftoken->number;
931 symbols_do (symbol_translation_processor, NULL,
932 symbol_table, &symbols_sorted);
933}
934
935
936/*----------------------------------------------------------------.
937| Assign symbol numbers, and write definition of token names into |
938| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
939`----------------------------------------------------------------*/
940
941void
942symbols_pack (void)
943{
944 symbols_do (symbol_check_alias_consistency_processor, NULL,
945 symbol_table, &symbols_sorted);
946
947 symbols = xcalloc (nsyms, sizeof *symbols);
948 symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
949
950 /* Aliases leave empty slots in symbols, so remove them. */
951 {
952 int writei;
953 int readi;
954 int nsyms_old = nsyms;
955 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
956 {
957 if (symbols[readi] == NULL)
958 {
959 nsyms -= 1;
960 ntokens -= 1;
961 }
962 else
963 {
964 symbols[writei] = symbols[readi];
965 symbols[writei]->number = writei;
966 if (symbols[writei]->alias)
967 symbols[writei]->alias->number = writei;
968 writei += 1;
969 }
970 }
971 }
972 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
973
974 symbols_token_translations_init ();
975
976 if (startsymbol->class == unknown_sym)
977 complain (&startsymbol_location, fatal,
978 _("the start symbol %s is undefined"),
979 startsymbol->tag);
980 else if (startsymbol->class == token_sym)
981 complain (&startsymbol_location, fatal,
982 _("the start symbol %s is a token"),
983 startsymbol->tag);
984}
985
986/*---------------------------------.
987| Initialize relation graph nodes. |
988`---------------------------------*/
989
990static void
991init_prec_nodes (void)
992{
993 int i;
994 prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
995 for (i = 0; i < nsyms; ++i)
996 {
997 prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
998 symgraph *s = prec_nodes[i];
999 s->id = i;
1000 s->succ = 0;
1001 s->pred = 0;
1002 }
1003}
1004
1005/*----------------.
1006| Create a link. |
1007`----------------*/
1008
1009static symgraphlink *
1010symgraphlink_new (graphid id, symgraphlink *next)
1011{
1012 symgraphlink *l = xmalloc (sizeof *l);
1013 l->id = id;
1014 l->next = next;
1015 return l;
1016}
1017
1018
1019/*------------------------------------------------------------------.
1020| Register the second symbol of the precedence relation, and return |
1021| whether this relation is new. Use only in register_precedence. |
1022`------------------------------------------------------------------*/
1023
1024static bool
1025register_precedence_second_symbol (symgraphlink **first, graphid sym)
1026{
1027 if (!*first || sym < (*first)->id)
1028 *first = symgraphlink_new (sym, *first);
1029 else
1030 {
1031 symgraphlink *slist = *first;
1032
1033 while (slist->next && slist->next->id <= sym)
1034 slist = slist->next;
1035
1036 if (slist->id == sym)
1037 /* Relation already present. */
1038 return false;
1039
1040 slist->next = symgraphlink_new (sym, slist->next);
1041 }
1042 return true;
1043}
1044
1045/*------------------------------------------------------------------.
1046| Register a new relation between symbols as used. The first symbol |
1047| has a greater precedence than the second one. |
1048`------------------------------------------------------------------*/
1049
1050void
1051register_precedence (graphid first, graphid snd)
1052{
1053 if (!prec_nodes)
1054 init_prec_nodes ();
1055 register_precedence_second_symbol (&(prec_nodes[first]->succ), snd);
1056 register_precedence_second_symbol (&(prec_nodes[snd]->pred), first);
1057}
1058
1059
1060/*---------------------------------------.
1061| Deep clear a linked / adjacency list). |
1062`---------------------------------------*/
1063
1064static void
1065linkedlist_free (symgraphlink *node)
1066{
1067 if (node)
1068 {
1069 while (node->next)
1070 {
1071 symgraphlink *tmp = node->next;
1072 free (node);
1073 node = tmp;
1074 }
1075 free (node);
1076 }
1077}
1078
1079/*----------------------------------------------.
1080| Clear and destroy association tracking table. |
1081`----------------------------------------------*/
1082
1083static void
1084assoc_free (void)
1085{
1086 int i;
1087 for (i = 0; i < nsyms; ++i)
1088 {
1089 linkedlist_free (prec_nodes[i]->pred);
1090 linkedlist_free (prec_nodes[i]->succ);
1091 free (prec_nodes[i]);
1092 }
1093 free (prec_nodes);
1094}
1095
1096/*---------------------------------------.
1097| Initialize association tracking table. |
1098`---------------------------------------*/
1099
1100static void
1101init_assoc (void)
1102{
1103 graphid i;
1104 used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
1105 for (i = 0; i < nsyms; ++i)
1106 used_assoc[i] = false;
1107}
1108
1109/*------------------------------------------------------------------.
1110| Test if the associativity for the symbols is defined and useless. |
1111`------------------------------------------------------------------*/
1112
1113static inline bool
1114is_assoc_useless (symbol *s)
1115{
1116 return s
1117 && s->assoc != undef_assoc
1118 && s->assoc != precedence_assoc
1119 && !used_assoc[s->number];
1120}
1121
1122/*-------------------------------.
1123| Register a used associativity. |
1124`-------------------------------*/
1125
1126void
1127register_assoc (graphid i, graphid j)
1128{
1129 if (!used_assoc)
1130 init_assoc ();
1131 used_assoc[i] = true;
1132 used_assoc[j] = true;
1133}
1134
1135/*--------------------------------------------------.
1136| Print a warning for unused precedence relations. |
1137`--------------------------------------------------*/
1138
1139void
1140print_precedence_warnings (void)
1141{
1142 int i;
1143 if (!prec_nodes)
1144 init_prec_nodes ();
1145 if (!used_assoc)
1146 init_assoc ();
1147 for (i = 0; i < nsyms; ++i)
1148 {
1149 symbol *s = symbols[i];
1150 if (s
1151 && s->prec != 0
1152 && !prec_nodes[i]->pred
1153 && !prec_nodes[i]->succ)
1154 {
1155 if (is_assoc_useless (s))
1156 complain (&s->location, Wprecedence,
1157 _("useless precedence and associativity for %s"), s->tag);
1158 else if (s->assoc == precedence_assoc)
1159 complain (&s->location, Wprecedence,
1160 _("useless precedence for %s"), s->tag);
1161 }
1162 else if (is_assoc_useless (s))
1163 complain (&s->location, Wprecedence,
1164 _("useless associativity for %s, use %%precedence"), s->tag);
1165 }
1166 free (used_assoc);
1167 assoc_free ();
1168}