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