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