]> git.saurik.com Git - bison.git/blame - src/symtab.c
NEWS: Internationalization.
[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
JD
491 symbol *sym = this;
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
AD
551{
552 if (this->class == nterm_sym)
553 {
554 this->number += ntokens;
555 }
556 else if (this->alias)
557 {
558 /* This symbol and its alias are a single token defn.
559 Allocate a tokno, and assign to both check agreement of
560 prec and assoc fields and make both the same */
561 if (this->number == NUMBER_UNDEFINED)
562 {
88bce5a2 563 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
564 this->number = this->alias->number = 0;
565 else
566 {
4f82b42a 567 aver (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
568 this->number = this->alias->number;
569 }
570 }
dfaa4860
JD
571 /* Do not do processing below for USER_NUMBER_HAS_STRING_ALIASes. */
572 if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
a3714bce 573 return true;
2f1afb73
AD
574 }
575 else /* this->class == token_sym */
4f82b42a 576 aver (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
577
578 symbols[this->number] = this;
a3714bce 579 return true;
2f1afb73
AD
580}
581
0fb1efaf
PE
582static bool
583symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
584{
585 return symbol_pack (this);
586}
587
2f1afb73 588
12cf133f
AD
589static void
590user_token_number_redeclaration (int num, symbol *first, symbol *second)
591{
592 /* User token numbers are not assigned during the parsing, but in a
83b60c97 593 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 594
83b60c97
JD
595 However, error messages make more sense if we keep the first
596 declaration first. */
12cf133f
AD
597 if (location_cmp (first->location, second->location) > 0)
598 {
599 symbol* tmp = first;
600 first = second;
601 second = tmp;
602 }
603 complain_at (second->location,
604 _("user token number %d redeclaration for %s"),
605 num, second->tag);
606 complain_at (first->location, _("previous declaration for %s"),
607 first->tag);
608}
2f1afb73
AD
609
610/*--------------------------------------------------.
611| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
612`--------------------------------------------------*/
613
0fb1efaf 614static inline bool
17ee7397 615symbol_translation (symbol *this)
2f1afb73
AD
616{
617 /* Non-terminal? */
618 if (this->class == token_sym
dfaa4860 619 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
620 {
621 /* A token which translation has already been set? */
622 if (token_translations[this->user_token_number] != undeftoken->number)
12cf133f
AD
623 user_token_number_redeclaration
624 (this->user_token_number,
625 symbols[token_translations[this->user_token_number]],
626 this);
2f1afb73
AD
627
628 token_translations[this->user_token_number] = this->number;
629 }
630
a3714bce 631 return true;
2f1afb73
AD
632}
633
0fb1efaf
PE
634static bool
635symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
636{
637 return symbol_translation (this);
638}
639
72a23c97 640
b2a0b7ca
JD
641/*---------------------------------------.
642| Symbol and semantic type hash tables. |
643`---------------------------------------*/
40675e7c 644
b2a0b7ca 645/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
646#define HT_INITIAL_CAPACITY 257
647
db8837cb 648static struct hash_table *symbol_table = NULL;
b2a0b7ca 649static struct hash_table *semantic_type_table = NULL;
72a23c97 650
0fb1efaf 651static inline bool
17ee7397 652hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 653{
95612cfa 654 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 655 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
656}
657
b2a0b7ca
JD
658static inline bool
659hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
660{
661 /* Since names are unique, we can compare the pointers themselves. */
662 return UNIQSTR_EQ (m1->tag, m2->tag);
663}
664
0fb1efaf
PE
665static bool
666hash_symbol_comparator (void const *m1, void const *m2)
667{
668 return hash_compare_symbol (m1, m2);
669}
670
b2a0b7ca
JD
671static bool
672hash_semantic_type_comparator (void const *m1, void const *m2)
673{
674 return hash_compare_semantic_type (m1, m2);
675}
676
233a88ad
PE
677static inline size_t
678hash_symbol (const symbol *m, size_t tablesize)
72a23c97 679{
95612cfa 680 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
681 return ((uintptr_t) m->tag) % tablesize;
682}
683
b2a0b7ca
JD
684static inline size_t
685hash_semantic_type (const semantic_type *m, size_t tablesize)
686{
687 /* Since names are unique, we can hash the pointer itself. */
688 return ((uintptr_t) m->tag) % tablesize;
689}
690
233a88ad
PE
691static size_t
692hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
693{
694 return hash_symbol (m, tablesize);
72a23c97
AD
695}
696
b2a0b7ca
JD
697static size_t
698hash_semantic_type_hasher (void const *m, size_t tablesize)
699{
700 return hash_semantic_type (m, tablesize);
701}
72a23c97
AD
702
703/*-------------------------------.
2f1afb73 704| Create the symbol hash table. |
72a23c97
AD
705`-------------------------------*/
706
707void
db8837cb 708symbols_new (void)
72a23c97 709{
db8837cb 710 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 711 NULL,
0fb1efaf
PE
712 hash_symbol_hasher,
713 hash_symbol_comparator,
714 free);
b2a0b7ca
JD
715 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
716 NULL,
717 hash_semantic_type_hasher,
718 hash_semantic_type_comparator,
719 free);
40675e7c
DM
720}
721
722
1e9798d5
AD
723/*----------------------------------------------------------------.
724| Find the symbol named KEY, and return it. If it does not exist |
725| yet, create it. |
726`----------------------------------------------------------------*/
727
17ee7397 728symbol *
203b9274 729symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 730{
17ee7397
PE
731 symbol probe;
732 symbol *entry;
40675e7c 733
0fb1efaf 734 probe.tag = key;
db8837cb 735 entry = hash_lookup (symbol_table, &probe);
40675e7c 736
72a23c97 737 if (!entry)
40675e7c 738 {
72a23c97 739 /* First insertion in the hash. */
83b60c97 740 aver (!symbols_sorted);
17ee7397 741 entry = symbol_new (key, loc);
92d7a23a
AD
742 if (!hash_insert (symbol_table, entry))
743 xalloc_die ();
40675e7c 744 }
72a23c97
AD
745 return entry;
746}
40675e7c 747
40675e7c 748
b2a0b7ca
JD
749/*-----------------------------------------------------------------------.
750| Find the semantic type named KEY, and return it. If it does not exist |
751| yet, create it. |
752`-----------------------------------------------------------------------*/
753
754semantic_type *
755semantic_type_from_uniqstr (const uniqstr key)
756{
757 semantic_type probe;
758 semantic_type *entry;
759
760 probe.tag = key;
761 entry = hash_lookup (semantic_type_table, &probe);
762
763 if (!entry)
764 {
765 /* First insertion in the hash. */
766 entry = semantic_type_new (key);
92d7a23a
AD
767 if (!hash_insert (semantic_type_table, entry))
768 xalloc_die ();
b2a0b7ca
JD
769 }
770 return entry;
771}
772
773
203b9274
AD
774/*----------------------------------------------------------------.
775| Find the symbol named KEY, and return it. If it does not exist |
776| yet, create it. |
777`----------------------------------------------------------------*/
778
779symbol *
780symbol_get (const char *key, location loc)
781{
782 return symbol_from_uniqstr (uniqstr_new (key), loc);
783}
784
785
b2a0b7ca
JD
786/*-----------------------------------------------------------------------.
787| Find the semantic type named KEY, and return it. If it does not exist |
788| yet, create it. |
789`-----------------------------------------------------------------------*/
790
791semantic_type *
792semantic_type_get (const char *key)
793{
794 return semantic_type_from_uniqstr (uniqstr_new (key));
795}
796
797
39f41916
AD
798/*------------------------------------------------------------------.
799| Generate a dummy nonterminal, whose name cannot conflict with the |
800| user's names. |
801`------------------------------------------------------------------*/
802
17ee7397
PE
803symbol *
804dummy_symbol_get (location loc)
39f41916
AD
805{
806 /* Incremented for each generated symbol. */
807 static int dummy_count = 0;
808 static char buf[256];
809
17ee7397 810 symbol *sym;
39f41916 811
f91b1629 812 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 813 sym = symbol_get (buf, loc);
39f41916
AD
814 sym->class = nterm_sym;
815 sym->number = nvars++;
816 return sym;
817}
818
4d7370cb
JD
819bool
820symbol_is_dummy (const symbol *sym)
821{
f91b1629 822 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 823}
39f41916 824
72a23c97 825/*-------------------.
db8837cb 826| Free the symbols. |
72a23c97
AD
827`-------------------*/
828
829void
db8837cb 830symbols_free (void)
72a23c97 831{
db8837cb 832 hash_free (symbol_table);
b2a0b7ca 833 hash_free (semantic_type_table);
536545f3 834 free (symbols);
83b60c97 835 free (symbols_sorted);
40675e7c
DM
836}
837
838
72a23c97 839/*---------------------------------------------------------------.
db8837cb 840| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
841| terminals. |
842`---------------------------------------------------------------*/
843
83b60c97
JD
844static int
845symbols_cmp (symbol const *a, symbol const *b)
846{
847 return strcmp (a->tag, b->tag);
848}
849
850static int
851symbols_cmp_qsort (void const *a, void const *b)
852{
853 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
854}
855
0fb1efaf
PE
856static void
857symbols_do (Hash_processor processor, void *processor_data)
40675e7c 858{
83b60c97
JD
859 size_t count = hash_get_n_entries (symbol_table);
860 if (!symbols_sorted)
861 {
862 symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
863 hash_get_entries (symbol_table, (void**)symbols_sorted, count);
864 qsort (symbols_sorted, count, sizeof *symbols_sorted,
865 symbols_cmp_qsort);
866 }
867 {
868 size_t i;
869 for (i = 0; i < count; ++i)
870 processor (symbols_sorted[i], processor_data);
871 }
40675e7c 872}
2f1afb73 873
2f1afb73
AD
874/*--------------------------------------------------------------.
875| Check that all the symbols are defined. Report any undefined |
876| symbols and consider them nonterminals. |
877`--------------------------------------------------------------*/
878
879void
880symbols_check_defined (void)
881{
0fb1efaf 882 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
883}
884
885/*------------------------------------------------------------------.
886| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
887| number. |
888`------------------------------------------------------------------*/
889
890static void
891symbols_token_translations_init (void)
892{
a3714bce 893 bool num_256_available_p = true;
2f1afb73
AD
894 int i;
895
896 /* Find the highest user token number, and whether 256, the POSIX
897 preferred user token number for the error token, is used. */
898 max_user_token_number = 0;
899 for (i = 0; i < ntokens; ++i)
900 {
17ee7397 901 symbol *this = symbols[i];
2f1afb73
AD
902 if (this->user_token_number != USER_NUMBER_UNDEFINED)
903 {
904 if (this->user_token_number > max_user_token_number)
905 max_user_token_number = this->user_token_number;
906 if (this->user_token_number == 256)
a3714bce 907 num_256_available_p = false;
2f1afb73
AD
908 }
909 }
910
911 /* If 256 is not used, assign it to error, to follow POSIX. */
912 if (num_256_available_p
913 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
914 errtoken->user_token_number = 256;
915
916 /* Set the missing user numbers. */
917 if (max_user_token_number < 256)
918 max_user_token_number = 256;
919
920 for (i = 0; i < ntokens; ++i)
921 {
17ee7397 922 symbol *this = symbols[i];
2f1afb73
AD
923 if (this->user_token_number == USER_NUMBER_UNDEFINED)
924 this->user_token_number = ++max_user_token_number;
925 if (this->user_token_number > max_user_token_number)
926 max_user_token_number = this->user_token_number;
927 }
928
da2a7671
PE
929 token_translations = xnmalloc (max_user_token_number + 1,
930 sizeof *token_translations);
2f1afb73 931
b3a28fd4
AD
932 /* Initialize all entries for literal tokens to the internal token
933 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
934 for (i = 0; i < max_user_token_number + 1; i++)
935 token_translations[i] = undeftoken->number;
0fb1efaf 936 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
937}
938
939
940/*----------------------------------------------------------------.
941| Assign symbol numbers, and write definition of token names into |
942| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
943`----------------------------------------------------------------*/
944
945void
946symbols_pack (void)
947{
0fb1efaf 948 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
949
950 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 951 symbols_do (symbol_pack_processor, NULL);
2f1afb73 952
6d0ef4ec
JD
953 /* Aliases leave empty slots in symbols, so remove them. */
954 {
955 int writei;
956 int readi;
957 int nsyms_old = nsyms;
958 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
959 {
960 if (symbols[readi] == NULL)
961 {
962 nsyms -= 1;
963 ntokens -= 1;
964 }
965 else
966 {
967 symbols[writei] = symbols[readi];
968 symbols[writei]->number = writei;
969 if (symbols[writei]->alias)
970 symbols[writei]->alias->number = writei;
971 writei += 1;
972 }
973 }
974 }
975 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
976
2f1afb73
AD
977 symbols_token_translations_init ();
978
979 if (startsymbol->class == unknown_sym)
ee000ba4 980 fatal_at (startsymbol_location,
dafdc66f 981 _("the start symbol %s is undefined"),
97650f4e 982 startsymbol->tag);
2f1afb73 983 else if (startsymbol->class == token_sym)
ee000ba4 984 fatal_at (startsymbol_location,
dafdc66f 985 _("the start symbol %s is a token"),
97650f4e 986 startsymbol->tag);
2f1afb73 987}
ec5479ce
JD
988
989
12e35840
JD
990/*--------------------------------------------------.
991| Set default tagged/tagless %destructor/%printer. |
992`--------------------------------------------------*/
993
994void
95021767 995default_tagged_destructor_set (code_props const *destructor)
12e35840 996{
95021767 997 if (default_tagged_destructor.code)
12e35840 998 {
95021767
JD
999 complain_at (destructor->location,
1000 _("redeclaration for default tagged %%destructor"));
1001 complain_at (default_tagged_destructor.location,
12e35840
JD
1002 _("previous declaration"));
1003 }
95021767 1004 default_tagged_destructor = *destructor;
12e35840
JD
1005}
1006
1007void
95021767 1008default_tagless_destructor_set (code_props const *destructor)
12e35840 1009{
95021767 1010 if (default_tagless_destructor.code)
12e35840 1011 {
95021767
JD
1012 complain_at (destructor->location,
1013 _("redeclaration for default tagless %%destructor"));
1014 complain_at (default_tagless_destructor.location,
12e35840
JD
1015 _("previous declaration"));
1016 }
95021767 1017 default_tagless_destructor = *destructor;
12e35840 1018}
ec5479ce
JD
1019
1020void
95021767 1021default_tagged_printer_set (code_props const *printer)
ec5479ce 1022{
95021767 1023 if (default_tagged_printer.code)
ec5479ce 1024 {
95021767
JD
1025 complain_at (printer->location,
1026 _("redeclaration for default tagged %%printer"));
1027 complain_at (default_tagged_printer.location,
12e35840 1028 _("previous declaration"));
ec5479ce 1029 }
95021767 1030 default_tagged_printer = *printer;
ec5479ce
JD
1031}
1032
1033void
95021767 1034default_tagless_printer_set (code_props const *printer)
ec5479ce 1035{
95021767 1036 if (default_tagless_printer.code)
ec5479ce 1037 {
95021767
JD
1038 complain_at (printer->location,
1039 _("redeclaration for default tagless %%printer"));
1040 complain_at (default_tagless_printer.location,
12e35840 1041 _("previous declaration"));
ec5479ce 1042 }
95021767 1043 default_tagless_printer = *printer;
ec5479ce 1044}