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