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