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