]> git.saurik.com Git - bison.git/blame - src/reader.c
Convert "misleading reference" messages to warnings.
[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
d5e8574b 193static void
992e874a 194assign_named_ref (symbol_list *p, named_ref *name)
d5e8574b
AR
195{
196 symbol *sym = p->content.sym;
197
992e874a 198 if (name->id == sym->tag)
d5e8574b 199 {
992e874a 200 warn_at (name->loc,
d5e8574b
AR
201 _("duplicated symbol name for %s ignored"),
202 quote (sym->tag));
992e874a 203 named_ref_free (name);
d5e8574b
AR
204 }
205 else
992e874a 206 p->named_ref = name;
d5e8574b
AR
207}
208
209
8efe435c
AD
210/* The rule currently being defined, and the previous rule.
211 CURRENT_RULE points to the first LHS of the current rule, while
212 PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */
e256e17f 213static symbol_list *current_rule = NULL;
04098407 214static symbol_list *previous_rule_end = NULL;
da4160c3
AD
215
216
8efe435c
AD
217/*----------------------------------------------.
218| Create a new rule for LHS in to the GRAMMAR. |
219`----------------------------------------------*/
da4160c3 220
e9955c83 221void
7685e2f7 222grammar_current_rule_begin (symbol *lhs, location loc,
992e874a 223 named_ref *lhs_name)
da4160c3 224{
7685e2f7
AR
225 symbol_list* p;
226
da4160c3
AD
227 /* Start a new rule and record its lhs. */
228 ++nrules;
8efe435c 229 previous_rule_end = grammar_end;
7685e2f7
AR
230
231 p = grammar_symbol_append (lhs, loc);
992e874a
AR
232 if (lhs_name)
233 assign_named_ref(p, lhs_name);
7685e2f7 234
da4160c3
AD
235 current_rule = grammar_end;
236
237 /* Mark the rule's lhs as a nonterminal if not already so. */
da4160c3
AD
238 if (lhs->class == unknown_sym)
239 {
240 lhs->class = nterm_sym;
241 lhs->number = nvars;
242 ++nvars;
243 }
244 else if (lhs->class == token_sym)
17ee7397 245 complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);
da4160c3
AD
246}
247
affac613 248
d40ba6c2 249/*----------------------------------------------------------------------.
17bd8a73
JD
250| A symbol should be used if either: |
251| 1. It has a destructor. |
252| 2. --warnings=midrule-values and the symbol is a mid-rule symbol |
253| (i.e., the generated LHS replacing a mid-rule action) that was |
254| assigned to or used, as in "exp: { $$ = 1; } { $$ = $1; }". |
d40ba6c2 255`----------------------------------------------------------------------*/
84866159
AD
256
257static bool
d40ba6c2 258symbol_should_be_used (symbol_list const *s)
84866159 259{
95021767 260 if (symbol_destructor_get (s->content.sym)->code)
17bd8a73
JD
261 return true;
262 if (warnings_flag & warnings_midrule_values)
f6857bbf 263 return ((s->midrule && s->midrule->action_props.is_value_used)
b0f4c4ea
JD
264 || (s->midrule_parent_rule
265 && symbol_list_n_get (s->midrule_parent_rule,
f6857bbf
JD
266 s->midrule_parent_rhs_index)
267 ->action_props.is_value_used));
17bd8a73 268 return false;
84866159
AD
269}
270
8f3596a6
AD
271/*----------------------------------------------------------------.
272| Check that the rule R is properly defined. For instance, there |
273| should be no type clash on the default action. |
274`----------------------------------------------------------------*/
e9955c83
AD
275
276static void
8f3596a6 277grammar_rule_check (const symbol_list *r)
e9955c83 278{
affac613 279 /* Type check.
e9955c83 280
affac613
AD
281 If there is an action, then there is nothing we can do: the user
282 is allowed to shoot herself in the foot.
3f4c0f80 283
affac613
AD
284 Don't worry about the default action if $$ is untyped, since $$'s
285 value can't be used. */
f6857bbf 286 if (!r->action_props.code && r->content.sym->type_name)
e9955c83 287 {
3be03b13 288 symbol *first_rhs = r->next->content.sym;
affac613
AD
289 /* If $$ is being set in default way, report if any type mismatch. */
290 if (first_rhs)
291 {
3be03b13 292 char const *lhs_type = r->content.sym->type_name;
affac613
AD
293 const char *rhs_type =
294 first_rhs->type_name ? first_rhs->type_name : "";
295 if (!UNIQSTR_EQ (lhs_type, rhs_type))
8f3596a6 296 warn_at (r->location,
affac613
AD
297 _("type clash on default action: <%s> != <%s>"),
298 lhs_type, rhs_type);
299 }
300 /* Warn if there is no default for $$ but we need one. */
301 else
8f3596a6 302 warn_at (r->location,
affac613
AD
303 _("empty rule for typed nonterminal, and no action"));
304 }
e3233bf6 305
d40ba6c2 306 /* Check that symbol values that should be used are in fact used. */
8f3596a6 307 {
668c5d19 308 symbol_list const *l = r;
8f3596a6 309 int n = 0;
3be03b13 310 for (; l && l->content.sym; l = l->next, ++n)
f6857bbf 311 if (! (l->action_props.is_value_used
d40ba6c2 312 || !symbol_should_be_used (l)
8f3596a6 313 /* The default action, $$ = $1, `uses' both. */
f6857bbf 314 || (!r->action_props.code && (n == 0 || n == 1))))
668c5d19
PE
315 {
316 if (n)
317 warn_at (r->location, _("unused value: $%d"), n);
318 else
319 warn_at (r->location, _("unset value: $$"));
320 }
8f3596a6 321 }
e9955c83
AD
322}
323
324
8efe435c
AD
325/*-------------------------------------.
326| End the currently being grown rule. |
327`-------------------------------------*/
e9955c83
AD
328
329void
8f3596a6 330grammar_current_rule_end (location loc)
e9955c83
AD
331{
332 /* Put an empty link in the list to mark the end of this rule */
8efe435c 333 grammar_symbol_append (NULL, grammar_end->location);
17ee7397 334 current_rule->location = loc;
e9955c83
AD
335}
336
337
8efe435c
AD
338/*-------------------------------------------------------------------.
339| The previous action turns out the be a mid-rule action. Attach it |
340| to the current rule, i.e., create a dummy symbol, attach it this |
341| mid-rule action, and append this dummy nonterminal to the current |
342| rule. |
343`-------------------------------------------------------------------*/
1485e106 344
6b702268 345void
1485e106
AD
346grammar_midrule_action (void)
347{
348 /* Since the action was written out with this rule's number, we must
349 give the new rule this number by inserting the new rule before
350 it. */
351
8efe435c
AD
352 /* Make a DUMMY nonterminal, whose location is that of the midrule
353 action. Create the MIDRULE. */
f6857bbf 354 location dummy_location = current_rule->action_props.location;
17ee7397 355 symbol *dummy = dummy_symbol_get (dummy_location);
3be03b13 356 symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
1485e106 357
d5e8574b 358 /* Remember named_ref of previous action. */
992e874a 359 named_ref *action_name = current_rule->action_props.named_ref;
7685e2f7 360
1485e106
AD
361 /* Make a new rule, whose body is empty, before the current one, so
362 that the action just read can belong to it. */
363 ++nrules;
364 ++nritems;
8efe435c
AD
365 /* Attach its location and actions to that of the DUMMY. */
366 midrule->location = dummy_location;
f6857bbf
JD
367 code_props_rule_action_init (&midrule->action_props,
368 current_rule->action_props.code,
369 current_rule->action_props.location,
7685e2f7 370 midrule, 0);
f6857bbf 371 code_props_none_init (&current_rule->action_props);
1485e106 372
8efe435c
AD
373 if (previous_rule_end)
374 previous_rule_end->next = midrule;
1485e106 375 else
8efe435c 376 grammar = midrule;
1485e106 377
8efe435c 378 /* End the dummy's rule. */
3be03b13 379 midrule->next = symbol_list_sym_new (NULL, dummy_location);
84866159 380 midrule->next->next = current_rule;
1485e106 381
84866159 382 previous_rule_end = midrule->next;
1485e106 383
8efe435c 384 /* Insert the dummy nonterminal replacing the midrule action into
84866159 385 the current rule. Bind it to its dedicated rule. */
992e874a
AR
386 grammar_current_rule_symbol_append (dummy, dummy_location,
387 action_name);
6ec2c0f2 388 grammar_end->midrule = midrule;
ffa4ba3a
JD
389 midrule->midrule_parent_rule = current_rule;
390 midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
1485e106
AD
391}
392
9af3fbce
AD
393/* Set the precedence symbol of the current rule to PRECSYM. */
394
e9955c83 395void
17ee7397 396grammar_current_rule_prec_set (symbol *precsym, location loc)
9af3fbce 397{
26b8a438 398 symbol_class_set (precsym, token_sym, loc, false);
9af3fbce 399 if (current_rule->ruleprec)
17ee7397 400 complain_at (loc, _("only one %s allowed per rule"), "%prec");
9af3fbce
AD
401 current_rule->ruleprec = precsym;
402}
403
676385e2
PH
404/* Attach dynamic precedence DPREC to the current rule. */
405
406void
17ee7397 407grammar_current_rule_dprec_set (int dprec, location loc)
676385e2
PH
408{
409 if (! glr_parser)
17ee7397 410 warn_at (loc, _("%s affects only GLR parsers"), "%dprec");
676385e2 411 if (dprec <= 0)
17ee7397 412 complain_at (loc, _("%s must be followed by positive number"), "%dprec");
39f41916 413 else if (current_rule->dprec != 0)
17ee7397 414 complain_at (loc, _("only one %s allowed per rule"), "%dprec");
676385e2
PH
415 current_rule->dprec = dprec;
416}
417
418/* Attach a merge function NAME with argument type TYPE to current
419 rule. */
420
421void
17ee7397 422grammar_current_rule_merge_set (uniqstr name, location loc)
676385e2
PH
423{
424 if (! glr_parser)
17ee7397 425 warn_at (loc, _("%s affects only GLR parsers"), "%merge");
39f41916 426 if (current_rule->merger != 0)
17ee7397 427 complain_at (loc, _("only one %s allowed per rule"), "%merge");
8ee5b538
JD
428 current_rule->merger = get_merge_function (name);
429 current_rule->merger_declaration_location = loc;
676385e2
PH
430}
431
17ee7397 432/* Attach SYM to the current rule. If needed, move the previous
2e047461
AD
433 action as a mid-rule action. */
434
e9955c83 435void
7685e2f7 436grammar_current_rule_symbol_append (symbol *sym, location loc,
992e874a 437 named_ref *name)
2e047461 438{
7685e2f7 439 symbol_list *p;
f6857bbf 440 if (current_rule->action_props.code)
2e047461 441 grammar_midrule_action ();
7685e2f7 442 p = grammar_symbol_append (sym, loc);
992e874a
AR
443 if (name)
444 assign_named_ref(p, name);
2e047461
AD
445}
446
6b702268 447/* Attach an ACTION to the current rule. */
2e047461 448
e9955c83 449void
7685e2f7 450grammar_current_rule_action_append (const char *action, location loc,
992e874a 451 named_ref *name)
2e047461 452{
f6857bbf 453 if (current_rule->action_props.code)
381ecb06 454 grammar_midrule_action ();
ffa4ba3a 455 /* After all symbol declarations have been parsed, packgram invokes
f6857bbf
JD
456 code_props_translate_code. */
457 code_props_rule_action_init (&current_rule->action_props, action, loc,
992e874a 458 current_rule, name);
2e047461
AD
459}
460
a70083a3 461\f
a70083a3
AD
462/*---------------------------------------------------------------.
463| Convert the rules into the representation using RRHS, RLHS and |
d9b739c3 464| RITEM. |
a70083a3 465`---------------------------------------------------------------*/
1ff442ca 466
4a120d45 467static void
118fb205 468packgram (void)
1ff442ca 469{
9222837b 470 unsigned int itemno = 0;
17ee7397
PE
471 rule_number ruleno = 0;
472 symbol_list *p = grammar;
1ff442ca 473
e9ad4aec
PE
474 ritem = xnmalloc (nritems + 1, sizeof *ritem);
475
476 /* This sentinel is used by build_relations in gram.c. */
477 *ritem++ = 0;
478
da2a7671 479 rules = xnmalloc (nrules, sizeof *rules);
1ff442ca 480
1ff442ca
NF
481 while (p)
482 {
e9071366 483 int rule_length = 0;
17ee7397 484 symbol *ruleprec = p->ruleprec;
3be03b13 485 record_merge_function_type (p->merger, p->content.sym->type_name,
8ee5b538 486 p->merger_declaration_location);
d7e1f00c 487 rules[ruleno].user_number = ruleno;
c3b407f4 488 rules[ruleno].number = ruleno;
3be03b13 489 rules[ruleno].lhs = p->content.sym;
99013900 490 rules[ruleno].rhs = ritem + itemno;
da2a7671
PE
491 rules[ruleno].prec = NULL;
492 rules[ruleno].dprec = p->dprec;
493 rules[ruleno].merger = p->merger;
494 rules[ruleno].precsym = NULL;
8efe435c 495 rules[ruleno].location = p->location;
b4afb6bb 496 rules[ruleno].useful = true;
f6857bbf
JD
497 rules[ruleno].action = p->action_props.code;
498 rules[ruleno].action_location = p->action_props.location;
1ff442ca 499
f91b1629
JD
500 /* If the midrule's $$ is set or its $n is used, remove the `$' from the
501 symbol name so that it's a user-defined symbol so that the default
502 %destructor and %printer apply. */
503 if (p->midrule_parent_rule
f6857bbf 504 && (p->action_props.is_value_used
b0f4c4ea 505 || symbol_list_n_get (p->midrule_parent_rule,
f6857bbf
JD
506 p->midrule_parent_rhs_index)
507 ->action_props.is_value_used))
f91b1629
JD
508 p->content.sym->tag += 1;
509
868d2d96
JD
510 /* Don't check the generated rule 0. It has no action, so some rhs
511 symbols may appear unused, but the parsing algorithm ensures that
512 %destructor's are invoked appropriately. */
513 if (p != grammar)
514 grammar_rule_check (p);
ffa4ba3a 515
3be03b13 516 for (p = p->next; p && p->content.sym; p = p->next)
1ff442ca 517 {
e9071366
AD
518 ++rule_length;
519
520 /* Don't allow rule_length == INT_MAX, since that might
521 cause confusion with strtol if INT_MAX == LONG_MAX. */
522 if (rule_length == INT_MAX)
523 fatal_at (rules[ruleno].location, _("rule is too long"));
524
17ee7397 525 /* item_number = symbol_number.
5fbb0954 526 But the former needs to contain more: negative rule numbers. */
3be03b13
JD
527 ritem[itemno++] =
528 symbol_number_as_item_number (p->content.sym->number);
1ff442ca 529 /* A rule gets by default the precedence and associativity
e9071366 530 of its last token. */
3be03b13
JD
531 if (p->content.sym->class == token_sym && default_prec)
532 rules[ruleno].prec = p->content.sym;
1ff442ca
NF
533 }
534
535 /* If this rule has a %prec,
a70083a3 536 the specified symbol's precedence replaces the default. */
1ff442ca
NF
537 if (ruleprec)
538 {
03b31c0c
AD
539 rules[ruleno].precsym = ruleprec;
540 rules[ruleno].prec = ruleprec;
1ff442ca 541 }
e9071366 542 /* An item ends by the rule number (negated). */
4b3d3a8e 543 ritem[itemno++] = rule_number_as_item_number (ruleno);
4f82b42a 544 aver (itemno < ITEM_NUMBER_MAX);
f3849179 545 ++ruleno;
4f82b42a 546 aver (ruleno < RULE_NUMBER_MAX);
1ff442ca 547
a70083a3
AD
548 if (p)
549 p = p->next;
1ff442ca
NF
550 }
551
4f82b42a 552 aver (itemno == nritems);
3067fbef 553
273a74fa 554 if (trace_flag & trace_sets)
3067fbef 555 ritem_print (stderr);
1ff442ca 556}
a70083a3 557\f
fdbcd8e2
AD
558/*------------------------------------------------------------------.
559| Read in the grammar specification and record it in the format |
560| described in gram.h. All actions are copied into ACTION_OBSTACK, |
561| in each case forming the body of a C function (YYACTION) which |
562| contains a switch statement to decide which action to execute. |
563`------------------------------------------------------------------*/
a70083a3
AD
564
565void
566reader (void)
567{
a70083a3 568 /* Initialize the symbol table. */
db8837cb 569 symbols_new ();
b6610515 570
88bce5a2
AD
571 /* Construct the accept symbol. */
572 accept = symbol_get ("$accept", empty_location);
573 accept->class = nterm_sym;
574 accept->number = nvars++;
30171f79 575
a70083a3 576 /* Construct the error token */
39f41916 577 errtoken = symbol_get ("error", empty_location);
d7020c20 578 errtoken->class = token_sym;
72a23c97 579 errtoken->number = ntokens++;
b6610515 580
a70083a3
AD
581 /* Construct a token that represents all undefined literal tokens.
582 It is always token number 2. */
88bce5a2 583 undeftoken = symbol_get ("$undefined", empty_location);
d7020c20 584 undeftoken->class = token_sym;
72a23c97 585 undeftoken->number = ntokens++;
a70083a3 586
2b81e969 587 gram_in = xfopen (grammar_file, "r");
e9955c83 588
473d0a75
AD
589 gram__flex_debug = trace_flag & trace_scan;
590 gram_debug = trace_flag & trace_parse;
e9071366 591 gram_scanner_initialize ();
78c3da9e 592 gram_parse ();
331dbc1b 593
1c4aa81d 594 /* Set front-end %define variable defaults. */
812775a0 595 muscle_percent_define_default ("lr.keep-unreachable-states", "false");
f805dfcb
JD
596 {
597 char *lr_type;
1c4aa81d
JD
598 /* IELR would be a better default, but LALR is historically the
599 default. */
f805dfcb
JD
600 muscle_percent_define_default ("lr.type", "LALR");
601 lr_type = muscle_percent_define_get ("lr.type");
602 if (0 != strcmp (lr_type, "canonical LR"))
1d0f55cc 603 muscle_percent_define_default ("lr.default-reductions", "all");
f805dfcb 604 else
1d0f55cc 605 muscle_percent_define_default ("lr.default-reductions", "accepting");
f805dfcb
JD
606 free (lr_type);
607 }
03c07b03 608
1c4aa81d 609 /* Check front-end %define variables. */
03c07b03
JD
610 {
611 static char const * const values[] = {
f805dfcb 612 "lr.type", "LALR", "IELR", "canonical LR", NULL,
1d0f55cc 613 "lr.default-reductions", "all", "consistent", "accepting", NULL,
03c07b03
JD
614 NULL
615 };
616 muscle_percent_define_check_values (values);
617 }
618
02d12d0d
PE
619 if (! complaint_issued)
620 check_and_convert_grammar ();
621
622 xfclose (gram_in);
623}
624
b275314e 625
02d12d0d
PE
626/*-------------------------------------------------------------.
627| Check the grammar that has just been read, and convert it to |
628| internal form. |
629`-------------------------------------------------------------*/
630
631static void
632check_and_convert_grammar (void)
633{
634 /* Grammar has been read. Do some checking. */
e9955c83
AD
635 if (nrules == 0)
636 fatal (_("no rules in the input grammar"));
637
638 /* Report any undefined symbols and consider them nonterminals. */
639 symbols_check_defined ();
b7c49edf 640
88bce5a2
AD
641 /* If the user did not define her ENDTOKEN, do it now. */
642 if (!endtoken)
b7c49edf 643 {
88bce5a2
AD
644 endtoken = symbol_get ("$end", empty_location);
645 endtoken->class = token_sym;
646 endtoken->number = 0;
b7c49edf 647 /* Value specified by POSIX. */
88bce5a2 648 endtoken->user_token_number = 0;
b7c49edf
AD
649 }
650
4d7370cb
JD
651 /* Find the start symbol if no %start. */
652 if (!start_flag)
653 {
654 symbol_list *node;
655 for (node = grammar;
3be03b13 656 node != NULL && symbol_is_dummy (node->content.sym);
4d7370cb
JD
657 node = node->next)
658 {
659 for (node = node->next;
3be03b13 660 node != NULL && node->content.sym != NULL;
4d7370cb
JD
661 node = node->next)
662 ;
663 }
4f82b42a 664 aver (node != NULL);
3be03b13
JD
665 grammar_start_symbol_set (node->content.sym,
666 node->content.sym->location);
4d7370cb
JD
667 }
668
02d12d0d 669 /* Insert the initial rule, whose line is that of the first rule
e9955c83
AD
670 (not that of the start symbol):
671
88bce5a2 672 accept: %start EOF. */
e9955c83 673 {
3be03b13 674 symbol_list *p = symbol_list_sym_new (accept, empty_location);
8efe435c 675 p->location = grammar->location;
3be03b13
JD
676 p->next = symbol_list_sym_new (startsymbol, empty_location);
677 p->next->next = symbol_list_sym_new (endtoken, empty_location);
678 p->next->next->next = symbol_list_sym_new (NULL, empty_location);
e9955c83
AD
679 p->next->next->next->next = grammar;
680 nrules += 1;
681 nritems += 3;
682 grammar = p;
683 }
684
4f82b42a 685 aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
b0c4483e 686
a70083a3
AD
687 /* Assign the symbols their symbol numbers. Write #defines for the
688 token symbols into FDEFINES if requested. */
2f1afb73 689 symbols_pack ();
93ede233 690
574add85
JD
691 /* Scan rule actions after invoking symbol_check_alias_consistency (in
692 symbols_pack above) so that token types are set correctly before the rule
693 action type checking.
694
695 Before invoking grammar_rule_check (in packgram below) on any rule, make
696 sure all actions have already been scanned in order to set `used' flags.
697 Otherwise, checking that a midrule's $$ should be set will not always work
698 properly because the check must forward-reference the midrule's parent
699 rule. For the same reason, all the `used' flags must be set before
700 checking whether to remove `$' from any midrule symbol name (also in
701 packgram). */
14462c2b
JD
702 {
703 symbol_list *sym;
704 for (sym = grammar; sym; sym = sym->next)
705 code_props_translate_code (&sym->action_props);
706 }
574add85 707
a70083a3 708 /* Convert the grammar into the format described in gram.h. */
6d0ef4ec 709 packgram ();
8419d367 710
17ee7397 711 /* The grammar as a symbol_list is no longer needed. */
17bd8a73 712 symbol_list_free (grammar);
a70083a3 713}