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