]> git.saurik.com Git - bison.git/blame - src/reader.c
* ChangeLog: Add mailing list references to some of the 2006-06-26 patches.
[bison.git] / src / reader.c
CommitLineData
35dcf428 1/* Input parser for Bison
9c4637fa 2
05ac60f3 3 Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003,
378f4bd8 4 2005, 2006 Free Software Foundation, Inc.
1ff442ca 5
41aca2e0 6 This file is part of Bison, the GNU Compiler Compiler.
1ff442ca 7
41aca2e0
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.
1ff442ca 12
41aca2e0
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.
1ff442ca 17
41aca2e0
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. */
1ff442ca 22
2cec9080 23#include <config.h>
1ff442ca 24#include "system.h"
e9071366 25#include <assert.h>
17ee7397
PE
26
27#include <quotearg.h>
28
29#include "complain.h"
30#include "conflicts.h"
1ff442ca 31#include "files.h"
17ee7397 32#include "getargs.h"
1ff442ca 33#include "gram.h"
17ee7397 34#include "muscle_tab.h"
b2ca4022 35#include "reader.h"
17ee7397
PE
36#include "symlist.h"
37#include "symtab.h"
e9071366
AD
38#include "scan-gram.h"
39#include "scan-code.h"
1ff442ca 40
02d12d0d
PE
41static void check_and_convert_grammar (void);
42
17ee7397 43static symbol_list *grammar = NULL;
d0829076 44static bool start_flag = false;
676385e2 45merger_list *merge_functions;
1ff442ca 46
34f98f46 47/* Was %union seen? */
d0829076 48bool typed = false;
39a06c25
PE
49
50/* Should rules have a default precedence? */
51bool default_prec = true;
0d533154 52\f
e9955c83
AD
53/*-----------------------.
54| Set the start symbol. |
55`-----------------------*/
1ff442ca 56
e9955c83 57void
a737b216 58grammar_start_symbol_set (symbol *sym, location loc)
1ff442ca
NF
59{
60 if (start_flag)
17ee7397 61 complain_at (loc, _("multiple %s declarations"), "%start");
943819bf
RS
62 else
63 {
d0829076 64 start_flag = true;
a737b216 65 startsymbol = sym;
17ee7397 66 startsymbol_location = loc;
943819bf 67 }
1ff442ca
NF
68}
69
1ff442ca 70
34f98f46
JD
71/*---------------------------------------------------------------------.
72| There are two prologues: one before the first %union and one after. |
73| Augment the one specified by POST. |
74`---------------------------------------------------------------------*/
1ff442ca 75
e9955c83 76void
34f98f46 77prologue_augment (const char *prologue, location loc, bool post)
b6610515 78{
e9955c83 79 struct obstack *oout =
34f98f46 80 !post ? &pre_prologue_obstack : &post_prologue_obstack;
b6610515 81
05ac60f3 82 obstack_fgrow1 (oout, "]b4_syncline(%d, [[", loc.start.line);
e9071366
AD
83 /* FIXME: Protection of M4 characters missing here. See
84 output.c:escaped_output. */
17ee7397
PE
85 MUSCLE_OBSTACK_SGROW (oout,
86 quotearg_style (c_quoting_style, loc.start.file));
6c239755 87 obstack_sgrow (oout, "]])[\n");
e9955c83 88 obstack_sgrow (oout, prologue);
b6610515
RA
89}
90
a70083a3
AD
91\f
92
8ee5b538
JD
93/*------------------------------------------------------------------------.
94| Return the merger index for a merging function named NAME. Records the |
95| function, if new, in MERGER_LIST. |
96`------------------------------------------------------------------------*/
676385e2
PH
97
98static int
8ee5b538 99get_merge_function (uniqstr name)
676385e2
PH
100{
101 merger_list *syms;
102 merger_list head;
103 int n;
104
105 if (! glr_parser)
106 return 0;
107
676385e2 108 head.next = merge_functions;
affac613 109 for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
17ee7397 110 if (UNIQSTR_EQ (name, syms->next->name))
676385e2 111 break;
a5d50994
AD
112 if (syms->next == NULL)
113 {
da2a7671 114 syms->next = xmalloc (sizeof syms->next[0]);
17ee7397 115 syms->next->name = uniqstr_new (name);
8ee5b538
JD
116 /* After all symbol type declarations have been parsed, packgram invokes
117 record_merge_function_type to set the type. */
118 syms->next->type = NULL;
a5d50994
AD
119 syms->next->next = NULL;
120 merge_functions = head.next;
121 }
676385e2
PH
122 return n;
123}
124
8ee5b538
JD
125/*-------------------------------------------------------------------------.
126| For the existing merging function with index MERGER, record the result |
127| type as TYPE as required by the lhs of the rule whose %merge declaration |
128| is at DECLARATION_LOC. |
129`-------------------------------------------------------------------------*/
130
131static void
132record_merge_function_type (int merger, uniqstr type, location declaration_loc)
133{
134 int merger_find;
135 merger_list *merge_function;
136
137 if (merger <= 0)
138 return;
139
140 if (type == NULL)
141 type = uniqstr_new ("");
142
143 merger_find = 1;
144 for (merge_function = merge_functions;
145 merge_function != NULL && merger_find != merger;
146 merge_function = merge_function->next)
147 merger_find += 1;
148 assert (merge_function != NULL && merger_find == merger);
149 if (merge_function->type == NULL)
150 {
151 merge_function->type = uniqstr_new (type);
152 merge_function->type_declaration_location = declaration_loc;
153 }
154 else if (!UNIQSTR_EQ (merge_function->type, type))
155 {
156 warn_at (declaration_loc,
157 _("result type clash on merge function `%s': <%s> != <%s>"),
158 merge_function->name, type, merge_function->type);
159 warn_at (merge_function->type_declaration_location,
160 _("first declaration"));
161 }
162}
163
676385e2
PH
164/*--------------------------------------.
165| Free all merge-function definitions. |
166`--------------------------------------*/
167
168void
169free_merger_functions (void)
170{
affac613
AD
171 merger_list *L0 = merge_functions;
172 while (L0)
676385e2
PH
173 {
174 merger_list *L1 = L0->next;
175 free (L0);
176 L0 = L1;
177 }
178}
179
a70083a3 180\f
107f7dfb 181/*-------------------------------------------------------------------.
17ee7397 182| Parse the input grammar into a one symbol_list structure. Each |
107f7dfb
AD
183| rule is represented by a sequence of symbols: the left hand side |
184| followed by the contents of the right hand side, followed by a |
185| null pointer instead of a symbol to terminate the rule. The next |
186| symbol is the lhs of the following rule. |
187| |
fdbcd8e2
AD
188| All actions are copied out, labelled by the rule number they apply |
189| to. |
107f7dfb 190`-------------------------------------------------------------------*/
1ff442ca 191
f6d0f937 192/* The (currently) last symbol of GRAMMAR. */
04098407 193static symbol_list *grammar_end = NULL;
f6d0f937 194
52328c6e 195/* Append SYM to the grammar. */
8f3596a6 196static void
17ee7397 197grammar_symbol_append (symbol *sym, location loc)
f6d0f937 198{
17ee7397 199 symbol_list *p = symbol_list_new (sym, loc);
f6d0f937
AD
200
201 if (grammar_end)
202 grammar_end->next = p;
203 else
204 grammar = p;
205
206 grammar_end = p;
8f3596a6 207
e3233bf6 208 /* A null SYM stands for an end of rule; it is not an actual
8f3596a6
AD
209 part of it. */
210 if (sym)
211 ++nritems;
f6d0f937
AD
212}
213
8efe435c
AD
214/* The rule currently being defined, and the previous rule.
215 CURRENT_RULE points to the first LHS of the current rule, while
216 PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */
e256e17f 217static symbol_list *current_rule = NULL;
04098407 218static symbol_list *previous_rule_end = NULL;
da4160c3
AD
219
220
8efe435c
AD
221/*----------------------------------------------.
222| Create a new rule for LHS in to the GRAMMAR. |
223`----------------------------------------------*/
da4160c3 224
e9955c83 225void
8f3596a6 226grammar_current_rule_begin (symbol *lhs, location loc)
da4160c3
AD
227{
228 if (!start_flag)
229 {
230 startsymbol = lhs;
17ee7397 231 startsymbol_location = loc;
d0829076 232 start_flag = true;
da4160c3
AD
233 }
234
235 /* Start a new rule and record its lhs. */
236 ++nrules;
8efe435c 237 previous_rule_end = grammar_end;
17ee7397 238 grammar_symbol_append (lhs, loc);
da4160c3
AD
239 current_rule = grammar_end;
240
241 /* Mark the rule's lhs as a nonterminal if not already so. */
da4160c3
AD
242 if (lhs->class == unknown_sym)
243 {
244 lhs->class = nterm_sym;
245 lhs->number = nvars;
246 ++nvars;
247 }
248 else if (lhs->class == token_sym)
17ee7397 249 complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);
da4160c3
AD
250}
251
affac613 252
d40ba6c2
PE
253/*----------------------------------------------------------------------.
254| A symbol should be used if it has a destructor, or if it is a |
255| mid-rule symbol (i.e., the generated LHS replacing a mid-rule |
256| action) that was assigned to, as in "exp: { $$ = 1; } { $$ = $1; }". |
257`----------------------------------------------------------------------*/
84866159
AD
258
259static bool
d40ba6c2 260symbol_should_be_used (symbol_list const *s)
84866159 261{
d40ba6c2 262 return (s->sym->destructor
c66dfadd 263 || (s->midrule && s->midrule->used));
84866159
AD
264}
265
8f3596a6
AD
266/*----------------------------------------------------------------.
267| Check that the rule R is properly defined. For instance, there |
268| should be no type clash on the default action. |
269`----------------------------------------------------------------*/
e9955c83
AD
270
271static void
8f3596a6 272grammar_rule_check (const symbol_list *r)
e9955c83 273{
affac613 274 /* Type check.
e9955c83 275
affac613
AD
276 If there is an action, then there is nothing we can do: the user
277 is allowed to shoot herself in the foot.
3f4c0f80 278
affac613
AD
279 Don't worry about the default action if $$ is untyped, since $$'s
280 value can't be used. */
8f3596a6 281 if (!r->action && r->sym->type_name)
e9955c83 282 {
8f3596a6 283 symbol *first_rhs = r->next->sym;
affac613
AD
284 /* If $$ is being set in default way, report if any type mismatch. */
285 if (first_rhs)
286 {
8f3596a6 287 char const *lhs_type = r->sym->type_name;
affac613
AD
288 const char *rhs_type =
289 first_rhs->type_name ? first_rhs->type_name : "";
290 if (!UNIQSTR_EQ (lhs_type, rhs_type))
8f3596a6 291 warn_at (r->location,
affac613
AD
292 _("type clash on default action: <%s> != <%s>"),
293 lhs_type, rhs_type);
294 }
295 /* Warn if there is no default for $$ but we need one. */
296 else
8f3596a6 297 warn_at (r->location,
affac613
AD
298 _("empty rule for typed nonterminal, and no action"));
299 }
e3233bf6 300
d40ba6c2 301 /* Check that symbol values that should be used are in fact used. */
8f3596a6 302 {
668c5d19 303 symbol_list const *l = r;
8f3596a6
AD
304 int n = 0;
305 for (; l && l->sym; l = l->next, ++n)
306 if (! (l->used
d40ba6c2 307 || !symbol_should_be_used (l)
8f3596a6 308 /* The default action, $$ = $1, `uses' both. */
668c5d19
PE
309 || (!r->action && (n == 0 || n == 1))))
310 {
311 if (n)
312 warn_at (r->location, _("unused value: $%d"), n);
313 else
314 warn_at (r->location, _("unset value: $$"));
315 }
8f3596a6 316 }
e9955c83
AD
317}
318
319
8efe435c
AD
320/*-------------------------------------.
321| End the currently being grown rule. |
322`-------------------------------------*/
e9955c83
AD
323
324void
8f3596a6 325grammar_current_rule_end (location loc)
e9955c83
AD
326{
327 /* Put an empty link in the list to mark the end of this rule */
8efe435c 328 grammar_symbol_append (NULL, grammar_end->location);
17ee7397 329 current_rule->location = loc;
e9955c83
AD
330}
331
332
8efe435c
AD
333/*-------------------------------------------------------------------.
334| The previous action turns out the be a mid-rule action. Attach it |
335| to the current rule, i.e., create a dummy symbol, attach it this |
336| mid-rule action, and append this dummy nonterminal to the current |
337| rule. |
338`-------------------------------------------------------------------*/
1485e106 339
6b702268 340void
1485e106
AD
341grammar_midrule_action (void)
342{
343 /* Since the action was written out with this rule's number, we must
344 give the new rule this number by inserting the new rule before
345 it. */
346
8efe435c
AD
347 /* Make a DUMMY nonterminal, whose location is that of the midrule
348 action. Create the MIDRULE. */
17ee7397
PE
349 location dummy_location = current_rule->action_location;
350 symbol *dummy = dummy_symbol_get (dummy_location);
351 symbol_list *midrule = symbol_list_new (dummy, dummy_location);
1485e106
AD
352
353 /* Make a new rule, whose body is empty, before the current one, so
354 that the action just read can belong to it. */
355 ++nrules;
356 ++nritems;
8efe435c
AD
357 /* Attach its location and actions to that of the DUMMY. */
358 midrule->location = dummy_location;
359 midrule->action = current_rule->action;
360 midrule->action_location = dummy_location;
1485e106 361 current_rule->action = NULL;
ffa4ba3a
JD
362 /* The action has not been translated yet, so $$ use hasn't been
363 detected yet. */
364 midrule->used = false;
1485e106 365
8efe435c
AD
366 if (previous_rule_end)
367 previous_rule_end->next = midrule;
1485e106 368 else
8efe435c 369 grammar = midrule;
1485e106 370
8efe435c 371 /* End the dummy's rule. */
84866159 372 midrule->next = symbol_list_new (NULL, dummy_location);
84866159 373 midrule->next->next = current_rule;
1485e106 374
84866159 375 previous_rule_end = midrule->next;
1485e106 376
8efe435c 377 /* Insert the dummy nonterminal replacing the midrule action into
84866159 378 the current rule. Bind it to its dedicated rule. */
8efe435c 379 grammar_current_rule_symbol_append (dummy, dummy_location);
6ec2c0f2 380 grammar_end->midrule = midrule;
ffa4ba3a
JD
381 midrule->midrule_parent_rule = current_rule;
382 midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
1485e106
AD
383}
384
9af3fbce
AD
385/* Set the precedence symbol of the current rule to PRECSYM. */
386
e9955c83 387void
17ee7397 388grammar_current_rule_prec_set (symbol *precsym, location loc)
9af3fbce
AD
389{
390 if (current_rule->ruleprec)
17ee7397 391 complain_at (loc, _("only one %s allowed per rule"), "%prec");
9af3fbce
AD
392 current_rule->ruleprec = precsym;
393}
394
676385e2
PH
395/* Attach dynamic precedence DPREC to the current rule. */
396
397void
17ee7397 398grammar_current_rule_dprec_set (int dprec, location loc)
676385e2
PH
399{
400 if (! glr_parser)
17ee7397 401 warn_at (loc, _("%s affects only GLR parsers"), "%dprec");
676385e2 402 if (dprec <= 0)
17ee7397 403 complain_at (loc, _("%s must be followed by positive number"), "%dprec");
39f41916 404 else if (current_rule->dprec != 0)
17ee7397 405 complain_at (loc, _("only one %s allowed per rule"), "%dprec");
676385e2
PH
406 current_rule->dprec = dprec;
407}
408
409/* Attach a merge function NAME with argument type TYPE to current
410 rule. */
411
412void
17ee7397 413grammar_current_rule_merge_set (uniqstr name, location loc)
676385e2
PH
414{
415 if (! glr_parser)
17ee7397 416 warn_at (loc, _("%s affects only GLR parsers"), "%merge");
39f41916 417 if (current_rule->merger != 0)
17ee7397 418 complain_at (loc, _("only one %s allowed per rule"), "%merge");
8ee5b538
JD
419 current_rule->merger = get_merge_function (name);
420 current_rule->merger_declaration_location = loc;
676385e2
PH
421}
422
17ee7397 423/* Attach SYM to the current rule. If needed, move the previous
2e047461
AD
424 action as a mid-rule action. */
425
e9955c83 426void
17ee7397 427grammar_current_rule_symbol_append (symbol *sym, location loc)
2e047461
AD
428{
429 if (current_rule->action)
430 grammar_midrule_action ();
17ee7397 431 grammar_symbol_append (sym, loc);
2e047461
AD
432}
433
6b702268 434/* Attach an ACTION to the current rule. */
2e047461 435
e9955c83 436void
17ee7397 437grammar_current_rule_action_append (const char *action, location loc)
2e047461 438{
381ecb06
JD
439 if (current_rule->action)
440 grammar_midrule_action ();
ffa4ba3a
JD
441 /* After all symbol declarations have been parsed, packgram invokes
442 translate_rule_action. */
e256e17f 443 current_rule->action = action;
17ee7397 444 current_rule->action_location = loc;
2e047461
AD
445}
446
a70083a3 447\f
a70083a3
AD
448/*---------------------------------------------------------------.
449| Convert the rules into the representation using RRHS, RLHS and |
d9b739c3 450| RITEM. |
a70083a3 451`---------------------------------------------------------------*/
1ff442ca 452
4a120d45 453static void
118fb205 454packgram (void)
1ff442ca 455{
9222837b 456 unsigned int itemno = 0;
17ee7397
PE
457 rule_number ruleno = 0;
458 symbol_list *p = grammar;
1ff442ca 459
e9ad4aec
PE
460 ritem = xnmalloc (nritems + 1, sizeof *ritem);
461
462 /* This sentinel is used by build_relations in gram.c. */
463 *ritem++ = 0;
464
da2a7671 465 rules = xnmalloc (nrules, sizeof *rules);
1ff442ca 466
1ff442ca
NF
467 while (p)
468 {
e9071366 469 int rule_length = 0;
17ee7397 470 symbol *ruleprec = p->ruleprec;
8ee5b538
JD
471 record_merge_function_type (p->merger, p->sym->type_name,
472 p->merger_declaration_location);
d7e1f00c 473 rules[ruleno].user_number = ruleno;
c3b407f4 474 rules[ruleno].number = ruleno;
bba97eb2 475 rules[ruleno].lhs = p->sym;
99013900 476 rules[ruleno].rhs = ritem + itemno;
da2a7671
PE
477 rules[ruleno].prec = NULL;
478 rules[ruleno].dprec = p->dprec;
479 rules[ruleno].merger = p->merger;
480 rules[ruleno].precsym = NULL;
8efe435c 481 rules[ruleno].location = p->location;
b4afb6bb 482 rules[ruleno].useful = true;
ffa4ba3a 483 rules[ruleno].action = p->action ? translate_rule_action (p) : NULL;
8efe435c 484 rules[ruleno].action_location = p->action_location;
1ff442ca 485
ffa4ba3a 486 /* If this rule contains midrules, rest assured that
ad6b1efa
JD
487 grammar_midrule_action inserted the midrules into grammar before this
488 rule. Thus, the midrule actions have already been scanned in order to
489 set `used' flags for this rule's rhs, so grammar_rule_check will work
490 properly. */
ffa4ba3a
JD
491 grammar_rule_check (p);
492
e9071366 493 for (p = p->next; p && p->sym; p = p->next)
1ff442ca 494 {
e9071366
AD
495 ++rule_length;
496
497 /* Don't allow rule_length == INT_MAX, since that might
498 cause confusion with strtol if INT_MAX == LONG_MAX. */
499 if (rule_length == INT_MAX)
500 fatal_at (rules[ruleno].location, _("rule is too long"));
501
17ee7397 502 /* item_number = symbol_number.
5fbb0954 503 But the former needs to contain more: negative rule numbers. */
a49aecd5 504 ritem[itemno++] = symbol_number_as_item_number (p->sym->number);
1ff442ca 505 /* A rule gets by default the precedence and associativity
e9071366 506 of its last token. */
39a06c25 507 if (p->sym->class == token_sym && default_prec)
03b31c0c 508 rules[ruleno].prec = p->sym;
1ff442ca
NF
509 }
510
511 /* If this rule has a %prec,
a70083a3 512 the specified symbol's precedence replaces the default. */
1ff442ca
NF
513 if (ruleprec)
514 {
03b31c0c
AD
515 rules[ruleno].precsym = ruleprec;
516 rules[ruleno].prec = ruleprec;
1ff442ca 517 }
e9071366 518 /* An item ends by the rule number (negated). */
4b3d3a8e 519 ritem[itemno++] = rule_number_as_item_number (ruleno);
e9071366 520 assert (itemno < ITEM_NUMBER_MAX);
f3849179 521 ++ruleno;
e9071366 522 assert (ruleno < RULE_NUMBER_MAX);
1ff442ca 523
a70083a3
AD
524 if (p)
525 p = p->next;
1ff442ca
NF
526 }
527
68cae94e 528 assert (itemno == nritems);
3067fbef 529
273a74fa 530 if (trace_flag & trace_sets)
3067fbef 531 ritem_print (stderr);
1ff442ca 532}
a70083a3 533\f
fdbcd8e2
AD
534/*------------------------------------------------------------------.
535| Read in the grammar specification and record it in the format |
536| described in gram.h. All actions are copied into ACTION_OBSTACK, |
537| in each case forming the body of a C function (YYACTION) which |
538| contains a switch statement to decide which action to execute. |
539`------------------------------------------------------------------*/
a70083a3
AD
540
541void
542reader (void)
543{
a70083a3 544 /* Initialize the symbol table. */
db8837cb 545 symbols_new ();
b6610515 546
88bce5a2
AD
547 /* Construct the accept symbol. */
548 accept = symbol_get ("$accept", empty_location);
549 accept->class = nterm_sym;
550 accept->number = nvars++;
30171f79 551
a70083a3 552 /* Construct the error token */
39f41916 553 errtoken = symbol_get ("error", empty_location);
d7020c20 554 errtoken->class = token_sym;
72a23c97 555 errtoken->number = ntokens++;
b6610515 556
a70083a3
AD
557 /* Construct a token that represents all undefined literal tokens.
558 It is always token number 2. */
88bce5a2 559 undeftoken = symbol_get ("$undefined", empty_location);
d7020c20 560 undeftoken->class = token_sym;
72a23c97 561 undeftoken->number = ntokens++;
a70083a3 562
331dbc1b 563 /* Initialize the obstacks. */
0dd1580a
RA
564 obstack_init (&pre_prologue_obstack);
565 obstack_init (&post_prologue_obstack);
331dbc1b 566
2b81e969 567 gram_in = xfopen (grammar_file, "r");
e9955c83 568
473d0a75
AD
569 gram__flex_debug = trace_flag & trace_scan;
570 gram_debug = trace_flag & trace_parse;
e9071366 571 gram_scanner_initialize ();
78c3da9e 572 gram_parse ();
331dbc1b 573
02d12d0d
PE
574 if (! complaint_issued)
575 check_and_convert_grammar ();
576
577 xfclose (gram_in);
578}
579
b275314e 580
02d12d0d
PE
581/*-------------------------------------------------------------.
582| Check the grammar that has just been read, and convert it to |
583| internal form. |
584`-------------------------------------------------------------*/
585
586static void
587check_and_convert_grammar (void)
588{
589 /* Grammar has been read. Do some checking. */
e9955c83
AD
590 if (nrules == 0)
591 fatal (_("no rules in the input grammar"));
592
593 /* Report any undefined symbols and consider them nonterminals. */
594 symbols_check_defined ();
b7c49edf 595
88bce5a2
AD
596 /* If the user did not define her ENDTOKEN, do it now. */
597 if (!endtoken)
b7c49edf 598 {
88bce5a2
AD
599 endtoken = symbol_get ("$end", empty_location);
600 endtoken->class = token_sym;
601 endtoken->number = 0;
b7c49edf 602 /* Value specified by POSIX. */
88bce5a2 603 endtoken->user_token_number = 0;
b7c49edf
AD
604 }
605
02d12d0d 606 /* Insert the initial rule, whose line is that of the first rule
e9955c83
AD
607 (not that of the start symbol):
608
88bce5a2 609 accept: %start EOF. */
e9955c83 610 {
17ee7397 611 symbol_list *p = symbol_list_new (accept, empty_location);
8efe435c
AD
612 p->location = grammar->location;
613 p->next = symbol_list_new (startsymbol, empty_location);
88bce5a2 614 p->next->next = symbol_list_new (endtoken, empty_location);
8efe435c 615 p->next->next->next = symbol_list_new (NULL, empty_location);
e9955c83
AD
616 p->next->next->next->next = grammar;
617 nrules += 1;
618 nritems += 3;
619 grammar = p;
620 }
621
68cae94e 622 assert (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
b0c4483e 623
a70083a3
AD
624 /* Assign the symbols their symbol numbers. Write #defines for the
625 token symbols into FDEFINES if requested. */
2f1afb73 626 symbols_pack ();
93ede233 627
a70083a3
AD
628 /* Convert the grammar into the format described in gram.h. */
629 packgram ();
8419d367 630
17ee7397
PE
631 /* The grammar as a symbol_list is no longer needed. */
632 LIST_FREE (symbol_list, grammar);
a70083a3 633}