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