]> git.saurik.com Git - bison.git/blame - src/symtab.c
variables: accept dashes.
[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);
db8837cb 683 hash_insert (symbol_table, entry);
40675e7c 684 }
72a23c97
AD
685 return entry;
686}
40675e7c 687
40675e7c 688
b2a0b7ca
JD
689/*-----------------------------------------------------------------------.
690| Find the semantic type named KEY, and return it. If it does not exist |
691| yet, create it. |
692`-----------------------------------------------------------------------*/
693
694semantic_type *
695semantic_type_from_uniqstr (const uniqstr key)
696{
697 semantic_type probe;
698 semantic_type *entry;
699
700 probe.tag = key;
701 entry = hash_lookup (semantic_type_table, &probe);
702
703 if (!entry)
704 {
705 /* First insertion in the hash. */
706 entry = semantic_type_new (key);
707 hash_insert (semantic_type_table, entry);
708 }
709 return entry;
710}
711
712
203b9274
AD
713/*----------------------------------------------------------------.
714| Find the symbol named KEY, and return it. If it does not exist |
715| yet, create it. |
716`----------------------------------------------------------------*/
717
718symbol *
719symbol_get (const char *key, location loc)
720{
721 return symbol_from_uniqstr (uniqstr_new (key), loc);
722}
723
724
b2a0b7ca
JD
725/*-----------------------------------------------------------------------.
726| Find the semantic type named KEY, and return it. If it does not exist |
727| yet, create it. |
728`-----------------------------------------------------------------------*/
729
730semantic_type *
731semantic_type_get (const char *key)
732{
733 return semantic_type_from_uniqstr (uniqstr_new (key));
734}
735
736
39f41916
AD
737/*------------------------------------------------------------------.
738| Generate a dummy nonterminal, whose name cannot conflict with the |
739| user's names. |
740`------------------------------------------------------------------*/
741
17ee7397
PE
742symbol *
743dummy_symbol_get (location loc)
39f41916
AD
744{
745 /* Incremented for each generated symbol. */
746 static int dummy_count = 0;
747 static char buf[256];
748
17ee7397 749 symbol *sym;
39f41916 750
f91b1629 751 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 752 sym = symbol_get (buf, loc);
39f41916
AD
753 sym->class = nterm_sym;
754 sym->number = nvars++;
755 return sym;
756}
757
4d7370cb
JD
758bool
759symbol_is_dummy (const symbol *sym)
760{
f91b1629 761 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 762}
39f41916 763
72a23c97 764/*-------------------.
db8837cb 765| Free the symbols. |
72a23c97
AD
766`-------------------*/
767
768void
db8837cb 769symbols_free (void)
72a23c97 770{
db8837cb 771 hash_free (symbol_table);
b2a0b7ca 772 hash_free (semantic_type_table);
536545f3 773 free (symbols);
40675e7c
DM
774}
775
776
72a23c97 777/*---------------------------------------------------------------.
db8837cb 778| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
779| terminals. |
780`---------------------------------------------------------------*/
781
0fb1efaf
PE
782static void
783symbols_do (Hash_processor processor, void *processor_data)
40675e7c 784{
0fb1efaf 785 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 786}
2f1afb73
AD
787
788
789/*--------------------------------------------------------------.
790| Check that all the symbols are defined. Report any undefined |
791| symbols and consider them nonterminals. |
792`--------------------------------------------------------------*/
793
794void
795symbols_check_defined (void)
796{
0fb1efaf 797 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
798}
799
800/*------------------------------------------------------------------.
801| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
802| number. |
803`------------------------------------------------------------------*/
804
805static void
806symbols_token_translations_init (void)
807{
a3714bce 808 bool num_256_available_p = true;
2f1afb73
AD
809 int i;
810
811 /* Find the highest user token number, and whether 256, the POSIX
812 preferred user token number for the error token, is used. */
813 max_user_token_number = 0;
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 {
819 if (this->user_token_number > max_user_token_number)
820 max_user_token_number = this->user_token_number;
821 if (this->user_token_number == 256)
a3714bce 822 num_256_available_p = false;
2f1afb73
AD
823 }
824 }
825
826 /* If 256 is not used, assign it to error, to follow POSIX. */
827 if (num_256_available_p
828 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
829 errtoken->user_token_number = 256;
830
831 /* Set the missing user numbers. */
832 if (max_user_token_number < 256)
833 max_user_token_number = 256;
834
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 this->user_token_number = ++max_user_token_number;
840 if (this->user_token_number > max_user_token_number)
841 max_user_token_number = this->user_token_number;
842 }
843
da2a7671
PE
844 token_translations = xnmalloc (max_user_token_number + 1,
845 sizeof *token_translations);
2f1afb73
AD
846
847 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
848 token number for $undefined, which represents all invalid inputs.
849 */
2f1afb73
AD
850 for (i = 0; i < max_user_token_number + 1; i++)
851 token_translations[i] = undeftoken->number;
0fb1efaf 852 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
853}
854
855
856/*----------------------------------------------------------------.
857| Assign symbol numbers, and write definition of token names into |
858| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
859`----------------------------------------------------------------*/
860
861void
862symbols_pack (void)
863{
0fb1efaf 864 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
865
866 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 867 symbols_do (symbol_pack_processor, NULL);
2f1afb73 868
6d0ef4ec
JD
869 /* Aliases leave empty slots in symbols, so remove them. */
870 {
871 int writei;
872 int readi;
873 int nsyms_old = nsyms;
874 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
875 {
876 if (symbols[readi] == NULL)
877 {
878 nsyms -= 1;
879 ntokens -= 1;
880 }
881 else
882 {
883 symbols[writei] = symbols[readi];
884 symbols[writei]->number = writei;
885 if (symbols[writei]->alias)
886 symbols[writei]->alias->number = writei;
887 writei += 1;
888 }
889 }
890 }
891 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
892
2f1afb73
AD
893 symbols_token_translations_init ();
894
895 if (startsymbol->class == unknown_sym)
ee000ba4 896 fatal_at (startsymbol_location,
dafdc66f 897 _("the start symbol %s is undefined"),
97650f4e 898 startsymbol->tag);
2f1afb73 899 else if (startsymbol->class == token_sym)
ee000ba4 900 fatal_at (startsymbol_location,
dafdc66f 901 _("the start symbol %s is a token"),
97650f4e 902 startsymbol->tag);
2f1afb73 903}
ec5479ce
JD
904
905
12e35840
JD
906/*--------------------------------------------------.
907| Set default tagged/tagless %destructor/%printer. |
908`--------------------------------------------------*/
909
910void
95021767 911default_tagged_destructor_set (code_props const *destructor)
12e35840 912{
95021767 913 if (default_tagged_destructor.code)
12e35840 914 {
95021767
JD
915 complain_at (destructor->location,
916 _("redeclaration for default tagged %%destructor"));
917 complain_at (default_tagged_destructor.location,
12e35840
JD
918 _("previous declaration"));
919 }
95021767 920 default_tagged_destructor = *destructor;
12e35840
JD
921}
922
923void
95021767 924default_tagless_destructor_set (code_props const *destructor)
12e35840 925{
95021767 926 if (default_tagless_destructor.code)
12e35840 927 {
95021767
JD
928 complain_at (destructor->location,
929 _("redeclaration for default tagless %%destructor"));
930 complain_at (default_tagless_destructor.location,
12e35840
JD
931 _("previous declaration"));
932 }
95021767 933 default_tagless_destructor = *destructor;
12e35840 934}
ec5479ce
JD
935
936void
95021767 937default_tagged_printer_set (code_props const *printer)
ec5479ce 938{
95021767 939 if (default_tagged_printer.code)
ec5479ce 940 {
95021767
JD
941 complain_at (printer->location,
942 _("redeclaration for default tagged %%printer"));
943 complain_at (default_tagged_printer.location,
12e35840 944 _("previous declaration"));
ec5479ce 945 }
95021767 946 default_tagged_printer = *printer;
ec5479ce
JD
947}
948
949void
95021767 950default_tagless_printer_set (code_props const *printer)
ec5479ce 951{
95021767 952 if (default_tagless_printer.code)
ec5479ce 953 {
95021767
JD
954 complain_at (printer->location,
955 _("redeclaration for default tagless %%printer"));
956 complain_at (default_tagless_printer.location,
12e35840 957 _("previous declaration"));
ec5479ce 958 }
95021767 959 default_tagless_printer = *printer;
ec5479ce 960}