]> git.saurik.com Git - bison.git/blame - src/symtab.c
maint: prepare forthcoming changes
[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, '-'))
6fb8b256
VS
78 complain_at (loc, Wyacc,
79 _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
4f646c37 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 97 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
6fb8b256
VS
98 complain (fatal, _("too many symbols in input grammar (limit is %d)"),
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 209{
6fb8b256
VS
210 complain_at (second, complaint, _("%s redeclaration for %s"), what, s->tag);
211 complain_at (first, complaint, _("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{
6fb8b256
VS
218 complain_at (second, complaint, _("%s redeclaration for <%s>"), what, s->tag);
219 complain_at (first, complaint, _("previous declaration"));
b2a0b7ca
JD
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 335 {
6fb8b256 336 complain_at (loc, complaint, _("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)
6fb8b256 351 complain_at (loc, Wother, _("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)
6fb8b256
VS
372 complain_at (loc, complaint, _("redefining user token number of %s"),
373 sym->tag);
44536b35 374
1f6b3679 375 *user_token_numberp = user_token_number;
88bce5a2 376 /* User defined $end token? */
44536b35
AD
377 if (user_token_number == 0)
378 {
17ee7397 379 endtoken = sym;
44536b35 380 /* It is always mapped to 0, so it was already counted in
e9690142 381 NTOKENS. */
1f36f544
JD
382 if (endtoken->number != NUMBER_UNDEFINED)
383 --ntokens;
384 endtoken->number = 0;
44536b35
AD
385 }
386}
387
388
17ee7397
PE
389/*----------------------------------------------------------.
390| If SYM is not defined, report an error, and consider it a |
391| nonterminal. |
392`----------------------------------------------------------*/
2f1afb73 393
0fb1efaf 394static inline bool
17ee7397 395symbol_check_defined (symbol *sym)
2f1afb73 396{
17ee7397 397 if (sym->class == unknown_sym)
2f1afb73 398 {
3b0b682f
AD
399 switch (sym->status)
400 {
401 case used:
6fb8b256 402 complain_at (sym->location, Wother,
3b0b682f
AD
403 _("symbol %s is used, but is not defined as a token"
404 " and has no rules"),
405 sym->tag);
406 break;
407 case undeclared:
408 case needed:
6fb8b256
VS
409 complain_at (sym->location, complaint,
410 _("symbol %s is used, but is not defined as a token"
411 " and has no rules"),
412 sym->tag);
3b0b682f
AD
413 break;
414 case declared:
415 /* If declared, then sym->class != unknown_sym. */
416 assert (0);
417 }
b921d92f 418
17ee7397
PE
419 sym->class = nterm_sym;
420 sym->number = nvars++;
2f1afb73
AD
421 }
422
ea9a35c6
VS
423 for (int i = 0; i < 2; ++i)
424 if (sym->props[i].kind == CODE_PROPS_NONE && sym->type_name)
425 {
426 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
427 if (sem_type
428 && sem_type->props[i].kind != CODE_PROPS_NONE)
429 sem_type->props[i].is_used = true;
430 }
431
9641b918
VS
432 /* Set the semantic type status associated to the current symbol to
433 'declared' so that we could check semantic types unnecessary uses. */
434 if (sym->type_name)
435 {
436 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
437 if (sem_type)
438 sem_type->status = declared;
439 }
440
441 return true;
442}
443
444static inline bool
445semantic_type_check_defined (semantic_type *sem_type)
446{
ea9a35c6
VS
447 if (sem_type->status == declared)
448 {
449 for (int i = 0; i < 2; ++i)
450 if (sem_type->props[i].kind != CODE_PROPS_NONE
451 && ! sem_type->props[i].is_used)
6fb8b256 452 complain_at (sem_type->location, Wother,
ea9a35c6
VS
453 _("useless %s for type <%s>"),
454 code_props_type_string (i), sem_type->tag);
455 }
456 else
6fb8b256
VS
457 complain_at (sem_type->location, Wother,
458 _("type <%s> is used, but is not associated to any symbol"),
459 sem_type->tag);
9641b918 460
a3714bce 461 return true;
2f1afb73
AD
462}
463
0fb1efaf
PE
464static bool
465symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
466{
467 return symbol_check_defined (sym);
468}
469
9641b918
VS
470static bool
471semantic_type_check_defined_processor (void *sem_type,
472 void *null ATTRIBUTE_UNUSED)
473{
474 return semantic_type_check_defined (sem_type);
475}
476
2f1afb73 477
2f1afb73 478void
dfaa4860 479symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 480{
dfaa4860 481 if (str->alias)
6fb8b256
VS
482 complain_at (loc, Wother,
483 _("symbol %s used more than once as a literal string"), str->tag);
17ee7397 484 else if (sym->alias)
6fb8b256
VS
485 complain_at (loc, Wother,
486 _("symbol %s given more than one literal string"), sym->tag);
2f1afb73
AD
487 else
488 {
dfaa4860
JD
489 str->class = token_sym;
490 str->user_token_number = sym->user_token_number;
491 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
492 str->alias = sym;
493 sym->alias = str;
494 str->number = sym->number;
495 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
496 }
497}
498
499
500/*---------------------------------------------------------.
501| Check that THIS, and its alias, have same precedence and |
502| associativity. |
503`---------------------------------------------------------*/
504
df09ef2e 505static inline void
0fb1efaf 506symbol_check_alias_consistency (symbol *this)
2f1afb73 507{
dfaa4860 508 symbol *sym = this;
b143f404 509 symbol *str = this->alias;
df09ef2e 510
dfaa4860
JD
511 /* Check only the symbol in the symbol-string pair. */
512 if (!(this->alias
513 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
514 return;
515
dfaa4860 516 if (str->type_name != sym->type_name)
2f1afb73 517 {
dfaa4860 518 if (str->type_name)
e9690142 519 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 520 else
e9690142 521 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 522 }
2f1afb73 523
df09ef2e 524
71da68b3
VS
525 for (int i = 0; i < CODE_PROPS_SIZE; ++i)
526 if (str->props[i].code)
527 symbol_code_props_set (sym, i, &str->props[i]);
528 else if (sym->props[i].code)
529 symbol_code_props_set (str, i, &sym->props[i]);
df09ef2e 530
dfaa4860 531 if (sym->prec || str->prec)
df09ef2e 532 {
dfaa4860 533 if (str->prec)
e9690142
JD
534 symbol_precedence_set (sym, str->prec, str->assoc,
535 str->prec_location);
df09ef2e 536 else
e9690142
JD
537 symbol_precedence_set (str, sym->prec, sym->assoc,
538 sym->prec_location);
2f1afb73 539 }
2f1afb73
AD
540}
541
0fb1efaf
PE
542static bool
543symbol_check_alias_consistency_processor (void *this,
e9690142 544 void *null ATTRIBUTE_UNUSED)
0fb1efaf 545{
df09ef2e
AD
546 symbol_check_alias_consistency (this);
547 return true;
0fb1efaf
PE
548}
549
2f1afb73
AD
550
551/*-------------------------------------------------------------------.
552| Assign a symbol number, and write the definition of the token name |
553| into FDEFINES. Put in SYMBOLS. |
554`-------------------------------------------------------------------*/
555
0fb1efaf 556static inline bool
17ee7397 557symbol_pack (symbol *this)
2f1afb73 558{
f74d6d25 559 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 560 if (this->class == nterm_sym)
f74d6d25
JD
561 this->number += ntokens;
562 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
563 return true;
2f1afb73
AD
564
565 symbols[this->number] = this;
a3714bce 566 return true;
2f1afb73
AD
567}
568
0fb1efaf
PE
569static bool
570symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
571{
572 return symbol_pack (this);
573}
574
2f1afb73 575
12cf133f
AD
576static void
577user_token_number_redeclaration (int num, symbol *first, symbol *second)
578{
579 /* User token numbers are not assigned during the parsing, but in a
83b60c97 580 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 581
83b60c97
JD
582 However, error messages make more sense if we keep the first
583 declaration first. */
12cf133f
AD
584 if (location_cmp (first->location, second->location) > 0)
585 {
586 symbol* tmp = first;
587 first = second;
588 second = tmp;
589 }
6fb8b256 590 complain_at (second->location, complaint,
12cf133f
AD
591 _("user token number %d redeclaration for %s"),
592 num, second->tag);
6fb8b256 593 complain_at (first->location, complaint, _("previous declaration for %s"),
12cf133f
AD
594 first->tag);
595}
2f1afb73
AD
596
597/*--------------------------------------------------.
598| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
599`--------------------------------------------------*/
600
0fb1efaf 601static inline bool
17ee7397 602symbol_translation (symbol *this)
2f1afb73
AD
603{
604 /* Non-terminal? */
605 if (this->class == token_sym
dfaa4860 606 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
607 {
608 /* A token which translation has already been set? */
609 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 610 user_token_number_redeclaration
12cf133f
AD
611 (this->user_token_number,
612 symbols[token_translations[this->user_token_number]],
613 this);
6fb8b256 614
2f1afb73
AD
615 token_translations[this->user_token_number] = this->number;
616 }
6fb8b256 617
a3714bce 618 return true;
2f1afb73
AD
619}
620
0fb1efaf
PE
621static bool
622symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
623{
624 return symbol_translation (this);
625}
626
72a23c97 627
b2a0b7ca
JD
628/*---------------------------------------.
629| Symbol and semantic type hash tables. |
630`---------------------------------------*/
40675e7c 631
b2a0b7ca 632/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
633#define HT_INITIAL_CAPACITY 257
634
db8837cb 635static struct hash_table *symbol_table = NULL;
b2a0b7ca 636static struct hash_table *semantic_type_table = NULL;
72a23c97 637
0fb1efaf 638static inline bool
17ee7397 639hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 640{
95612cfa 641 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 642 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
643}
644
b2a0b7ca
JD
645static inline bool
646hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
647{
648 /* Since names are unique, we can compare the pointers themselves. */
649 return UNIQSTR_EQ (m1->tag, m2->tag);
650}
651
0fb1efaf
PE
652static bool
653hash_symbol_comparator (void const *m1, void const *m2)
654{
655 return hash_compare_symbol (m1, m2);
656}
657
b2a0b7ca
JD
658static bool
659hash_semantic_type_comparator (void const *m1, void const *m2)
660{
661 return hash_compare_semantic_type (m1, m2);
662}
663
233a88ad
PE
664static inline size_t
665hash_symbol (const symbol *m, size_t tablesize)
72a23c97 666{
95612cfa 667 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
668 return ((uintptr_t) m->tag) % tablesize;
669}
670
b2a0b7ca
JD
671static inline size_t
672hash_semantic_type (const semantic_type *m, size_t tablesize)
673{
674 /* Since names are unique, we can hash the pointer itself. */
675 return ((uintptr_t) m->tag) % tablesize;
676}
677
233a88ad
PE
678static size_t
679hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
680{
681 return hash_symbol (m, tablesize);
72a23c97
AD
682}
683
b2a0b7ca
JD
684static size_t
685hash_semantic_type_hasher (void const *m, size_t tablesize)
686{
687 return hash_semantic_type (m, tablesize);
688}
72a23c97
AD
689
690/*-------------------------------.
2f1afb73 691| Create the symbol hash table. |
72a23c97
AD
692`-------------------------------*/
693
694void
db8837cb 695symbols_new (void)
72a23c97 696{
db8837cb 697 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
698 NULL,
699 hash_symbol_hasher,
700 hash_symbol_comparator,
701 free);
b2a0b7ca 702 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
703 NULL,
704 hash_semantic_type_hasher,
705 hash_semantic_type_comparator,
706 free);
40675e7c
DM
707}
708
709
1e9798d5
AD
710/*----------------------------------------------------------------.
711| Find the symbol named KEY, and return it. If it does not exist |
712| yet, create it. |
713`----------------------------------------------------------------*/
714
17ee7397 715symbol *
203b9274 716symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 717{
17ee7397
PE
718 symbol probe;
719 symbol *entry;
40675e7c 720
0fb1efaf 721 probe.tag = key;
db8837cb 722 entry = hash_lookup (symbol_table, &probe);
40675e7c 723
72a23c97 724 if (!entry)
40675e7c 725 {
72a23c97 726 /* First insertion in the hash. */
83b60c97 727 aver (!symbols_sorted);
17ee7397 728 entry = symbol_new (key, loc);
92d7a23a
AD
729 if (!hash_insert (symbol_table, entry))
730 xalloc_die ();
40675e7c 731 }
72a23c97
AD
732 return entry;
733}
40675e7c 734
40675e7c 735
b2a0b7ca
JD
736/*-----------------------------------------------------------------------.
737| Find the semantic type named KEY, and return it. If it does not exist |
738| yet, create it. |
739`-----------------------------------------------------------------------*/
740
741semantic_type *
9641b918 742semantic_type_from_uniqstr (const uniqstr key, const location *loc)
b2a0b7ca
JD
743{
744 semantic_type probe;
745 semantic_type *entry;
746
747 probe.tag = key;
748 entry = hash_lookup (semantic_type_table, &probe);
749
750 if (!entry)
751 {
752 /* First insertion in the hash. */
9641b918 753 entry = semantic_type_new (key, loc);
92d7a23a
AD
754 if (!hash_insert (semantic_type_table, entry))
755 xalloc_die ();
b2a0b7ca
JD
756 }
757 return entry;
758}
759
760
203b9274
AD
761/*----------------------------------------------------------------.
762| Find the symbol named KEY, and return it. If it does not exist |
763| yet, create it. |
764`----------------------------------------------------------------*/
765
766symbol *
767symbol_get (const char *key, location loc)
768{
769 return symbol_from_uniqstr (uniqstr_new (key), loc);
770}
771
772
b2a0b7ca
JD
773/*-----------------------------------------------------------------------.
774| Find the semantic type named KEY, and return it. If it does not exist |
775| yet, create it. |
776`-----------------------------------------------------------------------*/
777
778semantic_type *
9641b918 779semantic_type_get (const char *key, const location *loc)
b2a0b7ca 780{
9641b918 781 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
b2a0b7ca
JD
782}
783
784
39f41916
AD
785/*------------------------------------------------------------------.
786| Generate a dummy nonterminal, whose name cannot conflict with the |
787| user's names. |
788`------------------------------------------------------------------*/
789
17ee7397
PE
790symbol *
791dummy_symbol_get (location loc)
39f41916
AD
792{
793 /* Incremented for each generated symbol. */
794 static int dummy_count = 0;
795 static char buf[256];
796
17ee7397 797 symbol *sym;
39f41916 798
f91b1629 799 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 800 sym = symbol_get (buf, loc);
39f41916
AD
801 sym->class = nterm_sym;
802 sym->number = nvars++;
803 return sym;
804}
805
4d7370cb
JD
806bool
807symbol_is_dummy (const symbol *sym)
808{
f91b1629 809 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 810}
39f41916 811
72a23c97 812/*-------------------.
db8837cb 813| Free the symbols. |
72a23c97
AD
814`-------------------*/
815
816void
db8837cb 817symbols_free (void)
72a23c97 818{
db8837cb 819 hash_free (symbol_table);
b2a0b7ca 820 hash_free (semantic_type_table);
536545f3 821 free (symbols);
83b60c97 822 free (symbols_sorted);
40675e7c
DM
823}
824
825
72a23c97 826/*---------------------------------------------------------------.
db8837cb 827| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
828| terminals. |
829`---------------------------------------------------------------*/
830
83b60c97
JD
831static int
832symbols_cmp (symbol const *a, symbol const *b)
833{
834 return strcmp (a->tag, b->tag);
835}
836
837static int
838symbols_cmp_qsort (void const *a, void const *b)
839{
840 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
841}
842
0fb1efaf 843static void
dfe292c6
VS
844symbols_do (Hash_processor processor, void *processor_data,
845 struct hash_table *table, symbol **sorted)
40675e7c 846{
dfe292c6
VS
847 size_t count = hash_get_n_entries (table);
848 if (!sorted)
83b60c97 849 {
dfe292c6
VS
850 sorted = xnmalloc (count, sizeof *sorted);
851 hash_get_entries (table, (void**)sorted, count);
852 qsort (sorted, count, sizeof *sorted, symbols_cmp_qsort);
83b60c97
JD
853 }
854 {
855 size_t i;
856 for (i = 0; i < count; ++i)
dfe292c6 857 processor (sorted[i], processor_data);
83b60c97 858 }
40675e7c 859}
2f1afb73 860
2f1afb73
AD
861/*--------------------------------------------------------------.
862| Check that all the symbols are defined. Report any undefined |
863| symbols and consider them nonterminals. |
864`--------------------------------------------------------------*/
865
866void
867symbols_check_defined (void)
868{
dfe292c6
VS
869 symbols_do (symbol_check_defined_processor, NULL,
870 symbol_table, symbols_sorted);
9641b918
VS
871 symbols_do (semantic_type_check_defined_processor, NULL,
872 semantic_type_table, semantic_types_sorted);
2f1afb73
AD
873}
874
875/*------------------------------------------------------------------.
876| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
877| number. |
878`------------------------------------------------------------------*/
879
880static void
881symbols_token_translations_init (void)
882{
a3714bce 883 bool num_256_available_p = true;
2f1afb73
AD
884 int i;
885
886 /* Find the highest user token number, and whether 256, the POSIX
887 preferred user token number for the error token, is used. */
888 max_user_token_number = 0;
889 for (i = 0; i < ntokens; ++i)
890 {
17ee7397 891 symbol *this = symbols[i];
2f1afb73 892 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
893 {
894 if (this->user_token_number > max_user_token_number)
895 max_user_token_number = this->user_token_number;
896 if (this->user_token_number == 256)
897 num_256_available_p = false;
898 }
2f1afb73
AD
899 }
900
901 /* If 256 is not used, assign it to error, to follow POSIX. */
902 if (num_256_available_p
903 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
904 errtoken->user_token_number = 256;
905
906 /* Set the missing user numbers. */
907 if (max_user_token_number < 256)
908 max_user_token_number = 256;
909
910 for (i = 0; i < ntokens; ++i)
911 {
17ee7397 912 symbol *this = symbols[i];
2f1afb73 913 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 914 this->user_token_number = ++max_user_token_number;
2f1afb73 915 if (this->user_token_number > max_user_token_number)
e9690142 916 max_user_token_number = this->user_token_number;
2f1afb73
AD
917 }
918
da2a7671 919 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 920 sizeof *token_translations);
2f1afb73 921
b3a28fd4
AD
922 /* Initialize all entries for literal tokens to the internal token
923 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
924 for (i = 0; i < max_user_token_number + 1; i++)
925 token_translations[i] = undeftoken->number;
dfe292c6
VS
926 symbols_do (symbol_translation_processor, NULL,
927 symbol_table, symbols_sorted);
2f1afb73
AD
928}
929
930
931/*----------------------------------------------------------------.
932| Assign symbol numbers, and write definition of token names into |
933| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
934`----------------------------------------------------------------*/
935
936void
937symbols_pack (void)
938{
dfe292c6
VS
939 symbols_do (symbol_check_alias_consistency_processor, NULL,
940 symbol_table, symbols_sorted);
6d0ef4ec
JD
941
942 symbols = xcalloc (nsyms, sizeof *symbols);
dfe292c6 943 symbols_do (symbol_pack_processor, NULL, symbol_table, symbols_sorted);
2f1afb73 944
6d0ef4ec
JD
945 /* Aliases leave empty slots in symbols, so remove them. */
946 {
947 int writei;
948 int readi;
949 int nsyms_old = nsyms;
950 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
951 {
952 if (symbols[readi] == NULL)
953 {
954 nsyms -= 1;
955 ntokens -= 1;
956 }
957 else
958 {
959 symbols[writei] = symbols[readi];
960 symbols[writei]->number = writei;
961 if (symbols[writei]->alias)
962 symbols[writei]->alias->number = writei;
963 writei += 1;
964 }
965 }
966 }
967 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
968
2f1afb73
AD
969 symbols_token_translations_init ();
970
971 if (startsymbol->class == unknown_sym)
6fb8b256
VS
972 complain_at (startsymbol_location, fatal,
973 _("the start symbol %s is undefined"),
974 startsymbol->tag);
2f1afb73 975 else if (startsymbol->class == token_sym)
6fb8b256
VS
976 complain_at (startsymbol_location, fatal,
977 _("the start symbol %s is a token"),
978 startsymbol->tag);
2f1afb73 979}
ec5479ce
JD
980
981
12e35840
JD
982/*--------------------------------------------------.
983| Set default tagged/tagless %destructor/%printer. |
984`--------------------------------------------------*/
985
986void
71da68b3 987default_tagged_code_props_set (code_props_type kind, code_props const *code)
12e35840 988{
71da68b3 989 if (default_tagged_code_props[kind].code)
12e35840 990 {
6fb8b256 991 complain_at (code->location, complaint,
71da68b3
VS
992 _("redeclaration for default tagged %s"),
993 code_props_type_string (kind));
6fb8b256 994 complain_at (default_tagged_code_props[kind].location, complaint,
e9690142 995 _("previous declaration"));
12e35840 996 }
71da68b3 997 default_tagged_code_props[kind] = *code;
12e35840 998}
ec5479ce
JD
999
1000void
71da68b3 1001default_tagless_code_props_set (code_props_type kind, code_props const *code)
ec5479ce 1002{
71da68b3 1003 if (default_tagless_code_props[kind].code)
ec5479ce 1004 {
6fb8b256 1005 complain_at (code->location, complaint,
71da68b3
VS
1006 _("redeclaration for default tagless %s"),
1007 code_props_type_string (kind));
6fb8b256 1008 complain_at (default_tagless_code_props[kind].location, complaint,
e9690142 1009 _("previous declaration"));
ec5479ce 1010 }
71da68b3 1011 default_tagless_code_props[kind] = *code;
ec5479ce 1012}