]> git.saurik.com Git - bison.git/blame - src/output.c
Fix minor troff and spelling glitches.
[bison.git] / src / output.c
CommitLineData
c3e23647 1/* Output the generated parsing program for bison,
5bb18f9a 2 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
255ef638 3 Free Software Foundation, Inc.
c3e23647 4
9ee3c97b 5 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 6
9ee3c97b
AD
7 Bison is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
c3e23647 11
9ee3c97b
AD
12 Bison is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
c3e23647 16
9ee3c97b
AD
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
c3e23647
RS
21
22
c3e23647 23#include "system.h"
14d3eb9b 24#include "quotearg.h"
be2a1a68 25#include "error.h"
573312ac 26#include "subpipe.h"
ceed8467 27#include "getargs.h"
c3e23647
RS
28#include "files.h"
29#include "gram.h"
a0f6b076 30#include "complain.h"
6c89f1c1 31#include "output.h"
a70083a3 32#include "reader.h"
ad949da9 33#include "symtab.h"
c6f1a33c 34#include "tables.h"
11d82f03 35#include "muscle_tab.h"
be2a1a68 36
be2a1a68 37/* From src/scan-skel.l. */
573312ac 38void scan_skel (FILE *);
d019d655 39
12b0043a 40
f87685c3 41static struct obstack format_obstack;
c3e23647 42
c7925b99
MA
43int error_verbose = 0;
44
f0440388 45
133c20e2 46
5372019f
AD
47/*-------------------------------------------------------------------.
48| Create a function NAME which associates to the muscle NAME the |
49| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
50| TYPE), and to the muscle NAME_max, the max value of the |
51| TABLE_DATA. |
52`-------------------------------------------------------------------*/
62a3e4f0 53
62a3e4f0 54
5372019f 55#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
5fbb0954 56 \
5372019f
AD
57static void \
58Name (const char *name, \
5fbb0954
AD
59 Type *table_data, \
60 Type first, \
61 int begin, \
62 int end) \
63{ \
12b0043a 64 Type min = first; \
0c2d3f4c 65 Type max = first; \
5fbb0954
AD
66 int i; \
67 int j = 1; \
68 \
5372019f 69 obstack_fgrow1 (&format_obstack, "%6d", first); \
5fbb0954
AD
70 for (i = begin; i < end; ++i) \
71 { \
5372019f 72 obstack_1grow (&format_obstack, ','); \
5fbb0954
AD
73 if (j >= 10) \
74 { \
5372019f 75 obstack_sgrow (&format_obstack, "\n "); \
5fbb0954
AD
76 j = 1; \
77 } \
78 else \
79 ++j; \
5372019f 80 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
12b0043a
AD
81 if (table_data[i] < min) \
82 min = table_data[i]; \
83 if (max < table_data[i]) \
5fbb0954
AD
84 max = table_data[i]; \
85 } \
5372019f
AD
86 obstack_1grow (&format_obstack, 0); \
87 muscle_insert (name, obstack_finish (&format_obstack)); \
5fbb0954 88 \
12b0043a
AD
89 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
90 obstack_fgrow1 (&format_obstack, "%s_min", name); \
91 obstack_1grow (&format_obstack, 0); \
92 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
93 (long int) min); \
5372019f
AD
94 obstack_fgrow1 (&format_obstack, "%s_max", name); \
95 obstack_1grow (&format_obstack, 0); \
0c2d3f4c
AD
96 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
97 (long int) max); \
62a3e4f0
AD
98}
99
5372019f 100GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
12b0043a 101GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
5372019f 102GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_short_table, short)
12b0043a
AD
103GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_t)
104GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number_t)
a49aecd5 105GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number_t)
5372019f 106GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number_t)
d57650a5 107GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number_t)
c3e23647
RS
108
109
39912f52
AD
110/*------------------------------------------------------------------.
111| Prepare the muscles related to the symbols: translate, tname, and |
112| toknum. |
113`------------------------------------------------------------------*/
b0940840 114
4a120d45 115static void
39912f52 116prepare_symbols (void)
c3e23647 117{
39912f52
AD
118 MUSCLE_INSERT_INT ("tokens_number", ntokens);
119 MUSCLE_INSERT_INT ("nterms_number", nvars);
120 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
121 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
122
a49aecd5 123 muscle_insert_symbol_number_table ("translate",
fc5734fe
AD
124 token_translations,
125 token_translations[0],
126 1, max_user_token_number + 1);
c3e23647 127
39912f52 128 /* tname -- token names. */
b0940840
AD
129 {
130 int i;
131 int j = 0;
132 for (i = 0; i < nsyms; i++)
133 {
6b98e4b5
AD
134 /* Be sure not to use twice the same QUOTEARG slot:
135 SYMBOL_TAG_GET uses slot 0. */
b0940840
AD
136 const char *cp =
137 quotearg_n_style (1, c_quoting_style,
97650f4e 138 symbols[i]->tag);
01cfa697 139 /* Width of the next token, including the two quotes, the comma
b0940840
AD
140 and the space. */
141 int strsize = strlen (cp) + 2;
142
143 if (j + strsize > 75)
144 {
145 obstack_sgrow (&format_obstack, "\n ");
146 j = 2;
147 }
148
01cfa697
PE
149 for (; *cp; cp++)
150 switch (*cp)
151 {
152 case '[': obstack_sgrow (&format_obstack, "@<:@"); break;
153 case ']': obstack_sgrow (&format_obstack, "@:>@"); break;
154 default: obstack_1grow (&format_obstack, *cp); break;
155 }
156
b0940840
AD
157 obstack_sgrow (&format_obstack, ", ");
158 j += strsize;
159 }
160 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
161 defined). */
162 obstack_sgrow (&format_obstack, "0");
c3e23647 163
b0940840
AD
164 /* Finish table and store. */
165 obstack_1grow (&format_obstack, 0);
166 muscle_insert ("tname", obstack_finish (&format_obstack));
167 }
168
12b0043a 169 /* Output YYTOKNUM. */
b2ed6e58
AD
170 {
171 int i;
3650b4b8
AD
172 int *values = XCALLOC (int, ntokens);
173 for (i = 0; i < ntokens; ++i)
b0940840 174 values[i] = symbols[i]->user_token_number;
12b0043a 175 muscle_insert_int_table ("toknum", values,
3650b4b8 176 values[0], 1, ntokens);
b0940840 177 free (values);
b2ed6e58 178 }
b0940840 179}
b2ed6e58 180
b0940840
AD
181
182/*-------------------------------------------------------------.
183| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
676385e2 184| rline, dprec, merger |
b0940840
AD
185`-------------------------------------------------------------*/
186
187static void
188prepare_rules (void)
189{
9222837b 190 rule_number_t r;
5df5f6d5 191 unsigned int i = 0;
62a3e4f0 192 item_number_t *rhs = XMALLOC (item_number_t, nritems);
4b3d3a8e
AD
193 unsigned int *prhs = XMALLOC (unsigned int, nrules);
194 unsigned int *rline = XMALLOC (unsigned int, nrules);
195 symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules);
196 unsigned int *r2 = XMALLOC (unsigned int, nrules);
197 short *dprec = XMALLOC (short, nrules);
198 short *merger = XMALLOC (short, nrules);
199
200 for (r = 0; r < nrules; ++r)
b0940840 201 {
9222837b 202 item_number_t *rhsp = NULL;
b0940840
AD
203 /* Index of rule R in RHS. */
204 prhs[r] = i;
205 /* RHS of the rule R. */
206 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
207 rhs[i++] = *rhsp;
208 /* LHS of the rule R. */
209 r1[r] = rules[r].lhs->number;
210 /* Length of rule R's RHS. */
211 r2[r] = i - prhs[r];
212 /* Separator in RHS. */
213 rhs[i++] = -1;
214 /* Line where rule was defined. */
8efe435c 215 rline[r] = rules[r].location.first_line;
676385e2
PH
216 /* Dynamic precedence (GLR) */
217 dprec[r] = rules[r].dprec;
218 /* Merger-function index (GLR) */
219 merger[r] = rules[r].merger;
b0940840
AD
220 }
221 assert (i == nritems);
222
5372019f 223 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
4b3d3a8e
AD
224 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
225 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
226 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
227 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
228 muscle_insert_short_table ("dprec", dprec, 0, 0, nrules);
229 muscle_insert_short_table ("merger", merger, 0, 0, nrules);
796d61fb 230
39912f52
AD
231 MUSCLE_INSERT_INT ("rules_number", nrules);
232
b0940840
AD
233 free (rhs);
234 free (prhs);
5df5f6d5
AD
235 free (rline);
236 free (r1);
b0940840 237 free (r2);
676385e2
PH
238 free (dprec);
239 free (merger);
c3e23647
RS
240}
241
b0940840
AD
242/*--------------------------------------------.
243| Prepare the muscles related to the states. |
244`--------------------------------------------*/
c3e23647 245
4a120d45 246static void
b0940840 247prepare_states (void)
c3e23647 248{
d57650a5 249 state_number_t i;
a49aecd5
AD
250 symbol_number_t *values =
251 (symbol_number_t *) alloca (sizeof (symbol_number_t) * nstates);
9703cc49 252 for (i = 0; i < nstates; ++i)
29e88316 253 values[i] = states[i]->accessing_symbol;
a49aecd5 254 muscle_insert_symbol_number_table ("stos", values,
d57650a5 255 0, 1, nstates);
39912f52
AD
256
257 MUSCLE_INSERT_INT ("last", high);
258 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
259 MUSCLE_INSERT_INT ("states_number", nstates);
c3e23647
RS
260}
261
262
c3e23647 263
bb33f19a
PE
264/*---------------------------------.
265| Output the user actions to OUT. |
266`---------------------------------*/
12b0043a 267
4a120d45 268static void
c6f1a33c 269user_actions_output (FILE *out)
3f96f4dc 270{
9222837b 271 rule_number_t r;
dafdc66f
AD
272
273 fputs ("m4_define([b4_actions], \n[[", out);
4b3d3a8e 274 for (r = 0; r < nrules; ++r)
9222837b 275 if (rules[r].action)
3f96f4dc 276 {
4b3d3a8e 277 fprintf (out, " case %d:\n", r + 1);
3f96f4dc 278
437c2d80
AD
279 fprintf (out, "]b4_syncline([[%d]], [[%s]])[\n",
280 rules[r].action_location.first_line,
281 quotearg_style (escape_quoting_style,
282 rules[r].action_location.file));
e9955c83 283 fprintf (out, " %s\n break;\n\n",
9222837b 284 rules[r].action);
3f96f4dc 285 }
dafdc66f 286 fputs ("]])\n\n", out);
3f96f4dc
AD
287}
288
676385e2
PH
289/*--------------------------------------.
290| Output the merge functions to OUT. |
291`--------------------------------------*/
292
41442480 293static void
676385e2
PH
294merger_output (FILE *out)
295{
296 int n;
297 merger_list* p;
298
299 fputs ("m4_define([b4_mergers], \n[[", out);
e0e5bf84 300 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
676385e2 301 {
e0e5bf84 302 if (p->type[0] == '\0')
676385e2
PH
303 fprintf (out, " case %d: yyval = %s (*yy0, *yy1); break;\n",
304 n, p->name);
305 else
306 fprintf (out, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
307 n, p->type, p->name);
308 }
309 fputs ("]])\n\n", out);
310}
3f96f4dc 311
ae7453f2
AD
312/*--------------------------------------.
313| Output the tokens definition to OUT. |
314`--------------------------------------*/
091e20bb 315
c6f1a33c 316static void
be2a1a68 317token_definitions_output (FILE *out)
091e20bb
AD
318{
319 int i;
0d8bed56 320 int first = 1;
dafdc66f
AD
321
322 fputs ("m4_define([b4_tokens], \n[", out);
091e20bb
AD
323 for (i = 0; i < ntokens; ++i)
324 {
db8837cb 325 symbol_t *symbol = symbols[i];
091e20bb
AD
326 int number = symbol->user_token_number;
327
b87f8b21
AD
328 /* At this stage, if there are literal aliases, they are part of
329 SYMBOLS, so we should not find symbols which are the aliases
330 here. */
331 assert (number != USER_NUMBER_ALIAS);
332
091e20bb 333 /* Skip error token. */
007a50a4 334 if (symbol == errtoken)
091e20bb 335 continue;
b87f8b21
AD
336
337 /* If this string has an alias, then it is necessarily the alias
338 which is to be output. */
339 if (symbol->alias)
340 symbol = symbol->alias;
341
342 /* Don't output literal chars or strings (when defined only as a
343 string). Note that must be done after the alias resolution:
344 think about `%token 'f' "f"'. */
345 if (symbol->tag[0] == '\'' || symbol->tag[0] == '\"')
346 continue;
091e20bb
AD
347
348 /* Don't #define nonliteral tokens whose names contain periods
349 or '$' (as does the default value of the EOF token). */
350 if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$'))
351 continue;
352
83ccf991 353 fprintf (out, "%s[[[%s]], [%d]]",
0d8bed56 354 first ? "" : ",\n", symbol->tag, number);
b87f8b21 355
0d8bed56 356 first = 0;
091e20bb 357 }
dafdc66f 358 fputs ("])\n\n", out);
091e20bb
AD
359}
360
361
ae7453f2
AD
362/*---------------------------------------.
363| Output the symbol destructors to OUT. |
364`---------------------------------------*/
9280d3ef
AD
365
366static void
367symbol_destructors_output (FILE *out)
368{
369 int i;
370 int first = 1;
371
372 fputs ("m4_define([b4_symbol_destructors], \n[", out);
373 for (i = 0; i < nsyms; ++i)
374 if (symbols[i]->destructor)
375 {
376 symbol_t *symbol = symbols[i];
377
24c0aad7
AD
378 /* Filename, lineno,
379 Symbol-name, Symbol-number,
380 destructor, typename. */
381 fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
9280d3ef 382 first ? "" : ",\n",
6e40b4eb
AD
383 quotearg_style (escape_quoting_style,
384 symbol->destructor_location.file),
900c5db5 385 symbol->destructor_location.first_line,
97650f4e 386 symbol->tag,
24c0aad7
AD
387 symbol->number,
388 symbol->destructor,
389 symbol->type_name);
9280d3ef
AD
390
391 first = 0;
392 }
393 fputs ("])\n\n", out);
394}
395
396
ae7453f2
AD
397/*------------------------------------.
398| Output the symbol printers to OUT. |
399`------------------------------------*/
366eea36
AD
400
401static void
402symbol_printers_output (FILE *out)
403{
404 int i;
405 int first = 1;
406
407 fputs ("m4_define([b4_symbol_printers], \n[", out);
408 for (i = 0; i < nsyms; ++i)
409 if (symbols[i]->destructor)
410 {
411 symbol_t *symbol = symbols[i];
412
413 /* Filename, lineno,
414 Symbol-name, Symbol-number,
ae7453f2 415 printer, typename. */
366eea36
AD
416 fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
417 first ? "" : ",\n",
6e40b4eb
AD
418 quotearg_style (escape_quoting_style,
419 symbol->printer_location.file),
900c5db5 420 symbol->printer_location.first_line,
97650f4e 421 symbol->tag,
366eea36
AD
422 symbol->number,
423 symbol->printer,
424 symbol->type_name);
425
426 first = 0;
427 }
428 fputs ("])\n\n", out);
429}
430
431
4a120d45 432static void
c6f1a33c 433prepare_actions (void)
6c89f1c1 434{
c6f1a33c
AD
435 /* Figure out the actions for the specified state, indexed by
436 lookahead token type. */
bbb5bcc6 437
c6f1a33c
AD
438 muscle_insert_rule_number_table ("defact", yydefact,
439 yydefact[0], 1, nstates);
6c89f1c1 440
c6f1a33c
AD
441 /* Figure out what to do after reducing with each rule, depending on
442 the saved state from before the beginning of parsing the data
443 that matched this rule. */
d57650a5
AD
444 muscle_insert_state_number_table ("defgoto", yydefgoto,
445 yydefgoto[0], 1, nsyms - ntokens);
12b0043a 446
12b0043a 447
12b0043a
AD
448 /* Output PACT. */
449 muscle_insert_base_table ("pact", base,
5372019f 450 base[0], 1, nstates);
12b0043a 451 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
c3e23647 452
12b0043a
AD
453 /* Output PGOTO. */
454 muscle_insert_base_table ("pgoto", base,
5372019f 455 base[nstates], nstates + 1, nvectors);
c3e23647 456
12b0043a
AD
457 muscle_insert_base_table ("table", table,
458 table[0], 1, high + 1);
459 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
676385e2 460
12b0043a
AD
461 muscle_insert_base_table ("check", check,
462 check[0], 1, high + 1);
c3e23647 463
ea99527d
AD
464 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
465 YYPACT) so that in states with unresolved conflicts, the default
466 reduction is not used in the conflicted entries, so that there is
467 a place to put a conflict pointer.
468
469 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
470 parser, so we could avoid accidents by not writing them out in
471 that case. Nevertheless, it seems even better to be able to use
472 the GLR skeletons even without the non-deterministic tables. */
473 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
39912f52 474 conflict_table[0], 1, high + 1);
ea99527d
AD
475 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
476 conflict_list[0], 1, conflict_list_cnt);
6c89f1c1 477}
c3e23647 478
652def80 479\f
1239777d
AD
480/*---------------------------.
481| Call the skeleton parser. |
482`---------------------------*/
c3e23647 483
4a120d45 484static void
1239777d 485output_skeleton (void)
9b3add5b 486{
573312ac
PE
487 FILE *in;
488 FILE *out;
489 int filter_fd[2];
490 char const *argv[7];
491 pid_t pid;
492
493 /* Compute the names of the package data dir and skeleton file.
494 Test whether m4sugar.m4 is readable, to check for proper
495 installation. A faulty installation can cause deadlock, so a
496 cheap sanity check is worthwhile. */
497 char const m4sugar[] = "m4sugar/m4sugar.m4";
498 char *full_path;
499 char const *p;
500 char const *m4 = (p = getenv ("M4")) ? p : M4;
501 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
502 size_t skeleton_size = strlen (skeleton) + 1;
503 size_t pkgdatadirlen = strlen (pkgdatadir);
504 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
505 pkgdatadirlen--;
506 full_path = xmalloc (pkgdatadirlen + 1
507 + (skeleton_size < sizeof m4sugar
508 ? sizeof m4sugar : skeleton_size));
509 strcpy (full_path, pkgdatadir);
510 full_path[pkgdatadirlen] = '/';
511 strcpy (full_path + pkgdatadirlen + 1, m4sugar);
512 in = fopen (full_path, "r");
30ba05f2 513 if (! in)
573312ac 514 error (EXIT_FAILURE, errno, "%s", full_path);
30ba05f2 515 xfclose (in);
573312ac
PE
516 strcpy (full_path + pkgdatadirlen + 1, skeleton);
517
518 /* Create an m4 subprocess connected to us via two pipes. */
519
520 if (trace_flag & trace_tools)
521 fprintf (stderr, "running: %s -I %s %s - %s\n",
522 m4, pkgdatadir, m4sugar, full_path);
523
524 argv[0] = m4;
525 argv[1] = "-I";
526 argv[2] = pkgdatadir;
527 argv[3] = m4sugar;
528 argv[4] = "-";
529 argv[5] = full_path;
530 argv[6] = NULL;
531
532 init_subpipe ();
533 pid = create_subpipe (argv, filter_fd);
534 free (full_path);
535
536 out = fdopen (filter_fd[0], "w");
537 if (! out)
538 error (EXIT_FAILURE, errno, "fdopen");
539
540 /* Output the definitions of all the muscles. */
381fb12e
AD
541 fputs ("m4_init()\n", out);
542
c6f1a33c 543 user_actions_output (out);
676385e2 544 merger_output (out);
381fb12e 545 token_definitions_output (out);
9280d3ef 546 symbol_destructors_output (out);
366eea36 547 symbol_printers_output (out);
be2a1a68 548
381fb12e 549 muscles_m4_output (out);
be2a1a68 550
381fb12e
AD
551 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
552 fputs ("m4_divert_push(0)dnl\n", out);
553 xfclose (out);
be2a1a68 554
573312ac 555 /* Read and process m4's output. */
1509d42f 556 timevar_push (TV_M4);
573312ac
PE
557 in = fdopen (filter_fd[1], "r");
558 if (! in)
559 error (EXIT_FAILURE, errno, "fdopen");
560 scan_skel (in);
573312ac
PE
561 xfclose (in);
562 reap_subpipe (pid, m4);
1509d42f 563 timevar_pop (TV_M4);
26f609ff
RA
564}
565
566static void
567prepare (void)
568{
7db2ed2d 569 /* Flags. */
437c2d80 570 MUSCLE_INSERT_INT ("debug", debug_flag);
7db2ed2d
AD
571 MUSCLE_INSERT_INT ("defines_flag", defines_flag);
572 MUSCLE_INSERT_INT ("error_verbose", error_verbose);
437c2d80 573 MUSCLE_INSERT_INT ("locations_flag", locations_flag);
11d82f03 574 MUSCLE_INSERT_INT ("pure", pure_parser);
437c2d80 575 MUSCLE_INSERT_INT ("synclines_flag", !no_lines_flag);
11d82f03 576
b85810ae
AD
577 /* FIXME: This is wrong: the muscles should decide whether they hold
578 a copy or not, but the situation is too obscure currently. */
7db2ed2d 579 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
be2a1a68
AD
580 MUSCLE_INSERT_STRING ("output_infix", output_infix ? output_infix : "");
581 MUSCLE_INSERT_STRING ("output_prefix", short_base_name);
582 MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name);
583 MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file);
b85810ae 584
7db2ed2d 585 /* User Code. */
0dd1580a
RA
586 obstack_1grow (&pre_prologue_obstack, 0);
587 obstack_1grow (&post_prologue_obstack, 0);
588 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
589 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
381fb12e
AD
590
591 /* Find the right skeleton file. */
592 if (!skeleton)
676385e2
PH
593 {
594 if (glr_parser)
595 skeleton = "glr.c";
596 else
597 skeleton = "yacc.c";
598 }
381fb12e
AD
599
600 /* Parse the skeleton file and output the needed parsers. */
66d30cd4 601 MUSCLE_INSERT_STRING ("skeleton", skeleton);
26f609ff 602}
c3e23647 603
93ede233 604
6c89f1c1
AD
605/*----------------------------------------------------------.
606| Output the parsing tables and the parser code to ftable. |
607`----------------------------------------------------------*/
c3e23647 608
6c89f1c1
AD
609void
610output (void)
611{
f87685c3 612 obstack_init (&format_obstack);
dd60faec 613
39912f52 614 prepare_symbols ();
b0940840
AD
615 prepare_rules ();
616 prepare_states ();
536545f3 617 prepare_actions ();
342b8b6e 618
26f609ff 619 prepare ();
652def80 620
9b3add5b
RA
621 /* Process the selected skeleton file. */
622 output_skeleton ();
623
f499b062 624 obstack_free (&format_obstack, NULL);
0dd1580a
RA
625 obstack_free (&pre_prologue_obstack, NULL);
626 obstack_free (&post_prologue_obstack, NULL);
c3e23647 627}