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