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