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