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