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