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