]> git.saurik.com Git - bison.git/blame - src/reader.c
Fix code formatting.
[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,
378f4bd8 4 2005, 2006 Free Software Foundation, Inc.
1ff442ca 5
41aca2e0 6 This file is part of Bison, the GNU Compiler Compiler.
1ff442ca 7
41aca2e0
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
1ff442ca 12
41aca2e0
AD
13 Bison is distributed in the hope that it will be useful,
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
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
1ff442ca 22
2cec9080 23#include <config.h>
1ff442ca 24#include "system.h"
e9071366 25#include <assert.h>
17ee7397
PE
26
27#include <quotearg.h>
28
29#include "complain.h"
30#include "conflicts.h"
1ff442ca 31#include "files.h"
17ee7397 32#include "getargs.h"
1ff442ca 33#include "gram.h"
17ee7397 34#include "muscle_tab.h"
b2ca4022 35#include "reader.h"
17ee7397
PE
36#include "symlist.h"
37#include "symtab.h"
e9071366
AD
38#include "scan-gram.h"
39#include "scan-code.h"
1ff442ca 40
02d12d0d
PE
41static void check_and_convert_grammar (void);
42
17ee7397 43static symbol_list *grammar = NULL;
d0829076 44static bool start_flag = false;
676385e2 45merger_list *merge_functions;
1ff442ca 46
34f98f46 47/* Was %union seen? */
d0829076 48bool typed = 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
1ff442ca 70
34f98f46
JD
71/*---------------------------------------------------------------------.
72| There are two prologues: one before the first %union and one after. |
73| Augment the one specified by POST. |
74`---------------------------------------------------------------------*/
1ff442ca 75
e9955c83 76void
34f98f46 77prologue_augment (const char *prologue, location loc, bool post)
b6610515 78{
e9955c83 79 struct obstack *oout =
34f98f46 80 !post ? &pre_prologue_obstack : &post_prologue_obstack;
b6610515 81
05ac60f3 82 obstack_fgrow1 (oout, "]b4_syncline(%d, [[", loc.start.line);
e9071366
AD
83 /* FIXME: Protection of M4 characters missing here. See
84 output.c:escaped_output. */
17ee7397
PE
85 MUSCLE_OBSTACK_SGROW (oout,
86 quotearg_style (c_quoting_style, loc.start.file));
6c239755 87 obstack_sgrow (oout, "]])[\n");
e9955c83 88 obstack_sgrow (oout, prologue);
b6610515
RA
89}
90
a70083a3
AD
91\f
92
3e6656f9 93/*-------------------------------------------------------------------.
676385e2
PH
94| Return the merger index for a merging function named NAME, whose |
95| arguments have type TYPE. Records the function, if new, in |
95612cfa 96| MERGER_LIST. |
676385e2
PH
97`-------------------------------------------------------------------*/
98
99static int
17ee7397 100get_merge_function (uniqstr name, uniqstr type, location loc)
676385e2
PH
101{
102 merger_list *syms;
103 merger_list head;
104 int n;
105
106 if (! glr_parser)
107 return 0;
108
109 if (type == NULL)
17ee7397 110 type = uniqstr_new ("");
676385e2
PH
111
112 head.next = merge_functions;
affac613 113 for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
17ee7397 114 if (UNIQSTR_EQ (name, syms->next->name))
676385e2 115 break;
a5d50994
AD
116 if (syms->next == NULL)
117 {
da2a7671 118 syms->next = xmalloc (sizeof syms->next[0]);
17ee7397
PE
119 syms->next->name = uniqstr_new (name);
120 syms->next->type = uniqstr_new (type);
a5d50994
AD
121 syms->next->next = NULL;
122 merge_functions = head.next;
123 }
17ee7397 124 else if (!UNIQSTR_EQ (type, syms->next->type))
45a8a65d
PE
125 warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
126 name, type, syms->next->type);
676385e2
PH
127 return n;
128}
129
130/*--------------------------------------.
131| Free all merge-function definitions. |
132`--------------------------------------*/
133
134void
135free_merger_functions (void)
136{
affac613
AD
137 merger_list *L0 = merge_functions;
138 while (L0)
676385e2
PH
139 {
140 merger_list *L1 = L0->next;
141 free (L0);
142 L0 = L1;
143 }
144}
145
a70083a3 146\f
107f7dfb 147/*-------------------------------------------------------------------.
17ee7397 148| Parse the input grammar into a one symbol_list structure. Each |
107f7dfb
AD
149| rule is represented by a sequence of symbols: the left hand side |
150| followed by the contents of the right hand side, followed by a |
151| null pointer instead of a symbol to terminate the rule. The next |
152| symbol is the lhs of the following rule. |
153| |
fdbcd8e2
AD
154| All actions are copied out, labelled by the rule number they apply |
155| to. |
107f7dfb 156`-------------------------------------------------------------------*/
1ff442ca 157
f6d0f937 158/* The (currently) last symbol of GRAMMAR. */
04098407 159static symbol_list *grammar_end = NULL;
f6d0f937 160
52328c6e 161/* Append SYM to the grammar. */
8f3596a6 162static void
17ee7397 163grammar_symbol_append (symbol *sym, location loc)
f6d0f937 164{
17ee7397 165 symbol_list *p = symbol_list_new (sym, loc);
f6d0f937
AD
166
167 if (grammar_end)
168 grammar_end->next = p;
169 else
170 grammar = p;
171
172 grammar_end = p;
8f3596a6 173
e3233bf6 174 /* A null SYM stands for an end of rule; it is not an actual
8f3596a6
AD
175 part of it. */
176 if (sym)
177 ++nritems;
f6d0f937
AD
178}
179
8efe435c
AD
180/* The rule currently being defined, and the previous rule.
181 CURRENT_RULE points to the first LHS of the current rule, while
182 PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */
e256e17f 183static symbol_list *current_rule = NULL;
04098407 184static symbol_list *previous_rule_end = NULL;
da4160c3
AD
185
186
8efe435c
AD
187/*----------------------------------------------.
188| Create a new rule for LHS in to the GRAMMAR. |
189`----------------------------------------------*/
da4160c3 190
e9955c83 191void
8f3596a6 192grammar_current_rule_begin (symbol *lhs, location loc)
da4160c3
AD
193{
194 if (!start_flag)
195 {
196 startsymbol = lhs;
17ee7397 197 startsymbol_location = loc;
d0829076 198 start_flag = true;
da4160c3
AD
199 }
200
201 /* Start a new rule and record its lhs. */
202 ++nrules;
8efe435c 203 previous_rule_end = grammar_end;
17ee7397 204 grammar_symbol_append (lhs, loc);
da4160c3
AD
205 current_rule = grammar_end;
206
207 /* Mark the rule's lhs as a nonterminal if not already so. */
da4160c3
AD
208 if (lhs->class == unknown_sym)
209 {
210 lhs->class = nterm_sym;
211 lhs->number = nvars;
212 ++nvars;
213 }
214 else if (lhs->class == token_sym)
17ee7397 215 complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);
da4160c3
AD
216}
217
affac613 218
d40ba6c2
PE
219/*----------------------------------------------------------------------.
220| A symbol should be used if it has a destructor, or if it is a |
221| mid-rule symbol (i.e., the generated LHS replacing a mid-rule |
222| action) that was assigned to, as in "exp: { $$ = 1; } { $$ = $1; }". |
223`----------------------------------------------------------------------*/
84866159
AD
224
225static bool
d40ba6c2 226symbol_should_be_used (symbol_list const *s)
84866159 227{
d40ba6c2 228 return (s->sym->destructor
c66dfadd 229 || (s->midrule && s->midrule->used));
84866159
AD
230}
231
8f3596a6
AD
232/*----------------------------------------------------------------.
233| Check that the rule R is properly defined. For instance, there |
234| should be no type clash on the default action. |
235`----------------------------------------------------------------*/
e9955c83
AD
236
237static void
8f3596a6 238grammar_rule_check (const symbol_list *r)
e9955c83 239{
affac613 240 /* Type check.
e9955c83 241
affac613
AD
242 If there is an action, then there is nothing we can do: the user
243 is allowed to shoot herself in the foot.
3f4c0f80 244
affac613
AD
245 Don't worry about the default action if $$ is untyped, since $$'s
246 value can't be used. */
8f3596a6 247 if (!r->action && r->sym->type_name)
e9955c83 248 {
8f3596a6 249 symbol *first_rhs = r->next->sym;
affac613
AD
250 /* If $$ is being set in default way, report if any type mismatch. */
251 if (first_rhs)
252 {
8f3596a6 253 char const *lhs_type = r->sym->type_name;
affac613
AD
254 const char *rhs_type =
255 first_rhs->type_name ? first_rhs->type_name : "";
256 if (!UNIQSTR_EQ (lhs_type, rhs_type))
8f3596a6 257 warn_at (r->location,
affac613
AD
258 _("type clash on default action: <%s> != <%s>"),
259 lhs_type, rhs_type);
260 }
261 /* Warn if there is no default for $$ but we need one. */
262 else
8f3596a6 263 warn_at (r->location,
affac613
AD
264 _("empty rule for typed nonterminal, and no action"));
265 }
e3233bf6 266
d40ba6c2 267 /* Check that symbol values that should be used are in fact used. */
8f3596a6 268 {
668c5d19 269 symbol_list const *l = r;
8f3596a6
AD
270 int n = 0;
271 for (; l && l->sym; l = l->next, ++n)
272 if (! (l->used
d40ba6c2 273 || !symbol_should_be_used (l)
8f3596a6 274 /* The default action, $$ = $1, `uses' both. */
668c5d19
PE
275 || (!r->action && (n == 0 || n == 1))))
276 {
277 if (n)
278 warn_at (r->location, _("unused value: $%d"), n);
279 else
280 warn_at (r->location, _("unset value: $$"));
281 }
8f3596a6 282 }
e9955c83
AD
283}
284
285
8efe435c
AD
286/*-------------------------------------.
287| End the currently being grown rule. |
288`-------------------------------------*/
e9955c83
AD
289
290void
8f3596a6 291grammar_current_rule_end (location loc)
e9955c83
AD
292{
293 /* Put an empty link in the list to mark the end of this rule */
8efe435c 294 grammar_symbol_append (NULL, grammar_end->location);
17ee7397 295 current_rule->location = loc;
e9955c83
AD
296}
297
298
8efe435c
AD
299/*-------------------------------------------------------------------.
300| The previous action turns out the be a mid-rule action. Attach it |
301| to the current rule, i.e., create a dummy symbol, attach it this |
302| mid-rule action, and append this dummy nonterminal to the current |
303| rule. |
304`-------------------------------------------------------------------*/
1485e106 305
6b702268 306void
1485e106
AD
307grammar_midrule_action (void)
308{
309 /* Since the action was written out with this rule's number, we must
310 give the new rule this number by inserting the new rule before
311 it. */
312
8efe435c
AD
313 /* Make a DUMMY nonterminal, whose location is that of the midrule
314 action. Create the MIDRULE. */
17ee7397
PE
315 location dummy_location = current_rule->action_location;
316 symbol *dummy = dummy_symbol_get (dummy_location);
317 symbol_list *midrule = symbol_list_new (dummy, dummy_location);
1485e106
AD
318
319 /* Make a new rule, whose body is empty, before the current one, so
320 that the action just read can belong to it. */
321 ++nrules;
322 ++nritems;
8efe435c
AD
323 /* Attach its location and actions to that of the DUMMY. */
324 midrule->location = dummy_location;
325 midrule->action = current_rule->action;
326 midrule->action_location = dummy_location;
1485e106 327 current_rule->action = NULL;
ffa4ba3a
JD
328 /* The action has not been translated yet, so $$ use hasn't been
329 detected yet. */
330 midrule->used = false;
1485e106 331
8efe435c
AD
332 if (previous_rule_end)
333 previous_rule_end->next = midrule;
1485e106 334 else
8efe435c 335 grammar = midrule;
1485e106 336
8efe435c 337 /* End the dummy's rule. */
84866159 338 midrule->next = symbol_list_new (NULL, dummy_location);
84866159 339 midrule->next->next = current_rule;
1485e106 340
84866159 341 previous_rule_end = midrule->next;
1485e106 342
8efe435c 343 /* Insert the dummy nonterminal replacing the midrule action into
84866159 344 the current rule. Bind it to its dedicated rule. */
8efe435c 345 grammar_current_rule_symbol_append (dummy, dummy_location);
6ec2c0f2 346 grammar_end->midrule = midrule;
ffa4ba3a
JD
347 midrule->midrule_parent_rule = current_rule;
348 midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
1485e106
AD
349}
350
9af3fbce
AD
351/* Set the precedence symbol of the current rule to PRECSYM. */
352
e9955c83 353void
17ee7397 354grammar_current_rule_prec_set (symbol *precsym, location loc)
9af3fbce
AD
355{
356 if (current_rule->ruleprec)
17ee7397 357 complain_at (loc, _("only one %s allowed per rule"), "%prec");
9af3fbce
AD
358 current_rule->ruleprec = precsym;
359}
360
676385e2
PH
361/* Attach dynamic precedence DPREC to the current rule. */
362
363void
17ee7397 364grammar_current_rule_dprec_set (int dprec, location loc)
676385e2
PH
365{
366 if (! glr_parser)
17ee7397 367 warn_at (loc, _("%s affects only GLR parsers"), "%dprec");
676385e2 368 if (dprec <= 0)
17ee7397 369 complain_at (loc, _("%s must be followed by positive number"), "%dprec");
39f41916 370 else if (current_rule->dprec != 0)
17ee7397 371 complain_at (loc, _("only one %s allowed per rule"), "%dprec");
676385e2
PH
372 current_rule->dprec = dprec;
373}
374
375/* Attach a merge function NAME with argument type TYPE to current
376 rule. */
377
378void
17ee7397 379grammar_current_rule_merge_set (uniqstr name, location loc)
676385e2
PH
380{
381 if (! glr_parser)
17ee7397 382 warn_at (loc, _("%s affects only GLR parsers"), "%merge");
39f41916 383 if (current_rule->merger != 0)
17ee7397 384 complain_at (loc, _("only one %s allowed per rule"), "%merge");
39f41916 385 current_rule->merger =
17ee7397 386 get_merge_function (name, current_rule->sym->type_name, loc);
676385e2
PH
387}
388
17ee7397 389/* Attach SYM to the current rule. If needed, move the previous
2e047461
AD
390 action as a mid-rule action. */
391
e9955c83 392void
17ee7397 393grammar_current_rule_symbol_append (symbol *sym, location loc)
2e047461
AD
394{
395 if (current_rule->action)
396 grammar_midrule_action ();
17ee7397 397 grammar_symbol_append (sym, loc);
2e047461
AD
398}
399
6b702268 400/* Attach an ACTION to the current rule. */
2e047461 401
e9955c83 402void
17ee7397 403grammar_current_rule_action_append (const char *action, location loc)
2e047461 404{
381ecb06
JD
405 if (current_rule->action)
406 grammar_midrule_action ();
ffa4ba3a
JD
407 /* After all symbol declarations have been parsed, packgram invokes
408 translate_rule_action. */
e256e17f 409 current_rule->action = action;
17ee7397 410 current_rule->action_location = loc;
2e047461
AD
411}
412
a70083a3 413\f
a70083a3
AD
414/*---------------------------------------------------------------.
415| Convert the rules into the representation using RRHS, RLHS and |
d9b739c3 416| RITEM. |
a70083a3 417`---------------------------------------------------------------*/
1ff442ca 418
4a120d45 419static void
118fb205 420packgram (void)
1ff442ca 421{
9222837b 422 unsigned int itemno = 0;
17ee7397
PE
423 rule_number ruleno = 0;
424 symbol_list *p = grammar;
1ff442ca 425
e9ad4aec
PE
426 ritem = xnmalloc (nritems + 1, sizeof *ritem);
427
428 /* This sentinel is used by build_relations in gram.c. */
429 *ritem++ = 0;
430
da2a7671 431 rules = xnmalloc (nrules, sizeof *rules);
1ff442ca 432
1ff442ca
NF
433 while (p)
434 {
e9071366 435 int rule_length = 0;
17ee7397 436 symbol *ruleprec = p->ruleprec;
d7e1f00c 437 rules[ruleno].user_number = ruleno;
c3b407f4 438 rules[ruleno].number = ruleno;
bba97eb2 439 rules[ruleno].lhs = p->sym;
99013900 440 rules[ruleno].rhs = ritem + itemno;
da2a7671
PE
441 rules[ruleno].prec = NULL;
442 rules[ruleno].dprec = p->dprec;
443 rules[ruleno].merger = p->merger;
444 rules[ruleno].precsym = NULL;
8efe435c 445 rules[ruleno].location = p->location;
b4afb6bb 446 rules[ruleno].useful = true;
ffa4ba3a 447 rules[ruleno].action = p->action ? translate_rule_action (p) : NULL;
8efe435c 448 rules[ruleno].action_location = p->action_location;
1ff442ca 449
ffa4ba3a 450 /* If this rule contains midrules, rest assured that
ad6b1efa
JD
451 grammar_midrule_action inserted the midrules into grammar before this
452 rule. Thus, the midrule actions have already been scanned in order to
453 set `used' flags for this rule's rhs, so grammar_rule_check will work
454 properly. */
ffa4ba3a
JD
455 grammar_rule_check (p);
456
e9071366 457 for (p = p->next; p && p->sym; p = p->next)
1ff442ca 458 {
e9071366
AD
459 ++rule_length;
460
461 /* Don't allow rule_length == INT_MAX, since that might
462 cause confusion with strtol if INT_MAX == LONG_MAX. */
463 if (rule_length == INT_MAX)
464 fatal_at (rules[ruleno].location, _("rule is too long"));
465
17ee7397 466 /* item_number = symbol_number.
5fbb0954 467 But the former needs to contain more: negative rule numbers. */
a49aecd5 468 ritem[itemno++] = symbol_number_as_item_number (p->sym->number);
1ff442ca 469 /* A rule gets by default the precedence and associativity
e9071366 470 of its last token. */
39a06c25 471 if (p->sym->class == token_sym && default_prec)
03b31c0c 472 rules[ruleno].prec = p->sym;
1ff442ca
NF
473 }
474
475 /* If this rule has a %prec,
a70083a3 476 the specified symbol's precedence replaces the default. */
1ff442ca
NF
477 if (ruleprec)
478 {
03b31c0c
AD
479 rules[ruleno].precsym = ruleprec;
480 rules[ruleno].prec = ruleprec;
1ff442ca 481 }
e9071366 482 /* An item ends by the rule number (negated). */
4b3d3a8e 483 ritem[itemno++] = rule_number_as_item_number (ruleno);
e9071366 484 assert (itemno < ITEM_NUMBER_MAX);
f3849179 485 ++ruleno;
e9071366 486 assert (ruleno < RULE_NUMBER_MAX);
1ff442ca 487
a70083a3
AD
488 if (p)
489 p = p->next;
1ff442ca
NF
490 }
491
68cae94e 492 assert (itemno == nritems);
3067fbef 493
273a74fa 494 if (trace_flag & trace_sets)
3067fbef 495 ritem_print (stderr);
1ff442ca 496}
a70083a3 497\f
fdbcd8e2
AD
498/*------------------------------------------------------------------.
499| Read in the grammar specification and record it in the format |
500| described in gram.h. All actions are copied into ACTION_OBSTACK, |
501| in each case forming the body of a C function (YYACTION) which |
502| contains a switch statement to decide which action to execute. |
503`------------------------------------------------------------------*/
a70083a3
AD
504
505void
506reader (void)
507{
a70083a3 508 /* Initialize the symbol table. */
db8837cb 509 symbols_new ();
b6610515 510
88bce5a2
AD
511 /* Construct the accept symbol. */
512 accept = symbol_get ("$accept", empty_location);
513 accept->class = nterm_sym;
514 accept->number = nvars++;
30171f79 515
a70083a3 516 /* Construct the error token */
39f41916 517 errtoken = symbol_get ("error", empty_location);
d7020c20 518 errtoken->class = token_sym;
72a23c97 519 errtoken->number = ntokens++;
b6610515 520
a70083a3
AD
521 /* Construct a token that represents all undefined literal tokens.
522 It is always token number 2. */
88bce5a2 523 undeftoken = symbol_get ("$undefined", empty_location);
d7020c20 524 undeftoken->class = token_sym;
72a23c97 525 undeftoken->number = ntokens++;
a70083a3 526
331dbc1b 527 /* Initialize the obstacks. */
0dd1580a
RA
528 obstack_init (&pre_prologue_obstack);
529 obstack_init (&post_prologue_obstack);
331dbc1b 530
2b81e969 531 gram_in = xfopen (grammar_file, "r");
e9955c83 532
473d0a75
AD
533 gram__flex_debug = trace_flag & trace_scan;
534 gram_debug = trace_flag & trace_parse;
e9071366 535 gram_scanner_initialize ();
78c3da9e 536 gram_parse ();
331dbc1b 537
02d12d0d
PE
538 if (! complaint_issued)
539 check_and_convert_grammar ();
540
541 xfclose (gram_in);
542}
543
b275314e 544
02d12d0d
PE
545/*-------------------------------------------------------------.
546| Check the grammar that has just been read, and convert it to |
547| internal form. |
548`-------------------------------------------------------------*/
549
550static void
551check_and_convert_grammar (void)
552{
553 /* Grammar has been read. Do some checking. */
e9955c83
AD
554 if (nrules == 0)
555 fatal (_("no rules in the input grammar"));
556
557 /* Report any undefined symbols and consider them nonterminals. */
558 symbols_check_defined ();
b7c49edf 559
88bce5a2
AD
560 /* If the user did not define her ENDTOKEN, do it now. */
561 if (!endtoken)
b7c49edf 562 {
88bce5a2
AD
563 endtoken = symbol_get ("$end", empty_location);
564 endtoken->class = token_sym;
565 endtoken->number = 0;
b7c49edf 566 /* Value specified by POSIX. */
88bce5a2 567 endtoken->user_token_number = 0;
b7c49edf
AD
568 }
569
02d12d0d 570 /* Insert the initial rule, whose line is that of the first rule
e9955c83
AD
571 (not that of the start symbol):
572
88bce5a2 573 accept: %start EOF. */
e9955c83 574 {
17ee7397 575 symbol_list *p = symbol_list_new (accept, empty_location);
8efe435c
AD
576 p->location = grammar->location;
577 p->next = symbol_list_new (startsymbol, empty_location);
88bce5a2 578 p->next->next = symbol_list_new (endtoken, empty_location);
8efe435c 579 p->next->next->next = symbol_list_new (NULL, empty_location);
e9955c83
AD
580 p->next->next->next->next = grammar;
581 nrules += 1;
582 nritems += 3;
583 grammar = p;
584 }
585
68cae94e 586 assert (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
b0c4483e 587
a70083a3
AD
588 /* Assign the symbols their symbol numbers. Write #defines for the
589 token symbols into FDEFINES if requested. */
2f1afb73 590 symbols_pack ();
93ede233 591
a70083a3
AD
592 /* Convert the grammar into the format described in gram.h. */
593 packgram ();
8419d367 594
17ee7397
PE
595 /* The grammar as a symbol_list is no longer needed. */
596 LIST_FREE (symbol_list, grammar);
a70083a3 597}