]> git.saurik.com Git - bison.git/blame - src/symtab.c
Enable declaration of default %printer/%destructor. Make the parser
[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);
1e9798d5 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++;
269 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
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{
68cae94e 290 assert (sym->class == token_sym);
44536b35 291
17ee7397
PE
292 if (sym->user_token_number != USER_NUMBER_UNDEFINED
293 && sym->user_token_number != user_token_number)
294 complain_at (loc, _("redefining user token number of %s"), sym->tag);
44536b35 295
17ee7397 296 sym->user_token_number = user_token_number;
88bce5a2 297 /* User defined $end token? */
44536b35
AD
298 if (user_token_number == 0)
299 {
17ee7397 300 endtoken = sym;
88bce5a2 301 endtoken->number = 0;
44536b35
AD
302 /* It is always mapped to 0, so it was already counted in
303 NTOKENS. */
304 --ntokens;
305 }
306}
307
308
17ee7397
PE
309/*----------------------------------------------------------.
310| If SYM is not defined, report an error, and consider it a |
311| nonterminal. |
312`----------------------------------------------------------*/
2f1afb73 313
0fb1efaf 314static inline bool
17ee7397 315symbol_check_defined (symbol *sym)
2f1afb73 316{
17ee7397 317 if (sym->class == unknown_sym)
2f1afb73 318 {
ee000ba4 319 complain_at
17ee7397 320 (sym->location,
ee000ba4 321 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
322 sym->tag);
323 sym->class = nterm_sym;
324 sym->number = nvars++;
2f1afb73
AD
325 }
326
a3714bce 327 return true;
2f1afb73
AD
328}
329
0fb1efaf
PE
330static bool
331symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
332{
333 return symbol_check_defined (sym);
334}
335
2f1afb73 336
17ee7397
PE
337/*------------------------------------------------------------------.
338| Declare the new symbol SYM. Make it an alias of SYMVAL, and type |
527203e9 339| SYMVAL with SYM's type. |
17ee7397 340`------------------------------------------------------------------*/
2f1afb73
AD
341
342void
17ee7397 343symbol_make_alias (symbol *sym, symbol *symval, location loc)
2f1afb73
AD
344{
345 if (symval->alias)
a5d50994 346 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
df09ef2e 347 symval->tag);
17ee7397 348 else if (sym->alias)
a5d50994 349 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 350 sym->tag);
2f1afb73
AD
351 else
352 {
353 symval->class = token_sym;
17ee7397
PE
354 symval->user_token_number = sym->user_token_number;
355 sym->user_token_number = USER_NUMBER_ALIAS;
356 symval->alias = sym;
357 sym->alias = symval;
358 /* sym and symval combined are only one symbol. */
2f1afb73
AD
359 nsyms--;
360 ntokens--;
68cae94e 361 assert (ntokens == sym->number || ntokens == symval->number);
17ee7397
PE
362 sym->number = symval->number =
363 (symval->number < sym->number) ? symval->number : sym->number;
e8fd72d5 364 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
365 }
366}
367
368
369/*---------------------------------------------------------.
370| Check that THIS, and its alias, have same precedence and |
371| associativity. |
372`---------------------------------------------------------*/
373
df09ef2e 374static inline void
0fb1efaf 375symbol_check_alias_consistency (symbol *this)
2f1afb73 376{
df09ef2e
AD
377 symbol *alias = this;
378 symbol *orig = this->alias;
379
380 /* Check only those that _are_ the aliases. */
381 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
382 return;
383
e8fd72d5 384 if (orig->type_name != alias->type_name)
2f1afb73 385 {
df09ef2e
AD
386 if (orig->type_name)
387 symbol_type_set (alias, orig->type_name, orig->type_location);
388 else
389 symbol_type_set (orig, alias->type_name, alias->type_location);
390 }
2f1afb73 391
df09ef2e
AD
392
393 if (orig->destructor || alias->destructor)
394 {
395 if (orig->destructor)
396 symbol_destructor_set (alias, orig->destructor,
397 orig->destructor_location);
398 else
399 symbol_destructor_set (orig, alias->destructor,
400 alias->destructor_location);
401 }
402
403 if (orig->printer || alias->printer)
404 {
405 if (orig->printer)
406 symbol_printer_set (alias, orig->printer, orig->printer_location);
407 else
408 symbol_printer_set (orig, alias->printer, alias->printer_location);
409 }
410
411 if (alias->prec || orig->prec)
412 {
413 if (orig->prec)
414 symbol_precedence_set (alias, orig->prec, orig->assoc,
415 orig->prec_location);
416 else
417 symbol_precedence_set (orig, alias->prec, alias->assoc,
418 alias->prec_location);
2f1afb73 419 }
2f1afb73
AD
420}
421
0fb1efaf
PE
422static bool
423symbol_check_alias_consistency_processor (void *this,
424 void *null ATTRIBUTE_UNUSED)
425{
df09ef2e
AD
426 symbol_check_alias_consistency (this);
427 return true;
0fb1efaf
PE
428}
429
2f1afb73
AD
430
431/*-------------------------------------------------------------------.
432| Assign a symbol number, and write the definition of the token name |
433| into FDEFINES. Put in SYMBOLS. |
434`-------------------------------------------------------------------*/
435
0fb1efaf 436static inline bool
17ee7397 437symbol_pack (symbol *this)
2f1afb73
AD
438{
439 if (this->class == nterm_sym)
440 {
441 this->number += ntokens;
442 }
443 else if (this->alias)
444 {
445 /* This symbol and its alias are a single token defn.
446 Allocate a tokno, and assign to both check agreement of
447 prec and assoc fields and make both the same */
448 if (this->number == NUMBER_UNDEFINED)
449 {
88bce5a2 450 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
451 this->number = this->alias->number = 0;
452 else
453 {
68cae94e 454 assert (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
455 this->number = this->alias->number;
456 }
457 }
b9e00562 458 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 459 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 460 return true;
2f1afb73
AD
461 }
462 else /* this->class == token_sym */
68cae94e 463 assert (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
464
465 symbols[this->number] = this;
a3714bce 466 return true;
2f1afb73
AD
467}
468
0fb1efaf
PE
469static bool
470symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
471{
472 return symbol_pack (this);
473}
474
2f1afb73
AD
475
476
477
478/*--------------------------------------------------.
479| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
480`--------------------------------------------------*/
481
0fb1efaf 482static inline bool
17ee7397 483symbol_translation (symbol *this)
2f1afb73
AD
484{
485 /* Non-terminal? */
486 if (this->class == token_sym
487 && this->user_token_number != USER_NUMBER_ALIAS)
488 {
489 /* A token which translation has already been set? */
490 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
491 complain_at (this->location,
492 _("tokens %s and %s both assigned number %d"),
493 symbols[token_translations[this->user_token_number]]->tag,
494 this->tag, this->user_token_number);
2f1afb73
AD
495
496 token_translations[this->user_token_number] = this->number;
497 }
498
a3714bce 499 return true;
2f1afb73
AD
500}
501
0fb1efaf
PE
502static bool
503symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
504{
505 return symbol_translation (this);
506}
507
72a23c97
AD
508
509/*----------------------.
2f1afb73 510| A symbol hash table. |
72a23c97 511`----------------------*/
40675e7c 512
db8837cb 513/* Initial capacity of symbols hash table. */
72a23c97
AD
514#define HT_INITIAL_CAPACITY 257
515
db8837cb 516static struct hash_table *symbol_table = NULL;
72a23c97 517
0fb1efaf 518static inline bool
17ee7397 519hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 520{
95612cfa 521 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 522 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
523}
524
0fb1efaf
PE
525static bool
526hash_symbol_comparator (void const *m1, void const *m2)
527{
528 return hash_compare_symbol (m1, m2);
529}
530
233a88ad
PE
531static inline size_t
532hash_symbol (const symbol *m, size_t tablesize)
72a23c97 533{
95612cfa 534 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
535 return ((uintptr_t) m->tag) % tablesize;
536}
537
233a88ad
PE
538static size_t
539hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
540{
541 return hash_symbol (m, tablesize);
72a23c97
AD
542}
543
544
545/*-------------------------------.
2f1afb73 546| Create the symbol hash table. |
72a23c97
AD
547`-------------------------------*/
548
549void
db8837cb 550symbols_new (void)
72a23c97 551{
db8837cb 552 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 553 NULL,
0fb1efaf
PE
554 hash_symbol_hasher,
555 hash_symbol_comparator,
556 free);
40675e7c
DM
557}
558
559
1e9798d5
AD
560/*----------------------------------------------------------------.
561| Find the symbol named KEY, and return it. If it does not exist |
562| yet, create it. |
563`----------------------------------------------------------------*/
564
17ee7397 565symbol *
203b9274 566symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 567{
17ee7397
PE
568 symbol probe;
569 symbol *entry;
40675e7c 570
0fb1efaf 571 probe.tag = key;
db8837cb 572 entry = hash_lookup (symbol_table, &probe);
40675e7c 573
72a23c97 574 if (!entry)
40675e7c 575 {
72a23c97 576 /* First insertion in the hash. */
17ee7397 577 entry = symbol_new (key, loc);
db8837cb 578 hash_insert (symbol_table, entry);
40675e7c 579 }
72a23c97
AD
580 return entry;
581}
40675e7c 582
40675e7c 583
203b9274
AD
584/*----------------------------------------------------------------.
585| Find the symbol named KEY, and return it. If it does not exist |
586| yet, create it. |
587`----------------------------------------------------------------*/
588
589symbol *
590symbol_get (const char *key, location loc)
591{
592 return symbol_from_uniqstr (uniqstr_new (key), loc);
593}
594
595
39f41916
AD
596/*------------------------------------------------------------------.
597| Generate a dummy nonterminal, whose name cannot conflict with the |
598| user's names. |
599`------------------------------------------------------------------*/
600
17ee7397
PE
601symbol *
602dummy_symbol_get (location loc)
39f41916
AD
603{
604 /* Incremented for each generated symbol. */
605 static int dummy_count = 0;
606 static char buf[256];
607
17ee7397 608 symbol *sym;
39f41916
AD
609
610 sprintf (buf, "@%d", ++dummy_count);
17ee7397 611 sym = symbol_get (buf, loc);
39f41916
AD
612 sym->class = nterm_sym;
613 sym->number = nvars++;
614 return sym;
615}
616
617
72a23c97 618/*-------------------.
db8837cb 619| Free the symbols. |
72a23c97
AD
620`-------------------*/
621
622void
db8837cb 623symbols_free (void)
72a23c97 624{
db8837cb 625 hash_free (symbol_table);
536545f3 626 free (symbols);
40675e7c
DM
627}
628
629
72a23c97 630/*---------------------------------------------------------------.
db8837cb 631| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
632| terminals. |
633`---------------------------------------------------------------*/
634
0fb1efaf
PE
635static void
636symbols_do (Hash_processor processor, void *processor_data)
40675e7c 637{
0fb1efaf 638 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 639}
2f1afb73
AD
640
641
642/*--------------------------------------------------------------.
643| Check that all the symbols are defined. Report any undefined |
644| symbols and consider them nonterminals. |
645`--------------------------------------------------------------*/
646
647void
648symbols_check_defined (void)
649{
0fb1efaf 650 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
651}
652
653/*------------------------------------------------------------------.
654| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
655| number. |
656`------------------------------------------------------------------*/
657
658static void
659symbols_token_translations_init (void)
660{
a3714bce 661 bool num_256_available_p = true;
2f1afb73
AD
662 int i;
663
664 /* Find the highest user token number, and whether 256, the POSIX
665 preferred user token number for the error token, is used. */
666 max_user_token_number = 0;
667 for (i = 0; i < ntokens; ++i)
668 {
17ee7397 669 symbol *this = symbols[i];
2f1afb73
AD
670 if (this->user_token_number != USER_NUMBER_UNDEFINED)
671 {
672 if (this->user_token_number > max_user_token_number)
673 max_user_token_number = this->user_token_number;
674 if (this->user_token_number == 256)
a3714bce 675 num_256_available_p = false;
2f1afb73
AD
676 }
677 }
678
679 /* If 256 is not used, assign it to error, to follow POSIX. */
680 if (num_256_available_p
681 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
682 errtoken->user_token_number = 256;
683
684 /* Set the missing user numbers. */
685 if (max_user_token_number < 256)
686 max_user_token_number = 256;
687
688 for (i = 0; i < ntokens; ++i)
689 {
17ee7397 690 symbol *this = symbols[i];
2f1afb73
AD
691 if (this->user_token_number == USER_NUMBER_UNDEFINED)
692 this->user_token_number = ++max_user_token_number;
693 if (this->user_token_number > max_user_token_number)
694 max_user_token_number = this->user_token_number;
695 }
696
da2a7671
PE
697 token_translations = xnmalloc (max_user_token_number + 1,
698 sizeof *token_translations);
2f1afb73
AD
699
700 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
701 token number for $undefined, which represents all invalid inputs.
702 */
2f1afb73
AD
703 for (i = 0; i < max_user_token_number + 1; i++)
704 token_translations[i] = undeftoken->number;
0fb1efaf 705 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
706}
707
708
709/*----------------------------------------------------------------.
710| Assign symbol numbers, and write definition of token names into |
711| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
712`----------------------------------------------------------------*/
713
714void
715symbols_pack (void)
716{
da2a7671 717 symbols = xcalloc (nsyms, sizeof *symbols);
2f1afb73 718
0fb1efaf
PE
719 symbols_do (symbol_check_alias_consistency_processor, NULL);
720 symbols_do (symbol_pack_processor, NULL);
2f1afb73
AD
721
722 symbols_token_translations_init ();
723
724 if (startsymbol->class == unknown_sym)
ee000ba4 725 fatal_at (startsymbol_location,
dafdc66f 726 _("the start symbol %s is undefined"),
97650f4e 727 startsymbol->tag);
2f1afb73 728 else if (startsymbol->class == token_sym)
ee000ba4 729 fatal_at (startsymbol_location,
dafdc66f 730 _("the start symbol %s is a token"),
97650f4e 731 startsymbol->tag);
2f1afb73 732}
ec5479ce
JD
733
734
735/*-----------------------------------.
736| Set default %destructor/%printer. |
737`-----------------------------------*/
738
739void
740default_destructor_set (const char *destructor, location loc)
741{
742 if (default_destructor != NULL)
743 {
744 complain_at (loc, _("redeclaration for default %%destructor"));
745 complain_at (default_destructor_location, _("previous declaration"));
746 }
747 default_destructor = destructor;
748 default_destructor_location = loc;
749}
750
751void
752default_printer_set (const char *printer, location loc)
753{
754 if (default_printer != NULL)
755 {
756 complain_at (loc, _("redeclaration for default %%printer"));
757 complain_at (default_printer_location, _("previous declaration"));
758 }
759 default_printer = printer;
760 default_printer_location = loc;
761}