]> git.saurik.com Git - bison.git/blame - src/symtab.c
tests: address syntax-check failures
[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, '-'))
bb8e56ff
TR
64 complain (&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)
bb8e56ff 84 complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
6fb8b256 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;
e96b1b2c
TR
114 res->location = loc ? *loc : empty_location;
115 res->status = undeclared;
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;
b999409e
TR
197 complain_indent (&second, complaint, &i,
198 _("%s redeclaration for %s"), what, s->tag);
cbaea010 199 i += SUB_INDENT;
b999409e
TR
200 complain_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;
b999409e
TR
209 complain_indent (&second, complaint, &i,
210 _("%s redeclaration for <%s>"), what, s->tag);
cbaea010 211 i += SUB_INDENT;
b999409e
TR
212 complain_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 {
bb8e56ff 331 complain (&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)
bb8e56ff 346 complain (&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)
bb8e56ff
TR
367 complain (&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 394 assert (sym->status != declared);
bb8e56ff
TR
395 complain (&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)
bb8e56ff
TR
430 complain (&sem_type->location, Wother,
431 _("useless %s for type <%s>"),
432 code_props_type_string (i), sem_type->tag);
ea9a35c6
VS
433 }
434 else
bb8e56ff
TR
435 complain (&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)
bb8e56ff 460 complain (&loc, Wother,
6fb8b256 461 _("symbol %s used more than once as a literal string"), str->tag);
17ee7397 462 else if (sym->alias)
bb8e56ff 463 complain (&loc, Wother,
6fb8b256 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 }
b999409e
TR
569 complain_indent (&second->location, complaint, &i,
570 _("user token number %d redeclaration for %s"),
571 num, second->tag);
b506d9bf 572 i += SUB_INDENT;
b999409e
TR
573 complain_indent (&first->location, complaint, &i,
574 _("previous declaration for %s"),
575 first->tag);
12cf133f 576}
2f1afb73
AD
577
578/*--------------------------------------------------.
579| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
580`--------------------------------------------------*/
581
0fb1efaf 582static inline bool
17ee7397 583symbol_translation (symbol *this)
2f1afb73
AD
584{
585 /* Non-terminal? */
586 if (this->class == token_sym
dfaa4860 587 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
588 {
589 /* A token which translation has already been set? */
590 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 591 user_token_number_redeclaration
12cf133f
AD
592 (this->user_token_number,
593 symbols[token_translations[this->user_token_number]],
594 this);
9553083c 595
2f1afb73
AD
596 token_translations[this->user_token_number] = this->number;
597 }
9553083c 598
a3714bce 599 return true;
2f1afb73
AD
600}
601
0fb1efaf
PE
602static bool
603symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
604{
605 return symbol_translation (this);
606}
607
72a23c97 608
b2a0b7ca
JD
609/*---------------------------------------.
610| Symbol and semantic type hash tables. |
611`---------------------------------------*/
40675e7c 612
b2a0b7ca 613/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
614#define HT_INITIAL_CAPACITY 257
615
db8837cb 616static struct hash_table *symbol_table = NULL;
b2a0b7ca 617static struct hash_table *semantic_type_table = NULL;
72a23c97 618
0fb1efaf 619static inline bool
17ee7397 620hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 621{
95612cfa 622 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 623 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
624}
625
b2a0b7ca
JD
626static inline bool
627hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
628{
629 /* Since names are unique, we can compare the pointers themselves. */
630 return UNIQSTR_EQ (m1->tag, m2->tag);
631}
632
0fb1efaf
PE
633static bool
634hash_symbol_comparator (void const *m1, void const *m2)
635{
636 return hash_compare_symbol (m1, m2);
637}
638
b2a0b7ca
JD
639static bool
640hash_semantic_type_comparator (void const *m1, void const *m2)
641{
642 return hash_compare_semantic_type (m1, m2);
643}
644
233a88ad
PE
645static inline size_t
646hash_symbol (const symbol *m, size_t tablesize)
72a23c97 647{
95612cfa 648 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
649 return ((uintptr_t) m->tag) % tablesize;
650}
651
b2a0b7ca
JD
652static inline size_t
653hash_semantic_type (const semantic_type *m, size_t tablesize)
654{
655 /* Since names are unique, we can hash the pointer itself. */
656 return ((uintptr_t) m->tag) % tablesize;
657}
658
233a88ad
PE
659static size_t
660hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
661{
662 return hash_symbol (m, tablesize);
72a23c97
AD
663}
664
b2a0b7ca
JD
665static size_t
666hash_semantic_type_hasher (void const *m, size_t tablesize)
667{
668 return hash_semantic_type (m, tablesize);
669}
72a23c97
AD
670
671/*-------------------------------.
2f1afb73 672| Create the symbol hash table. |
72a23c97
AD
673`-------------------------------*/
674
675void
db8837cb 676symbols_new (void)
72a23c97 677{
db8837cb 678 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
679 NULL,
680 hash_symbol_hasher,
681 hash_symbol_comparator,
682 free);
b2a0b7ca 683 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
684 NULL,
685 hash_semantic_type_hasher,
686 hash_semantic_type_comparator,
687 free);
40675e7c
DM
688}
689
690
1e9798d5
AD
691/*----------------------------------------------------------------.
692| Find the symbol named KEY, and return it. If it does not exist |
693| yet, create it. |
694`----------------------------------------------------------------*/
695
17ee7397 696symbol *
203b9274 697symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 698{
17ee7397
PE
699 symbol probe;
700 symbol *entry;
40675e7c 701
0fb1efaf 702 probe.tag = key;
db8837cb 703 entry = hash_lookup (symbol_table, &probe);
40675e7c 704
72a23c97 705 if (!entry)
40675e7c 706 {
72a23c97 707 /* First insertion in the hash. */
83b60c97 708 aver (!symbols_sorted);
17ee7397 709 entry = symbol_new (key, loc);
92d7a23a
AD
710 if (!hash_insert (symbol_table, entry))
711 xalloc_die ();
40675e7c 712 }
72a23c97
AD
713 return entry;
714}
40675e7c 715
40675e7c 716
b2a0b7ca
JD
717/*-----------------------------------------------------------------------.
718| Find the semantic type named KEY, and return it. If it does not exist |
719| yet, create it. |
720`-----------------------------------------------------------------------*/
721
722semantic_type *
9641b918 723semantic_type_from_uniqstr (const uniqstr key, const location *loc)
b2a0b7ca
JD
724{
725 semantic_type probe;
726 semantic_type *entry;
727
728 probe.tag = key;
729 entry = hash_lookup (semantic_type_table, &probe);
730
731 if (!entry)
732 {
733 /* First insertion in the hash. */
9641b918 734 entry = semantic_type_new (key, loc);
92d7a23a
AD
735 if (!hash_insert (semantic_type_table, entry))
736 xalloc_die ();
b2a0b7ca
JD
737 }
738 return entry;
739}
740
741
203b9274
AD
742/*----------------------------------------------------------------.
743| Find the symbol named KEY, and return it. If it does not exist |
744| yet, create it. |
745`----------------------------------------------------------------*/
746
747symbol *
748symbol_get (const char *key, location loc)
749{
750 return symbol_from_uniqstr (uniqstr_new (key), loc);
751}
752
753
b2a0b7ca
JD
754/*-----------------------------------------------------------------------.
755| Find the semantic type named KEY, and return it. If it does not exist |
756| yet, create it. |
757`-----------------------------------------------------------------------*/
758
759semantic_type *
9641b918 760semantic_type_get (const char *key, const location *loc)
b2a0b7ca 761{
9641b918 762 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
b2a0b7ca
JD
763}
764
765
39f41916
AD
766/*------------------------------------------------------------------.
767| Generate a dummy nonterminal, whose name cannot conflict with the |
768| user's names. |
769`------------------------------------------------------------------*/
770
17ee7397
PE
771symbol *
772dummy_symbol_get (location loc)
39f41916
AD
773{
774 /* Incremented for each generated symbol. */
775 static int dummy_count = 0;
776 static char buf[256];
777
17ee7397 778 symbol *sym;
39f41916 779
f91b1629 780 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 781 sym = symbol_get (buf, loc);
39f41916
AD
782 sym->class = nterm_sym;
783 sym->number = nvars++;
784 return sym;
785}
786
4d7370cb
JD
787bool
788symbol_is_dummy (const symbol *sym)
789{
f91b1629 790 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 791}
39f41916 792
72a23c97 793/*-------------------.
db8837cb 794| Free the symbols. |
72a23c97
AD
795`-------------------*/
796
797void
db8837cb 798symbols_free (void)
72a23c97 799{
db8837cb 800 hash_free (symbol_table);
b2a0b7ca 801 hash_free (semantic_type_table);
536545f3 802 free (symbols);
83b60c97 803 free (symbols_sorted);
ae9c90ba 804 free (semantic_types_sorted);
40675e7c
DM
805}
806
807
72a23c97 808/*---------------------------------------------------------------.
db8837cb 809| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
810| terminals. |
811`---------------------------------------------------------------*/
812
83b60c97
JD
813static int
814symbols_cmp (symbol const *a, symbol const *b)
815{
816 return strcmp (a->tag, b->tag);
817}
818
819static int
820symbols_cmp_qsort (void const *a, void const *b)
821{
822 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
823}
824
0fb1efaf 825static void
dfe292c6 826symbols_do (Hash_processor processor, void *processor_data,
ae9c90ba 827 struct hash_table *table, symbol ***sorted)
40675e7c 828{
dfe292c6 829 size_t count = hash_get_n_entries (table);
ae9c90ba 830 if (!*sorted)
83b60c97 831 {
ae9c90ba
TR
832 *sorted = xnmalloc (count, sizeof **sorted);
833 hash_get_entries (table, (void**)*sorted, count);
834 qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
83b60c97
JD
835 }
836 {
837 size_t i;
838 for (i = 0; i < count; ++i)
ae9c90ba 839 processor ((*sorted)[i], processor_data);
83b60c97 840 }
40675e7c 841}
2f1afb73 842
2f1afb73
AD
843/*--------------------------------------------------------------.
844| Check that all the symbols are defined. Report any undefined |
845| symbols and consider them nonterminals. |
846`--------------------------------------------------------------*/
847
848void
849symbols_check_defined (void)
850{
dfe292c6 851 symbols_do (symbol_check_defined_processor, NULL,
ae9c90ba 852 symbol_table, &symbols_sorted);
9641b918 853 symbols_do (semantic_type_check_defined_processor, NULL,
ae9c90ba 854 semantic_type_table, &semantic_types_sorted);
2f1afb73
AD
855}
856
857/*------------------------------------------------------------------.
858| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
859| number. |
860`------------------------------------------------------------------*/
861
862static void
863symbols_token_translations_init (void)
864{
a3714bce 865 bool num_256_available_p = true;
2f1afb73
AD
866 int i;
867
868 /* Find the highest user token number, and whether 256, the POSIX
869 preferred user token number for the error token, is used. */
870 max_user_token_number = 0;
871 for (i = 0; i < ntokens; ++i)
872 {
17ee7397 873 symbol *this = symbols[i];
2f1afb73 874 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
875 {
876 if (this->user_token_number > max_user_token_number)
877 max_user_token_number = this->user_token_number;
878 if (this->user_token_number == 256)
879 num_256_available_p = false;
880 }
2f1afb73
AD
881 }
882
883 /* If 256 is not used, assign it to error, to follow POSIX. */
884 if (num_256_available_p
885 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
886 errtoken->user_token_number = 256;
887
888 /* Set the missing user numbers. */
889 if (max_user_token_number < 256)
890 max_user_token_number = 256;
891
892 for (i = 0; i < ntokens; ++i)
893 {
17ee7397 894 symbol *this = symbols[i];
2f1afb73 895 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 896 this->user_token_number = ++max_user_token_number;
2f1afb73 897 if (this->user_token_number > max_user_token_number)
e9690142 898 max_user_token_number = this->user_token_number;
2f1afb73
AD
899 }
900
da2a7671 901 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 902 sizeof *token_translations);
2f1afb73 903
b3a28fd4
AD
904 /* Initialize all entries for literal tokens to the internal token
905 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
906 for (i = 0; i < max_user_token_number + 1; i++)
907 token_translations[i] = undeftoken->number;
dfe292c6 908 symbols_do (symbol_translation_processor, NULL,
ae9c90ba 909 symbol_table, &symbols_sorted);
2f1afb73
AD
910}
911
912
913/*----------------------------------------------------------------.
914| Assign symbol numbers, and write definition of token names into |
915| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
916`----------------------------------------------------------------*/
917
918void
919symbols_pack (void)
920{
dfe292c6 921 symbols_do (symbol_check_alias_consistency_processor, NULL,
ae9c90ba 922 symbol_table, &symbols_sorted);
6d0ef4ec
JD
923
924 symbols = xcalloc (nsyms, sizeof *symbols);
ae9c90ba 925 symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
2f1afb73 926
6d0ef4ec
JD
927 /* Aliases leave empty slots in symbols, so remove them. */
928 {
929 int writei;
930 int readi;
931 int nsyms_old = nsyms;
932 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
933 {
934 if (symbols[readi] == NULL)
935 {
936 nsyms -= 1;
937 ntokens -= 1;
938 }
939 else
940 {
941 symbols[writei] = symbols[readi];
942 symbols[writei]->number = writei;
943 if (symbols[writei]->alias)
944 symbols[writei]->alias->number = writei;
945 writei += 1;
946 }
947 }
948 }
949 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
950
2f1afb73
AD
951 symbols_token_translations_init ();
952
953 if (startsymbol->class == unknown_sym)
bb8e56ff
TR
954 complain (&startsymbol_location, fatal,
955 _("the start symbol %s is undefined"),
956 startsymbol->tag);
2f1afb73 957 else if (startsymbol->class == token_sym)
bb8e56ff
TR
958 complain (&startsymbol_location, fatal,
959 _("the start symbol %s is a token"),
960 startsymbol->tag);
2f1afb73 961}