]> git.saurik.com Git - bison.git/blame - src/symtab.c
tests: lalr1.cc: check syntax_error.
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
34136e65 3 Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software
575619af 4 Foundation, Inc.
40675e7c 5
95e36146 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
f16b0819 8 This program is free software: you can redistribute it and/or modify
95e36146 9 it under the terms of the GNU General Public License as published by
f16b0819
PE
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
40675e7c 12
f16b0819 13 This program is distributed in the hope that it will be useful,
95e36146
AD
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
40675e7c 17
95e36146 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
40675e7c 20
2cec9080 21#include <config.h>
40675e7c 22#include "system.h"
17ee7397
PE
23
24#include <hash.h>
25#include <quotearg.h>
26
2f1afb73 27#include "complain.h"
40675e7c 28#include "gram.h"
4a9cd8f2 29#include "quote.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. */
ba60c395 72 if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-'))
4f646c37
AD
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)"),
e9690142 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
e9690142
JD
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)
e9690142 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)
e9690142 344 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
b2a0b7ca 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)
e9690142 379 warn_at (loc, _("symbol %s redeclared"), sym->tag);
073f9288
PE
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;
44536b35 407 /* It is always mapped to 0, so it was already counted in
e9690142 408 NTOKENS. */
1f36f544
JD
409 if (endtoken->number != NUMBER_UNDEFINED)
410 --ntokens;
411 endtoken->number = 0;
44536b35
AD
412 }
413}
414
415
17ee7397
PE
416/*----------------------------------------------------------.
417| If SYM is not defined, report an error, and consider it a |
418| nonterminal. |
419`----------------------------------------------------------*/
2f1afb73 420
0fb1efaf 421static inline bool
17ee7397 422symbol_check_defined (symbol *sym)
2f1afb73 423{
17ee7397 424 if (sym->class == unknown_sym)
2f1afb73 425 {
ee000ba4 426 complain_at
e9690142
JD
427 (sym->location,
428 _("symbol %s is used, but is not defined as a token and has no rules"),
429 sym->tag);
17ee7397
PE
430 sym->class = nterm_sym;
431 sym->number = nvars++;
2f1afb73
AD
432 }
433
a3714bce 434 return true;
2f1afb73
AD
435}
436
0fb1efaf
PE
437static bool
438symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
439{
440 return symbol_check_defined (sym);
441}
442
2f1afb73 443
2f1afb73 444void
dfaa4860 445symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 446{
dfaa4860 447 if (str->alias)
4a9cd8f2 448 warn_at (loc, _("symbol %s used more than once as a literal string"),
e9690142 449 str->tag);
17ee7397 450 else if (sym->alias)
4a9cd8f2 451 warn_at (loc, _("symbol %s given more than one literal string"),
e9690142 452 sym->tag);
2f1afb73
AD
453 else
454 {
dfaa4860
JD
455 str->class = token_sym;
456 str->user_token_number = sym->user_token_number;
457 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
458 str->alias = sym;
459 sym->alias = str;
460 str->number = sym->number;
461 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
462 }
463}
464
465
466/*---------------------------------------------------------.
467| Check that THIS, and its alias, have same precedence and |
468| associativity. |
469`---------------------------------------------------------*/
470
df09ef2e 471static inline void
0fb1efaf 472symbol_check_alias_consistency (symbol *this)
2f1afb73 473{
dfaa4860 474 symbol *sym = this;
b143f404 475 symbol *str = this->alias;
df09ef2e 476
dfaa4860
JD
477 /* Check only the symbol in the symbol-string pair. */
478 if (!(this->alias
479 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
480 return;
481
dfaa4860 482 if (str->type_name != sym->type_name)
2f1afb73 483 {
dfaa4860 484 if (str->type_name)
e9690142 485 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 486 else
e9690142 487 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 488 }
2f1afb73 489
df09ef2e 490
dfaa4860 491 if (str->destructor.code || sym->destructor.code)
df09ef2e 492 {
dfaa4860 493 if (str->destructor.code)
e9690142 494 symbol_destructor_set (sym, &str->destructor);
df09ef2e 495 else
e9690142 496 symbol_destructor_set (str, &sym->destructor);
df09ef2e
AD
497 }
498
dfaa4860 499 if (str->printer.code || sym->printer.code)
df09ef2e 500 {
dfaa4860 501 if (str->printer.code)
e9690142 502 symbol_printer_set (sym, &str->printer);
df09ef2e 503 else
e9690142 504 symbol_printer_set (str, &sym->printer);
df09ef2e
AD
505 }
506
dfaa4860 507 if (sym->prec || str->prec)
df09ef2e 508 {
dfaa4860 509 if (str->prec)
e9690142
JD
510 symbol_precedence_set (sym, str->prec, str->assoc,
511 str->prec_location);
df09ef2e 512 else
e9690142
JD
513 symbol_precedence_set (str, sym->prec, sym->assoc,
514 sym->prec_location);
2f1afb73 515 }
2f1afb73
AD
516}
517
0fb1efaf
PE
518static bool
519symbol_check_alias_consistency_processor (void *this,
e9690142 520 void *null ATTRIBUTE_UNUSED)
0fb1efaf 521{
df09ef2e
AD
522 symbol_check_alias_consistency (this);
523 return true;
0fb1efaf
PE
524}
525
2f1afb73
AD
526
527/*-------------------------------------------------------------------.
528| Assign a symbol number, and write the definition of the token name |
529| into FDEFINES. Put in SYMBOLS. |
530`-------------------------------------------------------------------*/
531
0fb1efaf 532static inline bool
17ee7397 533symbol_pack (symbol *this)
2f1afb73 534{
f74d6d25 535 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 536 if (this->class == nterm_sym)
f74d6d25
JD
537 this->number += ntokens;
538 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
539 return true;
2f1afb73
AD
540
541 symbols[this->number] = this;
a3714bce 542 return true;
2f1afb73
AD
543}
544
0fb1efaf
PE
545static bool
546symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
547{
548 return symbol_pack (this);
549}
550
2f1afb73 551
12cf133f
AD
552static void
553user_token_number_redeclaration (int num, symbol *first, symbol *second)
554{
555 /* User token numbers are not assigned during the parsing, but in a
83b60c97 556 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 557
83b60c97
JD
558 However, error messages make more sense if we keep the first
559 declaration first. */
12cf133f
AD
560 if (location_cmp (first->location, second->location) > 0)
561 {
562 symbol* tmp = first;
563 first = second;
564 second = tmp;
565 }
566 complain_at (second->location,
567 _("user token number %d redeclaration for %s"),
568 num, second->tag);
569 complain_at (first->location, _("previous declaration for %s"),
570 first->tag);
571}
2f1afb73
AD
572
573/*--------------------------------------------------.
574| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
575`--------------------------------------------------*/
576
0fb1efaf 577static inline bool
17ee7397 578symbol_translation (symbol *this)
2f1afb73
AD
579{
580 /* Non-terminal? */
581 if (this->class == token_sym
dfaa4860 582 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
583 {
584 /* A token which translation has already been set? */
585 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 586 user_token_number_redeclaration
12cf133f
AD
587 (this->user_token_number,
588 symbols[token_translations[this->user_token_number]],
589 this);
2f1afb73
AD
590
591 token_translations[this->user_token_number] = this->number;
592 }
593
a3714bce 594 return true;
2f1afb73
AD
595}
596
0fb1efaf
PE
597static bool
598symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
599{
600 return symbol_translation (this);
601}
602
72a23c97 603
b2a0b7ca
JD
604/*---------------------------------------.
605| Symbol and semantic type hash tables. |
606`---------------------------------------*/
40675e7c 607
b2a0b7ca 608/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
609#define HT_INITIAL_CAPACITY 257
610
db8837cb 611static struct hash_table *symbol_table = NULL;
b2a0b7ca 612static struct hash_table *semantic_type_table = NULL;
72a23c97 613
0fb1efaf 614static inline bool
17ee7397 615hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 616{
95612cfa 617 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 618 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
619}
620
b2a0b7ca
JD
621static inline bool
622hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
623{
624 /* Since names are unique, we can compare the pointers themselves. */
625 return UNIQSTR_EQ (m1->tag, m2->tag);
626}
627
0fb1efaf
PE
628static bool
629hash_symbol_comparator (void const *m1, void const *m2)
630{
631 return hash_compare_symbol (m1, m2);
632}
633
b2a0b7ca
JD
634static bool
635hash_semantic_type_comparator (void const *m1, void const *m2)
636{
637 return hash_compare_semantic_type (m1, m2);
638}
639
233a88ad
PE
640static inline size_t
641hash_symbol (const symbol *m, size_t tablesize)
72a23c97 642{
95612cfa 643 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
644 return ((uintptr_t) m->tag) % tablesize;
645}
646
b2a0b7ca
JD
647static inline size_t
648hash_semantic_type (const semantic_type *m, size_t tablesize)
649{
650 /* Since names are unique, we can hash the pointer itself. */
651 return ((uintptr_t) m->tag) % tablesize;
652}
653
233a88ad
PE
654static size_t
655hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
656{
657 return hash_symbol (m, tablesize);
72a23c97
AD
658}
659
b2a0b7ca
JD
660static size_t
661hash_semantic_type_hasher (void const *m, size_t tablesize)
662{
663 return hash_semantic_type (m, tablesize);
664}
72a23c97
AD
665
666/*-------------------------------.
2f1afb73 667| Create the symbol hash table. |
72a23c97
AD
668`-------------------------------*/
669
670void
db8837cb 671symbols_new (void)
72a23c97 672{
db8837cb 673 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
674 NULL,
675 hash_symbol_hasher,
676 hash_symbol_comparator,
677 free);
b2a0b7ca 678 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
679 NULL,
680 hash_semantic_type_hasher,
681 hash_semantic_type_comparator,
682 free);
40675e7c
DM
683}
684
685
1e9798d5
AD
686/*----------------------------------------------------------------.
687| Find the symbol named KEY, and return it. If it does not exist |
688| yet, create it. |
689`----------------------------------------------------------------*/
690
17ee7397 691symbol *
203b9274 692symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 693{
17ee7397
PE
694 symbol probe;
695 symbol *entry;
40675e7c 696
0fb1efaf 697 probe.tag = key;
db8837cb 698 entry = hash_lookup (symbol_table, &probe);
40675e7c 699
72a23c97 700 if (!entry)
40675e7c 701 {
72a23c97 702 /* First insertion in the hash. */
83b60c97 703 aver (!symbols_sorted);
17ee7397 704 entry = symbol_new (key, loc);
92d7a23a
AD
705 if (!hash_insert (symbol_table, entry))
706 xalloc_die ();
40675e7c 707 }
72a23c97
AD
708 return entry;
709}
40675e7c 710
40675e7c 711
b2a0b7ca
JD
712/*-----------------------------------------------------------------------.
713| Find the semantic type named KEY, and return it. If it does not exist |
714| yet, create it. |
715`-----------------------------------------------------------------------*/
716
717semantic_type *
718semantic_type_from_uniqstr (const uniqstr key)
719{
720 semantic_type probe;
721 semantic_type *entry;
722
723 probe.tag = key;
724 entry = hash_lookup (semantic_type_table, &probe);
725
726 if (!entry)
727 {
728 /* First insertion in the hash. */
729 entry = semantic_type_new (key);
92d7a23a
AD
730 if (!hash_insert (semantic_type_table, entry))
731 xalloc_die ();
b2a0b7ca
JD
732 }
733 return entry;
734}
735
736
203b9274
AD
737/*----------------------------------------------------------------.
738| Find the symbol named KEY, and return it. If it does not exist |
739| yet, create it. |
740`----------------------------------------------------------------*/
741
742symbol *
743symbol_get (const char *key, location loc)
744{
745 return symbol_from_uniqstr (uniqstr_new (key), loc);
746}
747
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_get (const char *key)
756{
757 return semantic_type_from_uniqstr (uniqstr_new (key));
758}
759
760
39f41916
AD
761/*------------------------------------------------------------------.
762| Generate a dummy nonterminal, whose name cannot conflict with the |
763| user's names. |
764`------------------------------------------------------------------*/
765
17ee7397
PE
766symbol *
767dummy_symbol_get (location loc)
39f41916
AD
768{
769 /* Incremented for each generated symbol. */
770 static int dummy_count = 0;
771 static char buf[256];
772
17ee7397 773 symbol *sym;
39f41916 774
f91b1629 775 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 776 sym = symbol_get (buf, loc);
39f41916
AD
777 sym->class = nterm_sym;
778 sym->number = nvars++;
779 return sym;
780}
781
4d7370cb
JD
782bool
783symbol_is_dummy (const symbol *sym)
784{
f91b1629 785 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 786}
39f41916 787
72a23c97 788/*-------------------.
db8837cb 789| Free the symbols. |
72a23c97
AD
790`-------------------*/
791
792void
db8837cb 793symbols_free (void)
72a23c97 794{
db8837cb 795 hash_free (symbol_table);
b2a0b7ca 796 hash_free (semantic_type_table);
536545f3 797 free (symbols);
83b60c97 798 free (symbols_sorted);
40675e7c
DM
799}
800
801
72a23c97 802/*---------------------------------------------------------------.
db8837cb 803| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
804| terminals. |
805`---------------------------------------------------------------*/
806
83b60c97
JD
807static int
808symbols_cmp (symbol const *a, symbol const *b)
809{
810 return strcmp (a->tag, b->tag);
811}
812
813static int
814symbols_cmp_qsort (void const *a, void const *b)
815{
816 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
817}
818
0fb1efaf
PE
819static void
820symbols_do (Hash_processor processor, void *processor_data)
40675e7c 821{
83b60c97
JD
822 size_t count = hash_get_n_entries (symbol_table);
823 if (!symbols_sorted)
824 {
825 symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
826 hash_get_entries (symbol_table, (void**)symbols_sorted, count);
827 qsort (symbols_sorted, count, sizeof *symbols_sorted,
828 symbols_cmp_qsort);
829 }
830 {
831 size_t i;
832 for (i = 0; i < count; ++i)
833 processor (symbols_sorted[i], processor_data);
834 }
40675e7c 835}
2f1afb73 836
2f1afb73
AD
837/*--------------------------------------------------------------.
838| Check that all the symbols are defined. Report any undefined |
839| symbols and consider them nonterminals. |
840`--------------------------------------------------------------*/
841
842void
843symbols_check_defined (void)
844{
0fb1efaf 845 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
846}
847
848/*------------------------------------------------------------------.
849| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
850| number. |
851`------------------------------------------------------------------*/
852
853static void
854symbols_token_translations_init (void)
855{
a3714bce 856 bool num_256_available_p = true;
2f1afb73
AD
857 int i;
858
859 /* Find the highest user token number, and whether 256, the POSIX
860 preferred user token number for the error token, is used. */
861 max_user_token_number = 0;
862 for (i = 0; i < ntokens; ++i)
863 {
17ee7397 864 symbol *this = symbols[i];
2f1afb73 865 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
866 {
867 if (this->user_token_number > max_user_token_number)
868 max_user_token_number = this->user_token_number;
869 if (this->user_token_number == 256)
870 num_256_available_p = false;
871 }
2f1afb73
AD
872 }
873
874 /* If 256 is not used, assign it to error, to follow POSIX. */
875 if (num_256_available_p
876 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
877 errtoken->user_token_number = 256;
878
879 /* Set the missing user numbers. */
880 if (max_user_token_number < 256)
881 max_user_token_number = 256;
882
883 for (i = 0; i < ntokens; ++i)
884 {
17ee7397 885 symbol *this = symbols[i];
2f1afb73 886 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 887 this->user_token_number = ++max_user_token_number;
2f1afb73 888 if (this->user_token_number > max_user_token_number)
e9690142 889 max_user_token_number = this->user_token_number;
2f1afb73
AD
890 }
891
da2a7671 892 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 893 sizeof *token_translations);
2f1afb73 894
b3a28fd4
AD
895 /* Initialize all entries for literal tokens to the internal token
896 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
897 for (i = 0; i < max_user_token_number + 1; i++)
898 token_translations[i] = undeftoken->number;
0fb1efaf 899 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
900}
901
902
903/*----------------------------------------------------------------.
904| Assign symbol numbers, and write definition of token names into |
905| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
906`----------------------------------------------------------------*/
907
908void
909symbols_pack (void)
910{
0fb1efaf 911 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
912
913 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 914 symbols_do (symbol_pack_processor, NULL);
2f1afb73 915
6d0ef4ec
JD
916 /* Aliases leave empty slots in symbols, so remove them. */
917 {
918 int writei;
919 int readi;
920 int nsyms_old = nsyms;
921 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
922 {
923 if (symbols[readi] == NULL)
924 {
925 nsyms -= 1;
926 ntokens -= 1;
927 }
928 else
929 {
930 symbols[writei] = symbols[readi];
931 symbols[writei]->number = writei;
932 if (symbols[writei]->alias)
933 symbols[writei]->alias->number = writei;
934 writei += 1;
935 }
936 }
937 }
938 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
939
2f1afb73
AD
940 symbols_token_translations_init ();
941
942 if (startsymbol->class == unknown_sym)
ee000ba4 943 fatal_at (startsymbol_location,
e9690142
JD
944 _("the start symbol %s is undefined"),
945 startsymbol->tag);
2f1afb73 946 else if (startsymbol->class == token_sym)
ee000ba4 947 fatal_at (startsymbol_location,
e9690142
JD
948 _("the start symbol %s is a token"),
949 startsymbol->tag);
2f1afb73 950}
ec5479ce
JD
951
952
12e35840
JD
953/*--------------------------------------------------.
954| Set default tagged/tagless %destructor/%printer. |
955`--------------------------------------------------*/
956
957void
95021767 958default_tagged_destructor_set (code_props const *destructor)
12e35840 959{
95021767 960 if (default_tagged_destructor.code)
12e35840 961 {
95021767
JD
962 complain_at (destructor->location,
963 _("redeclaration for default tagged %%destructor"));
964 complain_at (default_tagged_destructor.location,
e9690142 965 _("previous declaration"));
12e35840 966 }
95021767 967 default_tagged_destructor = *destructor;
12e35840
JD
968}
969
970void
95021767 971default_tagless_destructor_set (code_props const *destructor)
12e35840 972{
95021767 973 if (default_tagless_destructor.code)
12e35840 974 {
95021767
JD
975 complain_at (destructor->location,
976 _("redeclaration for default tagless %%destructor"));
977 complain_at (default_tagless_destructor.location,
e9690142 978 _("previous declaration"));
12e35840 979 }
95021767 980 default_tagless_destructor = *destructor;
12e35840 981}
ec5479ce
JD
982
983void
95021767 984default_tagged_printer_set (code_props const *printer)
ec5479ce 985{
95021767 986 if (default_tagged_printer.code)
ec5479ce 987 {
95021767
JD
988 complain_at (printer->location,
989 _("redeclaration for default tagged %%printer"));
990 complain_at (default_tagged_printer.location,
e9690142 991 _("previous declaration"));
ec5479ce 992 }
95021767 993 default_tagged_printer = *printer;
ec5479ce
JD
994}
995
996void
95021767 997default_tagless_printer_set (code_props const *printer)
ec5479ce 998{
95021767 999 if (default_tagless_printer.code)
ec5479ce 1000 {
95021767
JD
1001 complain_at (printer->location,
1002 _("redeclaration for default tagless %%printer"));
1003 complain_at (default_tagless_printer.location,
e9690142 1004 _("previous declaration"));
ec5479ce 1005 }
95021767 1006 default_tagless_printer = *printer;
ec5479ce 1007}