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