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