]> git.saurik.com Git - bison.git/blame - src/output.c
* src/files.c: Include "stdio-safer.h"; this fixes a typo in
[bison.git] / src / output.c
CommitLineData
a932883e 1/* Output the generated parsing program for Bison.
87ceef73 2
05ac60f3 3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005
255ef638 4 Free Software Foundation, Inc.
c3e23647 5
9ee3c97b 6 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 7
9ee3c97b
AD
8 Bison is free software; you can redistribute it and/or modify it
9 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.
c3e23647 12
9ee3c97b
AD
13 Bison is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
c3e23647 17
9ee3c97b
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 the Free
0fb669f9
PE
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
c3e23647
RS
22
23
c3e23647 24#include "system.h"
21fd22d6
PE
25
26#include <error.h>
27#include <get-errno.h>
28#include <quotearg.h>
29#include <subpipe.h>
30#include <timevar.h>
31
32#include "complain.h"
c3e23647 33#include "files.h"
21fd22d6 34#include "getargs.h"
c3e23647 35#include "gram.h"
21fd22d6 36#include "muscle_tab.h"
6c89f1c1 37#include "output.h"
a70083a3 38#include "reader.h"
ad949da9 39#include "symtab.h"
c6f1a33c 40#include "tables.h"
be2a1a68 41
be2a1a68 42/* From src/scan-skel.l. */
573312ac 43void scan_skel (FILE *);
d019d655 44
12b0043a 45
f87685c3 46static struct obstack format_obstack;
c3e23647 47
d0829076 48bool error_verbose = false;
c7925b99 49
f0440388 50
133c20e2 51
5372019f
AD
52/*-------------------------------------------------------------------.
53| Create a function NAME which associates to the muscle NAME the |
54| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
55| TYPE), and to the muscle NAME_max, the max value of the |
56| TABLE_DATA. |
57`-------------------------------------------------------------------*/
62a3e4f0 58
62a3e4f0 59
5372019f 60#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
5fbb0954 61 \
5372019f
AD
62static void \
63Name (const char *name, \
5fbb0954
AD
64 Type *table_data, \
65 Type first, \
66 int begin, \
67 int end) \
68{ \
12b0043a 69 Type min = first; \
0c2d3f4c 70 Type max = first; \
87ceef73
PE
71 long int lmin; \
72 long int lmax; \
5fbb0954
AD
73 int i; \
74 int j = 1; \
75 \
5372019f 76 obstack_fgrow1 (&format_obstack, "%6d", first); \
5fbb0954
AD
77 for (i = begin; i < end; ++i) \
78 { \
5372019f 79 obstack_1grow (&format_obstack, ','); \
5fbb0954
AD
80 if (j >= 10) \
81 { \
5372019f 82 obstack_sgrow (&format_obstack, "\n "); \
5fbb0954
AD
83 j = 1; \
84 } \
85 else \
86 ++j; \
5372019f 87 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
12b0043a
AD
88 if (table_data[i] < min) \
89 min = table_data[i]; \
90 if (max < table_data[i]) \
5fbb0954
AD
91 max = table_data[i]; \
92 } \
5372019f
AD
93 obstack_1grow (&format_obstack, 0); \
94 muscle_insert (name, obstack_finish (&format_obstack)); \
5fbb0954 95 \
87ceef73
PE
96 lmin = min; \
97 lmax = max; \
12b0043a
AD
98 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
99 obstack_fgrow1 (&format_obstack, "%s_min", name); \
100 obstack_1grow (&format_obstack, 0); \
87ceef73 101 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \
5372019f
AD
102 obstack_fgrow1 (&format_obstack, "%s_max", name); \
103 obstack_1grow (&format_obstack, 0); \
87ceef73 104 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \
62a3e4f0
AD
105}
106
5372019f 107GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
12b0043a 108GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
21fd22d6
PE
109GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
110GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
111GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
112GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
113GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
c3e23647
RS
114
115
05ac60f3
PE
116/*--------------------------------------------------------------------.
117| Print to OUT a representation of STRING escaped both for C and M4. |
118`--------------------------------------------------------------------*/
3813e141
PE
119
120static void
05ac60f3 121escaped_output (FILE *out, char const *string)
3813e141
PE
122{
123 char const *p;
124 fprintf (out, "[[");
125
05ac60f3 126 for (p = quotearg_style (c_quoting_style, string); *p; p++)
3813e141
PE
127 switch (*p)
128 {
129 case '$': fputs ("$][", out); break;
130 case '@': fputs ("@@", out); break;
131 case '[': fputs ("@{", out); break;
132 case ']': fputs ("@}", out); break;
133 default: fputc (*p, out); break;
134 }
135
136 fprintf (out, "]]");
137}
138
139
39912f52
AD
140/*------------------------------------------------------------------.
141| Prepare the muscles related to the symbols: translate, tname, and |
142| toknum. |
143`------------------------------------------------------------------*/
b0940840 144
4a120d45 145static void
39912f52 146prepare_symbols (void)
c3e23647 147{
39912f52
AD
148 MUSCLE_INSERT_INT ("tokens_number", ntokens);
149 MUSCLE_INSERT_INT ("nterms_number", nvars);
150 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
151 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
152
a49aecd5 153 muscle_insert_symbol_number_table ("translate",
fc5734fe
AD
154 token_translations,
155 token_translations[0],
156 1, max_user_token_number + 1);
c3e23647 157
39912f52 158 /* tname -- token names. */
b0940840
AD
159 {
160 int i;
d423d460
AD
161 /* We assume that the table will be output starting at column 2. */
162 int j = 2;
b0940840
AD
163 for (i = 0; i < nsyms; i++)
164 {
72f000b0
PE
165 char const *tag = symbols[i]->tag;
166 char const *cp = (*tag == '"'
167 ? tag
168 : quotearg_style (c_quoting_style, tag));
d423d460
AD
169 /* Width of the next token, including the two quotes, the
170 comma and the space. */
21fd22d6 171 int width = strlen (cp) + 2;
b0940840 172
21fd22d6 173 if (j + width > 75)
b0940840 174 {
d423d460
AD
175 obstack_sgrow (&format_obstack, "\n ");
176 j = 1;
b0940840
AD
177 }
178
d423d460
AD
179 if (i)
180 obstack_1grow (&format_obstack, ' ');
3813e141 181 MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
d423d460 182 obstack_1grow (&format_obstack, ',');
21fd22d6 183 j += width;
b0940840
AD
184 }
185 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
186 defined). */
d423d460 187 obstack_sgrow (&format_obstack, " 0");
c3e23647 188
b0940840
AD
189 /* Finish table and store. */
190 obstack_1grow (&format_obstack, 0);
191 muscle_insert ("tname", obstack_finish (&format_obstack));
192 }
193
12b0043a 194 /* Output YYTOKNUM. */
b2ed6e58
AD
195 {
196 int i;
da2a7671 197 int *values = xnmalloc (ntokens, sizeof *values);
3650b4b8 198 for (i = 0; i < ntokens; ++i)
b0940840 199 values[i] = symbols[i]->user_token_number;
12b0043a 200 muscle_insert_int_table ("toknum", values,
3650b4b8 201 values[0], 1, ntokens);
b0940840 202 free (values);
b2ed6e58 203 }
b0940840 204}
b2ed6e58 205
b0940840
AD
206
207/*-------------------------------------------------------------.
208| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
95612cfa 209| rline, dprec, merger. |
b0940840
AD
210`-------------------------------------------------------------*/
211
212static void
213prepare_rules (void)
214{
21fd22d6 215 rule_number r;
5df5f6d5 216 unsigned int i = 0;
da2a7671
PE
217 item_number *rhs = xnmalloc (nritems, sizeof *rhs);
218 unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
219 unsigned int *rline = xnmalloc (nrules, sizeof *rline);
220 symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
221 unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
f6fbd3da
PE
222 int *dprec = xnmalloc (nrules, sizeof *dprec);
223 int *merger = xnmalloc (nrules, sizeof *merger);
4b3d3a8e
AD
224
225 for (r = 0; r < nrules; ++r)
b0940840 226 {
21fd22d6 227 item_number *rhsp = NULL;
b0940840
AD
228 /* Index of rule R in RHS. */
229 prhs[r] = i;
230 /* RHS of the rule R. */
231 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
232 rhs[i++] = *rhsp;
233 /* LHS of the rule R. */
234 r1[r] = rules[r].lhs->number;
235 /* Length of rule R's RHS. */
236 r2[r] = i - prhs[r];
237 /* Separator in RHS. */
238 rhs[i++] = -1;
239 /* Line where rule was defined. */
2073702c 240 rline[r] = rules[r].location.start.line;
95612cfa 241 /* Dynamic precedence (GLR). */
676385e2 242 dprec[r] = rules[r].dprec;
95612cfa 243 /* Merger-function index (GLR). */
676385e2 244 merger[r] = rules[r].merger;
b0940840 245 }
a932883e
PE
246 if (i != nritems)
247 abort ();
b0940840 248
5372019f 249 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
4b3d3a8e
AD
250 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
251 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
252 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
253 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
f6fbd3da
PE
254 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
255 muscle_insert_int_table ("merger", merger, 0, 0, nrules);
796d61fb 256
39912f52 257 MUSCLE_INSERT_INT ("rules_number", nrules);
25005f6a 258 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
39912f52 259
b0940840
AD
260 free (rhs);
261 free (prhs);
5df5f6d5
AD
262 free (rline);
263 free (r1);
b0940840 264 free (r2);
676385e2
PH
265 free (dprec);
266 free (merger);
c3e23647
RS
267}
268
b0940840
AD
269/*--------------------------------------------.
270| Prepare the muscles related to the states. |
271`--------------------------------------------*/
c3e23647 272
4a120d45 273static void
b0940840 274prepare_states (void)
c3e23647 275{
21fd22d6 276 state_number i;
da2a7671 277 symbol_number *values = xnmalloc (nstates, sizeof *values);
9703cc49 278 for (i = 0; i < nstates; ++i)
29e88316 279 values[i] = states[i]->accessing_symbol;
a49aecd5 280 muscle_insert_symbol_number_table ("stos", values,
d57650a5 281 0, 1, nstates);
87ceef73 282 free (values);
39912f52
AD
283
284 MUSCLE_INSERT_INT ("last", high);
285 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
286 MUSCLE_INSERT_INT ("states_number", nstates);
c3e23647
RS
287}
288
289
c3e23647 290
bb33f19a
PE
291/*---------------------------------.
292| Output the user actions to OUT. |
293`---------------------------------*/
12b0043a 294
4a120d45 295static void
c6f1a33c 296user_actions_output (FILE *out)
3f96f4dc 297{
21fd22d6 298 rule_number r;
dafdc66f
AD
299
300 fputs ("m4_define([b4_actions], \n[[", out);
4b3d3a8e 301 for (r = 0; r < nrules; ++r)
9222837b 302 if (rules[r].action)
3f96f4dc 303 {
4b3d3a8e 304 fprintf (out, " case %d:\n", r + 1);
3f96f4dc 305
05ac60f3 306 fprintf (out, "]b4_syncline(%d, ",
2073702c 307 rules[r].action_location.start.line);
05ac60f3 308 escaped_output (out, rules[r].action_location.start.file);
3813e141 309 fprintf (out, ")[\n");
e9955c83 310 fprintf (out, " %s\n break;\n\n",
9222837b 311 rules[r].action);
3f96f4dc 312 }
dafdc66f 313 fputs ("]])\n\n", out);
3f96f4dc
AD
314}
315
676385e2
PH
316/*--------------------------------------.
317| Output the merge functions to OUT. |
318`--------------------------------------*/
319
41442480 320static void
676385e2
PH
321merger_output (FILE *out)
322{
323 int n;
324 merger_list* p;
325
326 fputs ("m4_define([b4_mergers], \n[[", out);
e0e5bf84 327 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
676385e2 328 {
e0e5bf84 329 if (p->type[0] == '\0')
16caa4f4 330 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
676385e2
PH
331 n, p->name);
332 else
16caa4f4 333 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
676385e2
PH
334 n, p->type, p->name);
335 }
336 fputs ("]])\n\n", out);
337}
3f96f4dc 338
ae7453f2
AD
339/*--------------------------------------.
340| Output the tokens definition to OUT. |
341`--------------------------------------*/
091e20bb 342
c6f1a33c 343static void
be2a1a68 344token_definitions_output (FILE *out)
091e20bb
AD
345{
346 int i;
d0829076 347 char const *sep = "";
dafdc66f
AD
348
349 fputs ("m4_define([b4_tokens], \n[", out);
091e20bb
AD
350 for (i = 0; i < ntokens; ++i)
351 {
21fd22d6
PE
352 symbol *sym = symbols[i];
353 int number = sym->user_token_number;
091e20bb 354
b87f8b21
AD
355 /* At this stage, if there are literal aliases, they are part of
356 SYMBOLS, so we should not find symbols which are the aliases
357 here. */
a932883e
PE
358 if (number == USER_NUMBER_ALIAS)
359 abort ();
b87f8b21 360
091e20bb 361 /* Skip error token. */
21fd22d6 362 if (sym == errtoken)
091e20bb 363 continue;
b87f8b21
AD
364
365 /* If this string has an alias, then it is necessarily the alias
366 which is to be output. */
21fd22d6
PE
367 if (sym->alias)
368 sym = sym->alias;
b87f8b21
AD
369
370 /* Don't output literal chars or strings (when defined only as a
371 string). Note that must be done after the alias resolution:
372 think about `%token 'f' "f"'. */
21fd22d6 373 if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
b87f8b21 374 continue;
091e20bb
AD
375
376 /* Don't #define nonliteral tokens whose names contain periods
377 or '$' (as does the default value of the EOF token). */
21fd22d6 378 if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
091e20bb
AD
379 continue;
380
05ac60f3 381 fprintf (out, "%s[[[%s]], %d]",
d0829076
PE
382 sep, sym->tag, number);
383 sep = ",\n";
091e20bb 384 }
dafdc66f 385 fputs ("])\n\n", out);
091e20bb
AD
386}
387
388
ae7453f2
AD
389/*---------------------------------------.
390| Output the symbol destructors to OUT. |
391`---------------------------------------*/
9280d3ef
AD
392
393static void
394symbol_destructors_output (FILE *out)
395{
396 int i;
d0829076 397 char const *sep = "";
9280d3ef
AD
398
399 fputs ("m4_define([b4_symbol_destructors], \n[", out);
400 for (i = 0; i < nsyms; ++i)
401 if (symbols[i]->destructor)
402 {
21fd22d6 403 symbol *sym = symbols[i];
9280d3ef 404
24c0aad7
AD
405 /* Filename, lineno,
406 Symbol-name, Symbol-number,
ee42c616 407 destructor, optional typename. */
d0829076
PE
408 fprintf (out, "%s[", sep);
409 sep = ",\n";
05ac60f3
PE
410 escaped_output (out, sym->destructor_location.start.file);
411 fprintf (out, ", %d, ", sym->destructor_location.start.line);
412 escaped_output (out, sym->tag);
413 fprintf (out, ", %d, [[%s]]", sym->number, sym->destructor);
ee42c616
PE
414 if (sym->type_name)
415 fprintf (out, ", [[%s]]", sym->type_name);
416 fputc (']', out);
9280d3ef
AD
417 }
418 fputs ("])\n\n", out);
419}
420
421
ae7453f2
AD
422/*------------------------------------.
423| Output the symbol printers to OUT. |
424`------------------------------------*/
366eea36
AD
425
426static void
427symbol_printers_output (FILE *out)
428{
429 int i;
d0829076 430 char const *sep = "";
366eea36
AD
431
432 fputs ("m4_define([b4_symbol_printers], \n[", out);
433 for (i = 0; i < nsyms; ++i)
34e1d160 434 if (symbols[i]->printer)
366eea36 435 {
21fd22d6 436 symbol *sym = symbols[i];
366eea36
AD
437
438 /* Filename, lineno,
439 Symbol-name, Symbol-number,
ee42c616 440 printer, optional typename. */
d0829076
PE
441 fprintf (out, "%s[", sep);
442 sep = ",\n";
05ac60f3
PE
443 escaped_output (out, sym->printer_location.start.file);
444 fprintf (out, ", %d, ", sym->printer_location.start.line);
445 escaped_output (out, sym->tag);
446 fprintf (out, ", %d, [[%s]]", sym->number, sym->printer);
ee42c616
PE
447 if (sym->type_name)
448 fprintf (out, ", [[%s]]", sym->type_name);
449 fputc (']', out);
366eea36
AD
450 }
451 fputs ("])\n\n", out);
452}
453
454
4a120d45 455static void
c6f1a33c 456prepare_actions (void)
6c89f1c1 457{
c6f1a33c 458 /* Figure out the actions for the specified state, indexed by
8dd162d3 459 look-ahead 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 498 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
da2a7671 499 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];
2fd4e131 513 char const *argv[6];
573312ac
PE
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";
2fd4e131
PE
521 char *full_m4sugar;
522 char *full_cm4;
eecf08fe 523 char *full_skeleton;
573312ac
PE
524 char const *p;
525 char const *m4 = (p = getenv ("M4")) ? p : M4;
526 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
527 size_t skeleton_size = strlen (skeleton) + 1;
528 size_t pkgdatadirlen = strlen (pkgdatadir);
529 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
530 pkgdatadirlen--;
eecf08fe
PE
531 full_skeleton = xmalloc (pkgdatadirlen + 1
532 + (skeleton_size < sizeof m4sugar
533 ? sizeof m4sugar : skeleton_size));
534 strcpy (full_skeleton, pkgdatadir);
535 full_skeleton[pkgdatadirlen] = '/';
536 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
537 full_m4sugar = xstrdup (full_skeleton);
538 strcpy (full_skeleton + pkgdatadirlen + 1, "c.m4");
539 full_cm4 = xstrdup (full_skeleton);
540 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
2fd4e131 541 xfclose (xfopen (full_m4sugar, "r"));
573312ac
PE
542
543 /* Create an m4 subprocess connected to us via two pipes. */
544
545 if (trace_flag & trace_tools)
2fd4e131 546 fprintf (stderr, "running: %s %s - %s %s\n",
eecf08fe 547 m4, full_m4sugar, full_cm4, full_skeleton);
573312ac
PE
548
549 argv[0] = m4;
2fd4e131
PE
550 argv[1] = full_m4sugar;
551 argv[2] = "-";
552 argv[3] = full_cm4;
eecf08fe 553 argv[4] = full_skeleton;
2fd4e131 554 argv[5] = NULL;
573312ac
PE
555
556 init_subpipe ();
557 pid = create_subpipe (argv, filter_fd);
2fd4e131
PE
558 free (full_m4sugar);
559 free (full_cm4);
eecf08fe 560 free (full_skeleton);
573312ac
PE
561
562 out = fdopen (filter_fd[0], "w");
563 if (! out)
21fd22d6 564 error (EXIT_FAILURE, get_errno (), "fdopen");
573312ac
PE
565
566 /* Output the definitions of all the muscles. */
381fb12e
AD
567 fputs ("m4_init()\n", out);
568
c6f1a33c 569 user_actions_output (out);
676385e2 570 merger_output (out);
381fb12e 571 token_definitions_output (out);
9280d3ef 572 symbol_destructors_output (out);
366eea36 573 symbol_printers_output (out);
be2a1a68 574
381fb12e 575 muscles_m4_output (out);
be2a1a68 576
381fb12e
AD
577 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
578 fputs ("m4_divert_push(0)dnl\n", out);
579 xfclose (out);
be2a1a68 580
573312ac 581 /* Read and process m4's output. */
1509d42f 582 timevar_push (TV_M4);
573312ac
PE
583 in = fdopen (filter_fd[1], "r");
584 if (! in)
21fd22d6 585 error (EXIT_FAILURE, get_errno (), "fdopen");
573312ac 586 scan_skel (in);
573312ac
PE
587 xfclose (in);
588 reap_subpipe (pid, m4);
1509d42f 589 timevar_pop (TV_M4);
26f609ff
RA
590}
591
592static void
593prepare (void)
594{
7db2ed2d 595 /* Flags. */
d0829076
PE
596 MUSCLE_INSERT_BOOL ("debug", debug_flag);
597 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
598 MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
599 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
600 MUSCLE_INSERT_BOOL ("pure", pure_parser);
601 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
11d82f03 602
573a6cd3 603 /* File names. */
7db2ed2d 604 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
b85810ae 605
7db2ed2d 606 /* User Code. */
0dd1580a
RA
607 obstack_1grow (&pre_prologue_obstack, 0);
608 obstack_1grow (&post_prologue_obstack, 0);
609 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
610 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
381fb12e
AD
611
612 /* Find the right skeleton file. */
613 if (!skeleton)
676385e2 614 {
916708d5 615 if (glr_parser || nondeterministic_parser)
676385e2
PH
616 skeleton = "glr.c";
617 else
618 skeleton = "yacc.c";
619 }
381fb12e
AD
620
621 /* Parse the skeleton file and output the needed parsers. */
3813e141 622 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
26f609ff 623}
c3e23647 624
93ede233 625
6c89f1c1
AD
626/*----------------------------------------------------------.
627| Output the parsing tables and the parser code to ftable. |
628`----------------------------------------------------------*/
c3e23647 629
6c89f1c1
AD
630void
631output (void)
632{
f87685c3 633 obstack_init (&format_obstack);
dd60faec 634
39912f52 635 prepare_symbols ();
b0940840
AD
636 prepare_rules ();
637 prepare_states ();
536545f3 638 prepare_actions ();
342b8b6e 639
26f609ff 640 prepare ();
652def80 641
9b3add5b
RA
642 /* Process the selected skeleton file. */
643 output_skeleton ();
644
f499b062 645 obstack_free (&format_obstack, NULL);
0dd1580a
RA
646 obstack_free (&pre_prologue_obstack, NULL);
647 obstack_free (&post_prologue_obstack, NULL);
c3e23647 648}