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