]> git.saurik.com Git - bison.git/blame - src/symtab.c
Redo some of the previous commit: add back the ability to use
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
073f9288
PE
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006 Free
4 Software Foundation, Inc.
40675e7c 5
95e36146 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
95e36146
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
40675e7c 12
95e36146
AD
13 Bison is distributed in the hope that it will be useful,
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
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
40675e7c 22
2cec9080 23#include <config.h>
40675e7c 24#include "system.h"
17ee7397
PE
25
26#include <hash.h>
27#include <quotearg.h>
28
2f1afb73 29#include "complain.h"
40675e7c 30#include "gram.h"
17ee7397 31#include "symtab.h"
40675e7c 32
2f1afb73
AD
33/*------------------------.
34| Distinguished symbols. |
35`------------------------*/
36
17ee7397
PE
37symbol *errtoken = NULL;
38symbol *undeftoken = NULL;
39symbol *endtoken = NULL;
40symbol *accept = NULL;
41symbol *startsymbol = NULL;
42location startsymbol_location;
2f1afb73 43
ec5479ce
JD
44/*-----------------------------------.
45| Default %destructor and %printer. |
46`-----------------------------------*/
47
48static const char *default_destructor = NULL;
49static location default_destructor_location;
50static const char *default_printer = NULL;
51static location default_printer_location;
52
72a23c97
AD
53/*---------------------------------.
54| Create a new symbol, named TAG. |
55`---------------------------------*/
1e9798d5 56
17ee7397
PE
57static symbol *
58symbol_new (uniqstr tag, location loc)
1e9798d5 59{
da2a7671 60 symbol *res = xmalloc (sizeof *res);
1e9798d5 61
17ee7397 62 uniqstr_assert (tag);
95612cfa 63 res->tag = tag;
17ee7397 64 res->location = loc;
24c0aad7 65
1e9798d5 66 res->type_name = NULL;
9280d3ef 67 res->destructor = NULL;
260008e5 68 res->printer = NULL;
24c0aad7 69
5fbb0954 70 res->number = NUMBER_UNDEFINED;
1e9798d5 71 res->prec = 0;
a945ec39 72 res->assoc = undef_assoc;
b87f8b21 73 res->user_token_number = USER_NUMBER_UNDEFINED;
260008e5 74
1e9798d5
AD
75 res->alias = NULL;
76 res->class = unknown_sym;
073f9288 77 res->declared = false;
1e9798d5 78
3239db74
PE
79 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
80 fatal (_("too many symbols in input grammar (limit is %d)"),
81 SYMBOL_NUMBER_MAXIMUM);
6d0ef4ec 82 nsyms++;
1e9798d5
AD
83 return res;
84}
85
40675e7c 86
867a3e00
AD
87/*-----------------.
88| Print a symbol. |
89`-----------------*/
90
91#define SYMBOL_ATTR_PRINT(Attr) \
92 if (s->Attr) \
ab703f2c 93 fprintf (f, " %s { %s }", #Attr, s->Attr)
867a3e00
AD
94
95void
22dda0f0 96symbol_print (symbol *s, FILE *f)
867a3e00 97{
affac613
AD
98 if (s)
99 {
100 fprintf (f, "\"%s\"", s->tag);
101 SYMBOL_ATTR_PRINT (type_name);
102 SYMBOL_ATTR_PRINT (destructor);
103 SYMBOL_ATTR_PRINT (printer);
104 }
105 else
106 fprintf (f, "<NULL>");
867a3e00
AD
107}
108
109#undef SYMBOL_ATTR_PRINT
110
df09ef2e
AD
111/*------------------------------------------------------------------.
112| Complain that S's WHAT is redeclared at SECOND, and was first set |
113| at FIRST. |
114`------------------------------------------------------------------*/
115
116static void
117redeclaration (symbol* s, const char *what, location first, location second)
118{
119 complain_at (second, _("%s redeclaration for %s"), what, s->tag);
dd60572a 120 complain_at (first, _("previous declaration"));
df09ef2e
AD
121}
122
123
17ee7397
PE
124/*-----------------------------------------------------------------.
125| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
126| as TYPE_NAME. |
127`-----------------------------------------------------------------*/
3ae2b51f
AD
128
129void
17ee7397 130symbol_type_set (symbol *sym, uniqstr type_name, location loc)
3ae2b51f 131{
e9955c83
AD
132 if (type_name)
133 {
17ee7397 134 if (sym->type_name)
df09ef2e 135 redeclaration (sym, "%type", sym->type_location, loc);
17ee7397
PE
136 uniqstr_assert (type_name);
137 sym->type_name = type_name;
df09ef2e 138 sym->type_location = loc;
e9955c83 139 }
3ae2b51f
AD
140}
141
142
17ee7397
PE
143/*------------------------------------------------------------------.
144| Set the DESTRUCTOR associated with SYM. Do nothing if passed 0. |
145`------------------------------------------------------------------*/
9280d3ef
AD
146
147void
c1432f65 148symbol_destructor_set (symbol *sym, const char *destructor, location loc)
9280d3ef
AD
149{
150 if (destructor)
151 {
17ee7397 152 if (sym->destructor)
df09ef2e 153 redeclaration (sym, "%destructor", sym->destructor_location, loc);
17ee7397
PE
154 sym->destructor = destructor;
155 sym->destructor_location = loc;
9280d3ef
AD
156 }
157}
158
ec5479ce
JD
159/*---------------------------------------.
160| Get the computed %destructor for SYM. |
161`---------------------------------------*/
162
163const char *
164symbol_destructor_get (symbol *sym)
165{
166 /* Token 0 cannot have a %destructor unless the user renames it. */
167 if (UNIQSTR_EQ (sym->tag, uniqstr_new ("$end")))
168 return NULL;
169
170 if (sym->destructor != NULL)
171 return sym->destructor;
172 return default_destructor;
173}
174
175/*---------------------------------------------------------------.
176| Get the grammar location of the %destructor computed for SYM. |
177`---------------------------------------------------------------*/
178
179location
180symbol_destructor_location_get (symbol *sym)
181{
182 if (sym->destructor != NULL)
183 return sym->destructor_location;
184 return default_destructor_location;
185}
9280d3ef 186
17ee7397
PE
187/*---------------------------------------------------------------.
188| Set the PRINTER associated with SYM. Do nothing if passed 0. |
189`---------------------------------------------------------------*/
366eea36
AD
190
191void
c1432f65 192symbol_printer_set (symbol *sym, const char *printer, location loc)
366eea36
AD
193{
194 if (printer)
195 {
17ee7397 196 if (sym->printer)
31b2b07e 197 redeclaration (sym, "%printer", sym->printer_location, loc);
17ee7397
PE
198 sym->printer = printer;
199 sym->printer_location = loc;
366eea36
AD
200 }
201}
202
ec5479ce
JD
203/*------------------------------------.
204| Get the computed %printer for SYM. |
205`------------------------------------*/
206
207const char *
208symbol_printer_get (symbol *sym)
209{
210 /* Token 0 cannot have a %printer unless the user renames it. */
211 if (UNIQSTR_EQ (sym->tag, uniqstr_new ("$end")))
212 return NULL;
213
214 if (sym->printer != NULL)
215 return sym->printer;
216 return default_printer;
217}
218
219/*------------------------------------------------------------.
220| Get the grammar location of the %printer computed for SYM. |
221`------------------------------------------------------------*/
222
223location
224symbol_printer_location_get (symbol *sym)
225{
226 if (sym->printer != NULL)
227 return sym->printer_location;
228 return default_printer_location;
229}
230
366eea36 231
17ee7397
PE
232/*-----------------------------------------------------------------.
233| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
234| with UNDEF_ASSOC as ASSOC. |
235`-----------------------------------------------------------------*/
3ae2b51f
AD
236
237void
17ee7397 238symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 239{
17ee7397 240 if (a != undef_assoc)
e9955c83 241 {
17ee7397 242 if (sym->prec != 0)
df09ef2e 243 redeclaration (sym, assoc_to_string (a), sym->prec_location, loc);
17ee7397
PE
244 sym->prec = prec;
245 sym->assoc = a;
df09ef2e 246 sym->prec_location = loc;
e9955c83
AD
247 }
248
249 /* Only terminals have a precedence. */
073f9288 250 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
251}
252
253
17ee7397
PE
254/*------------------------------------.
255| Set the CLASS associated with SYM. |
256`------------------------------------*/
44536b35
AD
257
258void
073f9288 259symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 260{
17ee7397 261 if (sym->class != unknown_sym && sym->class != class)
073f9288
PE
262 {
263 complain_at (loc, _("symbol %s redefined"), sym->tag);
264 sym->declared = false;
265 }
44536b35 266
17ee7397
PE
267 if (class == nterm_sym && sym->class != nterm_sym)
268 sym->number = nvars++;
6d0ef4ec 269 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
17ee7397 270 sym->number = ntokens++;
44536b35 271
17ee7397 272 sym->class = class;
073f9288
PE
273
274 if (declaring)
275 {
276 if (sym->declared)
277 warn_at (loc, _("symbol %s redeclared"), sym->tag);
278 sym->declared = true;
279 }
44536b35
AD
280}
281
282
17ee7397
PE
283/*------------------------------------------------.
284| Set the USER_TOKEN_NUMBER associated with SYM. |
285`------------------------------------------------*/
44536b35
AD
286
287void
17ee7397 288symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 289{
1f6b3679
JD
290 int *user_token_numberp;
291
68cae94e 292 assert (sym->class == token_sym);
44536b35 293
1f6b3679
JD
294 if (sym->user_token_number != USER_NUMBER_ALIAS)
295 user_token_numberp = &sym->user_token_number;
296 else
297 user_token_numberp = &sym->alias->user_token_number;
298 if (*user_token_numberp != USER_NUMBER_UNDEFINED
299 && *user_token_numberp != user_token_number)
17ee7397 300 complain_at (loc, _("redefining user token number of %s"), sym->tag);
44536b35 301
1f6b3679 302 *user_token_numberp = user_token_number;
88bce5a2 303 /* User defined $end token? */
44536b35
AD
304 if (user_token_number == 0)
305 {
17ee7397 306 endtoken = sym;
88bce5a2 307 endtoken->number = 0;
44536b35
AD
308 /* It is always mapped to 0, so it was already counted in
309 NTOKENS. */
310 --ntokens;
311 }
312}
313
314
17ee7397
PE
315/*----------------------------------------------------------.
316| If SYM is not defined, report an error, and consider it a |
317| nonterminal. |
318`----------------------------------------------------------*/
2f1afb73 319
0fb1efaf 320static inline bool
17ee7397 321symbol_check_defined (symbol *sym)
2f1afb73 322{
17ee7397 323 if (sym->class == unknown_sym)
2f1afb73 324 {
ee000ba4 325 complain_at
17ee7397 326 (sym->location,
ee000ba4 327 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
328 sym->tag);
329 sym->class = nterm_sym;
330 sym->number = nvars++;
2f1afb73
AD
331 }
332
a3714bce 333 return true;
2f1afb73
AD
334}
335
0fb1efaf
PE
336static bool
337symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
338{
339 return symbol_check_defined (sym);
340}
341
2f1afb73 342
17ee7397
PE
343/*------------------------------------------------------------------.
344| Declare the new symbol SYM. Make it an alias of SYMVAL, and type |
527203e9 345| SYMVAL with SYM's type. |
17ee7397 346`------------------------------------------------------------------*/
2f1afb73
AD
347
348void
17ee7397 349symbol_make_alias (symbol *sym, symbol *symval, location loc)
2f1afb73
AD
350{
351 if (symval->alias)
a5d50994 352 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
df09ef2e 353 symval->tag);
17ee7397 354 else if (sym->alias)
a5d50994 355 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 356 sym->tag);
2f1afb73
AD
357 else
358 {
359 symval->class = token_sym;
17ee7397
PE
360 symval->user_token_number = sym->user_token_number;
361 sym->user_token_number = USER_NUMBER_ALIAS;
362 symval->alias = sym;
363 sym->alias = symval;
965537bc 364 symval->number = sym->number;
e8fd72d5 365 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
366 }
367}
368
369
370/*---------------------------------------------------------.
371| Check that THIS, and its alias, have same precedence and |
372| associativity. |
373`---------------------------------------------------------*/
374
df09ef2e 375static inline void
0fb1efaf 376symbol_check_alias_consistency (symbol *this)
2f1afb73 377{
df09ef2e
AD
378 symbol *alias = this;
379 symbol *orig = this->alias;
380
381 /* Check only those that _are_ the aliases. */
382 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
383 return;
384
e8fd72d5 385 if (orig->type_name != alias->type_name)
2f1afb73 386 {
df09ef2e
AD
387 if (orig->type_name)
388 symbol_type_set (alias, orig->type_name, orig->type_location);
389 else
390 symbol_type_set (orig, alias->type_name, alias->type_location);
391 }
2f1afb73 392
df09ef2e
AD
393
394 if (orig->destructor || alias->destructor)
395 {
396 if (orig->destructor)
397 symbol_destructor_set (alias, orig->destructor,
398 orig->destructor_location);
399 else
400 symbol_destructor_set (orig, alias->destructor,
401 alias->destructor_location);
402 }
403
404 if (orig->printer || alias->printer)
405 {
406 if (orig->printer)
407 symbol_printer_set (alias, orig->printer, orig->printer_location);
408 else
409 symbol_printer_set (orig, alias->printer, alias->printer_location);
410 }
411
412 if (alias->prec || orig->prec)
413 {
414 if (orig->prec)
415 symbol_precedence_set (alias, orig->prec, orig->assoc,
416 orig->prec_location);
417 else
418 symbol_precedence_set (orig, alias->prec, alias->assoc,
419 alias->prec_location);
2f1afb73 420 }
2f1afb73
AD
421}
422
0fb1efaf
PE
423static bool
424symbol_check_alias_consistency_processor (void *this,
425 void *null ATTRIBUTE_UNUSED)
426{
df09ef2e
AD
427 symbol_check_alias_consistency (this);
428 return true;
0fb1efaf
PE
429}
430
2f1afb73
AD
431
432/*-------------------------------------------------------------------.
433| Assign a symbol number, and write the definition of the token name |
434| into FDEFINES. Put in SYMBOLS. |
435`-------------------------------------------------------------------*/
436
0fb1efaf 437static inline bool
17ee7397 438symbol_pack (symbol *this)
2f1afb73
AD
439{
440 if (this->class == nterm_sym)
441 {
442 this->number += ntokens;
443 }
444 else if (this->alias)
445 {
446 /* This symbol and its alias are a single token defn.
447 Allocate a tokno, and assign to both check agreement of
448 prec and assoc fields and make both the same */
449 if (this->number == NUMBER_UNDEFINED)
450 {
88bce5a2 451 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
452 this->number = this->alias->number = 0;
453 else
454 {
68cae94e 455 assert (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
456 this->number = this->alias->number;
457 }
458 }
b9e00562 459 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 460 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 461 return true;
2f1afb73
AD
462 }
463 else /* this->class == token_sym */
68cae94e 464 assert (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
465
466 symbols[this->number] = this;
a3714bce 467 return true;
2f1afb73
AD
468}
469
0fb1efaf
PE
470static bool
471symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
472{
473 return symbol_pack (this);
474}
475
2f1afb73
AD
476
477
478
479/*--------------------------------------------------.
480| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
481`--------------------------------------------------*/
482
0fb1efaf 483static inline bool
17ee7397 484symbol_translation (symbol *this)
2f1afb73
AD
485{
486 /* Non-terminal? */
487 if (this->class == token_sym
488 && this->user_token_number != USER_NUMBER_ALIAS)
489 {
490 /* A token which translation has already been set? */
491 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
492 complain_at (this->location,
493 _("tokens %s and %s both assigned number %d"),
494 symbols[token_translations[this->user_token_number]]->tag,
495 this->tag, this->user_token_number);
2f1afb73
AD
496
497 token_translations[this->user_token_number] = this->number;
498 }
499
a3714bce 500 return true;
2f1afb73
AD
501}
502
0fb1efaf
PE
503static bool
504symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
505{
506 return symbol_translation (this);
507}
508
72a23c97
AD
509
510/*----------------------.
2f1afb73 511| A symbol hash table. |
72a23c97 512`----------------------*/
40675e7c 513
db8837cb 514/* Initial capacity of symbols hash table. */
72a23c97
AD
515#define HT_INITIAL_CAPACITY 257
516
db8837cb 517static struct hash_table *symbol_table = NULL;
72a23c97 518
0fb1efaf 519static inline bool
17ee7397 520hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 521{
95612cfa 522 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 523 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
524}
525
0fb1efaf
PE
526static bool
527hash_symbol_comparator (void const *m1, void const *m2)
528{
529 return hash_compare_symbol (m1, m2);
530}
531
233a88ad
PE
532static inline size_t
533hash_symbol (const symbol *m, size_t tablesize)
72a23c97 534{
95612cfa 535 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
536 return ((uintptr_t) m->tag) % tablesize;
537}
538
233a88ad
PE
539static size_t
540hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
541{
542 return hash_symbol (m, tablesize);
72a23c97
AD
543}
544
545
546/*-------------------------------.
2f1afb73 547| Create the symbol hash table. |
72a23c97
AD
548`-------------------------------*/
549
550void
db8837cb 551symbols_new (void)
72a23c97 552{
db8837cb 553 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 554 NULL,
0fb1efaf
PE
555 hash_symbol_hasher,
556 hash_symbol_comparator,
557 free);
40675e7c
DM
558}
559
560
1e9798d5
AD
561/*----------------------------------------------------------------.
562| Find the symbol named KEY, and return it. If it does not exist |
563| yet, create it. |
564`----------------------------------------------------------------*/
565
17ee7397 566symbol *
203b9274 567symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 568{
17ee7397
PE
569 symbol probe;
570 symbol *entry;
40675e7c 571
0fb1efaf 572 probe.tag = key;
db8837cb 573 entry = hash_lookup (symbol_table, &probe);
40675e7c 574
72a23c97 575 if (!entry)
40675e7c 576 {
72a23c97 577 /* First insertion in the hash. */
17ee7397 578 entry = symbol_new (key, loc);
db8837cb 579 hash_insert (symbol_table, entry);
40675e7c 580 }
72a23c97
AD
581 return entry;
582}
40675e7c 583
40675e7c 584
203b9274
AD
585/*----------------------------------------------------------------.
586| Find the symbol named KEY, and return it. If it does not exist |
587| yet, create it. |
588`----------------------------------------------------------------*/
589
590symbol *
591symbol_get (const char *key, location loc)
592{
593 return symbol_from_uniqstr (uniqstr_new (key), loc);
594}
595
596
39f41916
AD
597/*------------------------------------------------------------------.
598| Generate a dummy nonterminal, whose name cannot conflict with the |
599| user's names. |
600`------------------------------------------------------------------*/
601
17ee7397
PE
602symbol *
603dummy_symbol_get (location loc)
39f41916
AD
604{
605 /* Incremented for each generated symbol. */
606 static int dummy_count = 0;
607 static char buf[256];
608
17ee7397 609 symbol *sym;
39f41916
AD
610
611 sprintf (buf, "@%d", ++dummy_count);
17ee7397 612 sym = symbol_get (buf, loc);
39f41916
AD
613 sym->class = nterm_sym;
614 sym->number = nvars++;
615 return sym;
616}
617
618
72a23c97 619/*-------------------.
db8837cb 620| Free the symbols. |
72a23c97
AD
621`-------------------*/
622
623void
db8837cb 624symbols_free (void)
72a23c97 625{
db8837cb 626 hash_free (symbol_table);
536545f3 627 free (symbols);
40675e7c
DM
628}
629
630
72a23c97 631/*---------------------------------------------------------------.
db8837cb 632| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
633| terminals. |
634`---------------------------------------------------------------*/
635
0fb1efaf
PE
636static void
637symbols_do (Hash_processor processor, void *processor_data)
40675e7c 638{
0fb1efaf 639 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 640}
2f1afb73
AD
641
642
643/*--------------------------------------------------------------.
644| Check that all the symbols are defined. Report any undefined |
645| symbols and consider them nonterminals. |
646`--------------------------------------------------------------*/
647
648void
649symbols_check_defined (void)
650{
0fb1efaf 651 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
652}
653
654/*------------------------------------------------------------------.
655| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
656| number. |
657`------------------------------------------------------------------*/
658
659static void
660symbols_token_translations_init (void)
661{
a3714bce 662 bool num_256_available_p = true;
2f1afb73
AD
663 int i;
664
665 /* Find the highest user token number, and whether 256, the POSIX
666 preferred user token number for the error token, is used. */
667 max_user_token_number = 0;
668 for (i = 0; i < ntokens; ++i)
669 {
17ee7397 670 symbol *this = symbols[i];
2f1afb73
AD
671 if (this->user_token_number != USER_NUMBER_UNDEFINED)
672 {
673 if (this->user_token_number > max_user_token_number)
674 max_user_token_number = this->user_token_number;
675 if (this->user_token_number == 256)
a3714bce 676 num_256_available_p = false;
2f1afb73
AD
677 }
678 }
679
680 /* If 256 is not used, assign it to error, to follow POSIX. */
681 if (num_256_available_p
682 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
683 errtoken->user_token_number = 256;
684
685 /* Set the missing user numbers. */
686 if (max_user_token_number < 256)
687 max_user_token_number = 256;
688
689 for (i = 0; i < ntokens; ++i)
690 {
17ee7397 691 symbol *this = symbols[i];
2f1afb73
AD
692 if (this->user_token_number == USER_NUMBER_UNDEFINED)
693 this->user_token_number = ++max_user_token_number;
694 if (this->user_token_number > max_user_token_number)
695 max_user_token_number = this->user_token_number;
696 }
697
da2a7671
PE
698 token_translations = xnmalloc (max_user_token_number + 1,
699 sizeof *token_translations);
2f1afb73
AD
700
701 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
702 token number for $undefined, which represents all invalid inputs.
703 */
2f1afb73
AD
704 for (i = 0; i < max_user_token_number + 1; i++)
705 token_translations[i] = undeftoken->number;
0fb1efaf 706 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
707}
708
709
710/*----------------------------------------------------------------.
711| Assign symbol numbers, and write definition of token names into |
712| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
713`----------------------------------------------------------------*/
714
715void
716symbols_pack (void)
717{
0fb1efaf 718 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
719
720 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 721 symbols_do (symbol_pack_processor, NULL);
2f1afb73 722
6d0ef4ec
JD
723 /* Aliases leave empty slots in symbols, so remove them. */
724 {
725 int writei;
726 int readi;
727 int nsyms_old = nsyms;
728 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
729 {
730 if (symbols[readi] == NULL)
731 {
732 nsyms -= 1;
733 ntokens -= 1;
734 }
735 else
736 {
737 symbols[writei] = symbols[readi];
738 symbols[writei]->number = writei;
739 if (symbols[writei]->alias)
740 symbols[writei]->alias->number = writei;
741 writei += 1;
742 }
743 }
744 }
745 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
746
2f1afb73
AD
747 symbols_token_translations_init ();
748
749 if (startsymbol->class == unknown_sym)
ee000ba4 750 fatal_at (startsymbol_location,
dafdc66f 751 _("the start symbol %s is undefined"),
97650f4e 752 startsymbol->tag);
2f1afb73 753 else if (startsymbol->class == token_sym)
ee000ba4 754 fatal_at (startsymbol_location,
dafdc66f 755 _("the start symbol %s is a token"),
97650f4e 756 startsymbol->tag);
2f1afb73 757}
ec5479ce
JD
758
759
760/*-----------------------------------.
761| Set default %destructor/%printer. |
762`-----------------------------------*/
763
764void
765default_destructor_set (const char *destructor, location loc)
766{
767 if (default_destructor != NULL)
768 {
769 complain_at (loc, _("redeclaration for default %%destructor"));
770 complain_at (default_destructor_location, _("previous declaration"));
771 }
772 default_destructor = destructor;
773 default_destructor_location = loc;
774}
775
776void
777default_printer_set (const char *printer, location loc)
778{
779 if (default_printer != NULL)
780 {
781 complain_at (loc, _("redeclaration for default %%printer"));
782 complain_at (default_printer_location, _("previous declaration"));
783 }
784 default_printer = printer;
785 default_printer_location = loc;
786}