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