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