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