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