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