]> git.saurik.com Git - bison.git/blame - src/reader.c
maint: prepare forthcoming changes
[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
26#include "complain.h"
27#include "conflicts.h"
1ff442ca 28#include "files.h"
17ee7397 29#include "getargs.h"
1ff442ca 30#include "gram.h"
00f5d575 31#include "muscle-tab.h"
b2ca4022 32#include "reader.h"
17ee7397
PE
33#include "symlist.h"
34#include "symtab.h"
e9071366
AD
35#include "scan-gram.h"
36#include "scan-code.h"
1ff442ca 37
dfaa4860 38static void prepare_percent_define_front_end_variables (void);
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)
6fb8b256 62 complain_at (loc, complaint, _("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 96 /* After all symbol type declarations have been parsed, packgram invokes
e9690142 97 record_merge_function_type to set the type. */
8ee5b538 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 {
6fb8b256 131 complain_at (declaration_loc, complaint,
5ff5cf67
VS
132 _("result type clash on merge function %s: <%s> != <%s>"),
133 quote (merge_function->name), type, merge_function->type);
6fb8b256 134 complain_at (merge_function->type_declaration_location, complaint,
5ff5cf67 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 141/*--------------------------------------.
e9690142 142| Free all merge-function definitions. |
676385e2
PH
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. */
b9f1d9a4 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;
b9f1d9a4
AR
189
190 return p;
f6d0f937
AD
191}
192
872b52bc 193static void
ba4184ec 194assign_named_ref (symbol_list *p, named_ref *name)
872b52bc
AR
195{
196 symbol *sym = p->content.sym;
197
ba4184ec 198 if (name->id == sym->tag)
872b52bc 199 {
6fb8b256
VS
200 complain_at (name->loc, Wother,
201 _("duplicated symbol name for %s ignored"),
202 quote (sym->tag));
ba4184ec 203 named_ref_free (name);
872b52bc
AR
204 }
205 else
ba4184ec 206 p->named_ref = name;
872b52bc
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
b9f1d9a4 222grammar_current_rule_begin (symbol *lhs, location loc,
e9690142 223 named_ref *lhs_name)
da4160c3 224{
b9f1d9a4
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;
b9f1d9a4
AR
230
231 p = grammar_symbol_append (lhs, loc);
ba4184ec 232 if (lhs_name)
a4d1bf6a 233 assign_named_ref (p, named_ref_copy (lhs_name));
b9f1d9a4 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)
6fb8b256
VS
245 complain_at (loc, complaint, _("rule given for %s, which is a token"),
246 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{
71da68b3 261 if (symbol_code_props_get (s->content.sym, destructor)->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))
6fb8b256
VS
300 complain_at (r->location, Wother,
301 _("type clash on default action: <%s> != <%s>"),
302 lhs_type, rhs_type);
e9690142 303 }
affac613
AD
304 /* Warn if there is no default for $$ but we need one. */
305 else
6fb8b256
VS
306 complain_at (r->location, Wother,
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 {
5ff5cf67 322 warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
c39014ae 323 if (n)
6fb8b256 324 complain_at (r->location, warn_flag, _("unused value: $%d"), n);
c39014ae 325 else
6fb8b256 326 complain_at (r->location, warn_flag, _("unset value: $$"));
c39014ae
JD
327 }
328 }
8f3596a6 329 }
8bb3a2e7
JD
330
331 /* See comments in grammar_current_rule_prec_set for how POSIX
332 mandates this complaint. It's only for identifiers, so skip
333 it for char literals and strings, which are always tokens. */
334 if (r->ruleprec
335 && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
b921d92f 336 && r->ruleprec->status != declared && !r->ruleprec->prec)
6fb8b256
VS
337 complain_at (r->location, Wother,
338 _("token for %%prec is not defined: %s"), r->ruleprec->tag);
e9955c83
AD
339}
340
341
8efe435c
AD
342/*-------------------------------------.
343| End the currently being grown rule. |
344`-------------------------------------*/
e9955c83
AD
345
346void
8f3596a6 347grammar_current_rule_end (location loc)
e9955c83
AD
348{
349 /* Put an empty link in the list to mark the end of this rule */
8efe435c 350 grammar_symbol_append (NULL, grammar_end->location);
17ee7397 351 current_rule->location = loc;
e9955c83
AD
352}
353
354
8efe435c
AD
355/*-------------------------------------------------------------------.
356| The previous action turns out the be a mid-rule action. Attach it |
357| to the current rule, i.e., create a dummy symbol, attach it this |
358| mid-rule action, and append this dummy nonterminal to the current |
359| rule. |
360`-------------------------------------------------------------------*/
1485e106 361
6b702268 362void
1485e106
AD
363grammar_midrule_action (void)
364{
365 /* Since the action was written out with this rule's number, we must
366 give the new rule this number by inserting the new rule before
367 it. */
368
8efe435c
AD
369 /* Make a DUMMY nonterminal, whose location is that of the midrule
370 action. Create the MIDRULE. */
f6857bbf 371 location dummy_location = current_rule->action_props.location;
17ee7397 372 symbol *dummy = dummy_symbol_get (dummy_location);
3be03b13 373 symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
1485e106 374
872b52bc 375 /* Remember named_ref of previous action. */
ba4184ec 376 named_ref *action_name = current_rule->action_props.named_ref;
b9f1d9a4 377
1485e106
AD
378 /* Make a new rule, whose body is empty, before the current one, so
379 that the action just read can belong to it. */
380 ++nrules;
381 ++nritems;
8efe435c
AD
382 /* Attach its location and actions to that of the DUMMY. */
383 midrule->location = dummy_location;
f6857bbf
JD
384 code_props_rule_action_init (&midrule->action_props,
385 current_rule->action_props.code,
386 current_rule->action_props.location,
ca2a6d15 387 midrule, 0,
e9690142 388 current_rule->action_props.is_predicate);
f6857bbf 389 code_props_none_init (&current_rule->action_props);
1485e106 390
8efe435c
AD
391 if (previous_rule_end)
392 previous_rule_end->next = midrule;
1485e106 393 else
8efe435c 394 grammar = midrule;
1485e106 395
8efe435c 396 /* End the dummy's rule. */
3be03b13 397 midrule->next = symbol_list_sym_new (NULL, dummy_location);
84866159 398 midrule->next->next = current_rule;
1485e106 399
84866159 400 previous_rule_end = midrule->next;
1485e106 401
8efe435c 402 /* Insert the dummy nonterminal replacing the midrule action into
84866159 403 the current rule. Bind it to its dedicated rule. */
ba4184ec
AR
404 grammar_current_rule_symbol_append (dummy, dummy_location,
405 action_name);
6ec2c0f2 406 grammar_end->midrule = midrule;
ffa4ba3a
JD
407 midrule->midrule_parent_rule = current_rule;
408 midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
1485e106
AD
409}
410
9af3fbce
AD
411/* Set the precedence symbol of the current rule to PRECSYM. */
412
e9955c83 413void
17ee7397 414grammar_current_rule_prec_set (symbol *precsym, location loc)
9af3fbce 415{
8bb3a2e7
JD
416 /* POSIX says that any identifier is a nonterminal if it does not
417 appear on the LHS of a grammar rule and is not defined by %token
418 or by one of the directives that assigns precedence to a token. We
419 ignore this here because the only kind of identifier that POSIX
420 allows to follow a %prec is a token and because assuming it's a
421 token now can produce more logical error messages. Nevertheless,
422 grammar_rule_check does obey what we believe is the real intent of
423 POSIX here: that an error be reported for any identifier that
424 appears after %prec but that is not defined separately as a
425 token. */
26b8a438 426 symbol_class_set (precsym, token_sym, loc, false);
9af3fbce 427 if (current_rule->ruleprec)
6fb8b256 428 complain_at (loc, complaint, _("only one %s allowed per rule"), "%prec");
9af3fbce
AD
429 current_rule->ruleprec = precsym;
430}
431
676385e2
PH
432/* Attach dynamic precedence DPREC to the current rule. */
433
434void
17ee7397 435grammar_current_rule_dprec_set (int dprec, location loc)
676385e2
PH
436{
437 if (! glr_parser)
6fb8b256
VS
438 complain_at (loc, Wother, _("%s affects only GLR parsers"),
439 "%dprec");
676385e2 440 if (dprec <= 0)
6fb8b256
VS
441 complain_at (loc, complaint, _("%s must be followed by positive number"),
442 "%dprec");
39f41916 443 else if (current_rule->dprec != 0)
6fb8b256 444 complain_at (loc, complaint, _("only one %s allowed per rule"), "%dprec");
676385e2
PH
445 current_rule->dprec = dprec;
446}
447
448/* Attach a merge function NAME with argument type TYPE to current
449 rule. */
450
451void
17ee7397 452grammar_current_rule_merge_set (uniqstr name, location loc)
676385e2
PH
453{
454 if (! glr_parser)
6fb8b256
VS
455 complain_at (loc, Wother, _("%s affects only GLR parsers"),
456 "%merge");
39f41916 457 if (current_rule->merger != 0)
6fb8b256 458 complain_at (loc, complaint, _("only one %s allowed per rule"), "%merge");
8ee5b538
JD
459 current_rule->merger = get_merge_function (name);
460 current_rule->merger_declaration_location = loc;
676385e2
PH
461}
462
17ee7397 463/* Attach SYM to the current rule. If needed, move the previous
2e047461
AD
464 action as a mid-rule action. */
465
e9955c83 466void
b9f1d9a4 467grammar_current_rule_symbol_append (symbol *sym, location loc,
e9690142 468 named_ref *name)
2e047461 469{
b9f1d9a4 470 symbol_list *p;
f6857bbf 471 if (current_rule->action_props.code)
2e047461 472 grammar_midrule_action ();
b9f1d9a4 473 p = grammar_symbol_append (sym, loc);
ba4184ec
AR
474 if (name)
475 assign_named_ref(p, name);
3b0b682f
AD
476 if (sym->status == undeclared || sym->status == used)
477 sym->status = needed;
2e047461
AD
478}
479
6b702268 480/* Attach an ACTION to the current rule. */
2e047461 481
e9955c83 482void
b9f1d9a4 483grammar_current_rule_action_append (const char *action, location loc,
e9690142 484 named_ref *name, bool is_predicate)
2e047461 485{
f6857bbf 486 if (current_rule->action_props.code)
381ecb06 487 grammar_midrule_action ();
ffa4ba3a 488 /* After all symbol declarations have been parsed, packgram invokes
f6857bbf
JD
489 code_props_translate_code. */
490 code_props_rule_action_init (&current_rule->action_props, action, loc,
ca2a6d15 491 current_rule, name, is_predicate);
2e047461
AD
492}
493
a70083a3 494\f
a70083a3
AD
495/*---------------------------------------------------------------.
496| Convert the rules into the representation using RRHS, RLHS and |
d9b739c3 497| RITEM. |
a70083a3 498`---------------------------------------------------------------*/
1ff442ca 499
4a120d45 500static void
118fb205 501packgram (void)
1ff442ca 502{
9222837b 503 unsigned int itemno = 0;
17ee7397
PE
504 rule_number ruleno = 0;
505 symbol_list *p = grammar;
1ff442ca 506
e9ad4aec
PE
507 ritem = xnmalloc (nritems + 1, sizeof *ritem);
508
509 /* This sentinel is used by build_relations in gram.c. */
510 *ritem++ = 0;
511
da2a7671 512 rules = xnmalloc (nrules, sizeof *rules);
1ff442ca 513
1ff442ca
NF
514 while (p)
515 {
e9071366 516 int rule_length = 0;
17ee7397 517 symbol *ruleprec = p->ruleprec;
3be03b13 518 record_merge_function_type (p->merger, p->content.sym->type_name,
e9690142 519 p->merger_declaration_location);
d7e1f00c 520 rules[ruleno].user_number = ruleno;
c3b407f4 521 rules[ruleno].number = ruleno;
3be03b13 522 rules[ruleno].lhs = p->content.sym;
99013900 523 rules[ruleno].rhs = ritem + itemno;
da2a7671
PE
524 rules[ruleno].prec = NULL;
525 rules[ruleno].dprec = p->dprec;
526 rules[ruleno].merger = p->merger;
527 rules[ruleno].precsym = NULL;
8efe435c 528 rules[ruleno].location = p->location;
b4afb6bb 529 rules[ruleno].useful = true;
f6857bbf
JD
530 rules[ruleno].action = p->action_props.code;
531 rules[ruleno].action_location = p->action_props.location;
ca2a6d15 532 rules[ruleno].is_predicate = p->action_props.is_predicate;
1ff442ca 533
f91b1629 534 /* If the midrule's $$ is set or its $n is used, remove the `$' from the
e9690142
JD
535 symbol name so that it's a user-defined symbol so that the default
536 %destructor and %printer apply. */
f91b1629 537 if (p->midrule_parent_rule
f6857bbf 538 && (p->action_props.is_value_used
e9690142
JD
539 || symbol_list_n_get (p->midrule_parent_rule,
540 p->midrule_parent_rhs_index)
f6857bbf 541 ->action_props.is_value_used))
e9690142 542 p->content.sym->tag += 1;
f91b1629 543
868d2d96 544 /* Don't check the generated rule 0. It has no action, so some rhs
e9690142
JD
545 symbols may appear unused, but the parsing algorithm ensures that
546 %destructor's are invoked appropriately. */
868d2d96 547 if (p != grammar)
e9690142 548 grammar_rule_check (p);
ffa4ba3a 549
3be03b13 550 for (p = p->next; p && p->content.sym; p = p->next)
e9690142
JD
551 {
552 ++rule_length;
e9071366 553
e9690142
JD
554 /* Don't allow rule_length == INT_MAX, since that might
555 cause confusion with strtol if INT_MAX == LONG_MAX. */
556 if (rule_length == INT_MAX)
6fb8b256 557 complain_at (rules[ruleno].location, fatal, _("rule is too long"));
e9071366 558
e9690142
JD
559 /* item_number = symbol_number.
560 But the former needs to contain more: negative rule numbers. */
561 ritem[itemno++] =
3be03b13 562 symbol_number_as_item_number (p->content.sym->number);
e9690142
JD
563 /* A rule gets by default the precedence and associativity
564 of its last token. */
565 if (p->content.sym->class == token_sym && default_prec)
566 rules[ruleno].prec = p->content.sym;
567 }
1ff442ca
NF
568
569 /* If this rule has a %prec,
a70083a3 570 the specified symbol's precedence replaces the default. */
1ff442ca 571 if (ruleprec)
e9690142
JD
572 {
573 rules[ruleno].precsym = ruleprec;
574 rules[ruleno].prec = ruleprec;
575 }
e9071366 576 /* An item ends by the rule number (negated). */
4b3d3a8e 577 ritem[itemno++] = rule_number_as_item_number (ruleno);
4f82b42a 578 aver (itemno < ITEM_NUMBER_MAX);
f3849179 579 ++ruleno;
4f82b42a 580 aver (ruleno < RULE_NUMBER_MAX);
1ff442ca 581
a70083a3 582 if (p)
e9690142 583 p = p->next;
1ff442ca
NF
584 }
585
4f82b42a 586 aver (itemno == nritems);
3067fbef 587
273a74fa 588 if (trace_flag & trace_sets)
3067fbef 589 ritem_print (stderr);
1ff442ca 590}
a70083a3 591\f
fdbcd8e2
AD
592/*------------------------------------------------------------------.
593| Read in the grammar specification and record it in the format |
594| described in gram.h. All actions are copied into ACTION_OBSTACK, |
595| in each case forming the body of a C function (YYACTION) which |
596| contains a switch statement to decide which action to execute. |
597`------------------------------------------------------------------*/
a70083a3
AD
598
599void
600reader (void)
601{
a70083a3 602 /* Initialize the symbol table. */
db8837cb 603 symbols_new ();
b6610515 604
88bce5a2
AD
605 /* Construct the accept symbol. */
606 accept = symbol_get ("$accept", empty_location);
607 accept->class = nterm_sym;
608 accept->number = nvars++;
30171f79 609
a70083a3 610 /* Construct the error token */
39f41916 611 errtoken = symbol_get ("error", empty_location);
d7020c20 612 errtoken->class = token_sym;
72a23c97 613 errtoken->number = ntokens++;
b6610515 614
a70083a3
AD
615 /* Construct a token that represents all undefined literal tokens.
616 It is always token number 2. */
88bce5a2 617 undeftoken = symbol_get ("$undefined", empty_location);
d7020c20 618 undeftoken->class = token_sym;
72a23c97 619 undeftoken->number = ntokens++;
a70083a3 620
2b81e969 621 gram_in = xfopen (grammar_file, "r");
e9955c83 622
473d0a75
AD
623 gram__flex_debug = trace_flag & trace_scan;
624 gram_debug = trace_flag & trace_parse;
e9071366 625 gram_scanner_initialize ();
78c3da9e 626 gram_parse ();
dfaa4860 627 prepare_percent_define_front_end_variables ();
331dbc1b 628
dfaa4860
JD
629 if (! complaint_issued)
630 check_and_convert_grammar ();
631
632 xfclose (gram_in);
633}
634
635static void
636prepare_percent_define_front_end_variables (void)
637{
638 /* Set %define front-end variable defaults. */
67212941 639 muscle_percent_define_default ("lr.keep-unreachable-states", "false");
db34f798
JD
640 {
641 char *lr_type;
ba5c6d94
JD
642 /* IELR would be a better default, but LALR is historically the
643 default. */
6ba96404 644 muscle_percent_define_default ("lr.type", "lalr");
db34f798 645 lr_type = muscle_percent_define_get ("lr.type");
f518dbaf 646 if (STRNEQ (lr_type, "canonical-lr"))
f0ad1b2f 647 muscle_percent_define_default ("lr.default-reductions", "most");
db34f798 648 else
5bab9d08 649 muscle_percent_define_default ("lr.default-reductions", "accepting");
db34f798
JD
650 free (lr_type);
651 }
7254f6a8 652
dfaa4860 653 /* Check %define front-end variables. */
7254f6a8
JD
654 {
655 static char const * const values[] = {
6ba96404 656 "lr.type", "lalr", "ielr", "canonical-lr", NULL,
f0ad1b2f 657 "lr.default-reductions", "most", "consistent", "accepting", NULL,
7254f6a8
JD
658 NULL
659 };
660 muscle_percent_define_check_values (values);
661 }
02d12d0d
PE
662}
663
b275314e 664
02d12d0d
PE
665/*-------------------------------------------------------------.
666| Check the grammar that has just been read, and convert it to |
e9690142 667| internal form. |
02d12d0d
PE
668`-------------------------------------------------------------*/
669
670static void
671check_and_convert_grammar (void)
672{
673 /* Grammar has been read. Do some checking. */
e9955c83 674 if (nrules == 0)
6fb8b256 675 complain (fatal, _("no rules in the input grammar"));
e9955c83 676
88bce5a2
AD
677 /* If the user did not define her ENDTOKEN, do it now. */
678 if (!endtoken)
b7c49edf 679 {
88bce5a2
AD
680 endtoken = symbol_get ("$end", empty_location);
681 endtoken->class = token_sym;
682 endtoken->number = 0;
b7c49edf 683 /* Value specified by POSIX. */
88bce5a2 684 endtoken->user_token_number = 0;
b7c49edf
AD
685 }
686
83b60c97
JD
687 /* Report any undefined symbols and consider them nonterminals. */
688 symbols_check_defined ();
689
4d7370cb
JD
690 /* Find the start symbol if no %start. */
691 if (!start_flag)
692 {
693 symbol_list *node;
694 for (node = grammar;
3be03b13 695 node != NULL && symbol_is_dummy (node->content.sym);
4d7370cb
JD
696 node = node->next)
697 {
698 for (node = node->next;
3be03b13 699 node != NULL && node->content.sym != NULL;
4d7370cb
JD
700 node = node->next)
701 ;
702 }
4f82b42a 703 aver (node != NULL);
3be03b13
JD
704 grammar_start_symbol_set (node->content.sym,
705 node->content.sym->location);
4d7370cb
JD
706 }
707
02d12d0d 708 /* Insert the initial rule, whose line is that of the first rule
e9955c83
AD
709 (not that of the start symbol):
710
88bce5a2 711 accept: %start EOF. */
e9955c83 712 {
3be03b13 713 symbol_list *p = symbol_list_sym_new (accept, empty_location);
8efe435c 714 p->location = grammar->location;
3be03b13
JD
715 p->next = symbol_list_sym_new (startsymbol, empty_location);
716 p->next->next = symbol_list_sym_new (endtoken, empty_location);
717 p->next->next->next = symbol_list_sym_new (NULL, empty_location);
e9955c83
AD
718 p->next->next->next->next = grammar;
719 nrules += 1;
720 nritems += 3;
721 grammar = p;
722 }
723
4f82b42a 724 aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
b0c4483e 725
a70083a3
AD
726 /* Assign the symbols their symbol numbers. Write #defines for the
727 token symbols into FDEFINES if requested. */
2f1afb73 728 symbols_pack ();
93ede233 729
574add85
JD
730 /* Scan rule actions after invoking symbol_check_alias_consistency (in
731 symbols_pack above) so that token types are set correctly before the rule
732 action type checking.
733
734 Before invoking grammar_rule_check (in packgram below) on any rule, make
735 sure all actions have already been scanned in order to set `used' flags.
736 Otherwise, checking that a midrule's $$ should be set will not always work
737 properly because the check must forward-reference the midrule's parent
738 rule. For the same reason, all the `used' flags must be set before
739 checking whether to remove `$' from any midrule symbol name (also in
740 packgram). */
14462c2b
JD
741 {
742 symbol_list *sym;
743 for (sym = grammar; sym; sym = sym->next)
744 code_props_translate_code (&sym->action_props);
745 }
574add85 746
a70083a3 747 /* Convert the grammar into the format described in gram.h. */
6d0ef4ec 748 packgram ();
8419d367 749
17ee7397 750 /* The grammar as a symbol_list is no longer needed. */
17bd8a73 751 symbol_list_free (grammar);
a70083a3 752}