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