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