]> git.saurik.com Git - bison.git/blame - src/output.c
* lib/.cvsignore: Add charset.alias.
[bison.git] / src / output.c
CommitLineData
a932883e 1/* Output the generated parsing program for Bison.
87ceef73 2
e2a21b6f 3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
945e396c 4 2005, 2006, 2007 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
95021767
JD
376/*---------------------------------------------------.
377| Output the symbol destructors or printers to OUT. |
378`---------------------------------------------------*/
9280d3ef
AD
379
380static void
95021767
JD
381symbol_code_props_output (FILE *out, char const *what,
382 code_props const *(*get)(symbol const *))
9280d3ef
AD
383{
384 int i;
d0829076 385 char const *sep = "";
9280d3ef 386
95021767
JD
387 fputs ("m4_define([b4_symbol_", out);
388 fputs (what, out);
389 fputs ("], \n[", out);
9280d3ef 390 for (i = 0; i < nsyms; ++i)
95021767
JD
391 {
392 symbol *sym = symbols[i];
393 char const *code = (*get) (sym)->code;
394 if (code)
395 {
396 location loc = (*get) (sym)->location;
397 /* Filename, lineno,
398 Symbol-name, Symbol-number,
399 code, optional typename. */
400 fprintf (out, "%s[", sep);
401 sep = ",\n";
402 escaped_output (out, loc.start.file);
403 fprintf (out, ", %d, ", loc.start.line);
404 escaped_output (out, sym->tag);
405 fprintf (out, ", %d, [[%s]]", sym->number, code);
406 if (sym->type_name)
407 fprintf (out, ", [[%s]]", sym->type_name);
408 fputc (']', out);
409 }
410 }
366eea36
AD
411 fputs ("])\n\n", out);
412}
413
414
4a120d45 415static void
c6f1a33c 416prepare_actions (void)
6c89f1c1 417{
c6f1a33c 418 /* Figure out the actions for the specified state, indexed by
742e4900 419 lookahead token type. */
bbb5bcc6 420
c6f1a33c
AD
421 muscle_insert_rule_number_table ("defact", yydefact,
422 yydefact[0], 1, nstates);
6c89f1c1 423
c6f1a33c
AD
424 /* Figure out what to do after reducing with each rule, depending on
425 the saved state from before the beginning of parsing the data
426 that matched this rule. */
d57650a5
AD
427 muscle_insert_state_number_table ("defgoto", yydefgoto,
428 yydefgoto[0], 1, nsyms - ntokens);
12b0043a 429
12b0043a 430
12b0043a
AD
431 /* Output PACT. */
432 muscle_insert_base_table ("pact", base,
5372019f 433 base[0], 1, nstates);
12b0043a 434 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
c3e23647 435
12b0043a
AD
436 /* Output PGOTO. */
437 muscle_insert_base_table ("pgoto", base,
5372019f 438 base[nstates], nstates + 1, nvectors);
c3e23647 439
12b0043a
AD
440 muscle_insert_base_table ("table", table,
441 table[0], 1, high + 1);
442 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
676385e2 443
12b0043a
AD
444 muscle_insert_base_table ("check", check,
445 check[0], 1, high + 1);
c3e23647 446
ea99527d
AD
447 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
448 YYPACT) so that in states with unresolved conflicts, the default
449 reduction is not used in the conflicted entries, so that there is
450 a place to put a conflict pointer.
451
452 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
453 parser, so we could avoid accidents by not writing them out in
454 that case. Nevertheless, it seems even better to be able to use
455 the GLR skeletons even without the non-deterministic tables. */
456 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
39912f52 457 conflict_table[0], 1, high + 1);
ea99527d 458 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
da2a7671 459 0, 1, conflict_list_cnt);
6c89f1c1 460}
c3e23647 461
652def80 462\f
1239777d
AD
463/*---------------------------.
464| Call the skeleton parser. |
465`---------------------------*/
c3e23647 466
4a120d45 467static void
1239777d 468output_skeleton (void)
9b3add5b 469{
573312ac
PE
470 FILE *in;
471 FILE *out;
472 int filter_fd[2];
90b9908d 473 char const *argv[7];
573312ac
PE
474 pid_t pid;
475
476 /* Compute the names of the package data dir and skeleton file.
477 Test whether m4sugar.m4 is readable, to check for proper
478 installation. A faulty installation can cause deadlock, so a
479 cheap sanity check is worthwhile. */
480 char const m4sugar[] = "m4sugar/m4sugar.m4";
90b9908d 481 char const m4bison[] = "bison.m4";
2fd4e131 482 char *full_m4sugar;
90b9908d 483 char *full_m4bison;
eecf08fe 484 char *full_skeleton;
573312ac
PE
485 char const *p;
486 char const *m4 = (p = getenv ("M4")) ? p : M4;
487 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
488 size_t skeleton_size = strlen (skeleton) + 1;
489 size_t pkgdatadirlen = strlen (pkgdatadir);
490 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
491 pkgdatadirlen--;
eecf08fe
PE
492 full_skeleton = xmalloc (pkgdatadirlen + 1
493 + (skeleton_size < sizeof m4sugar
494 ? sizeof m4sugar : skeleton_size));
a7867f53 495 strncpy (full_skeleton, pkgdatadir, pkgdatadirlen);
eecf08fe
PE
496 full_skeleton[pkgdatadirlen] = '/';
497 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
498 full_m4sugar = xstrdup (full_skeleton);
90b9908d
PB
499 strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
500 full_m4bison = xstrdup (full_skeleton);
a7867f53
JD
501 if (strchr (skeleton, '/'))
502 strcpy (full_skeleton, skeleton);
503 else
504 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
2fd4e131 505 xfclose (xfopen (full_m4sugar, "r"));
573312ac
PE
506
507 /* Create an m4 subprocess connected to us via two pipes. */
508
509 if (trace_flag & trace_tools)
90b9908d
PB
510 fprintf (stderr, "running: %s %s - %s %s\n",
511 m4, full_m4sugar, full_m4bison, full_skeleton);
573312ac
PE
512
513 argv[0] = m4;
2fd4e131
PE
514 argv[1] = full_m4sugar;
515 argv[2] = "-";
90b9908d
PB
516 argv[3] = full_m4bison;
517 argv[4] = full_skeleton;
518 argv[5] = trace_flag & trace_m4 ? "-dV" : NULL;
519 argv[6] = NULL;
573312ac
PE
520
521 init_subpipe ();
522 pid = create_subpipe (argv, filter_fd);
90b9908d 523 free (full_m4bison);
2fd4e131 524 free (full_m4sugar);
eecf08fe 525 free (full_skeleton);
573312ac
PE
526
527 out = fdopen (filter_fd[0], "w");
528 if (! out)
04098407
PE
529 error (EXIT_FAILURE, get_errno (),
530 "fdopen");
573312ac
PE
531
532 /* Output the definitions of all the muscles. */
381fb12e
AD
533 fputs ("m4_init()\n", out);
534
c6f1a33c 535 user_actions_output (out);
676385e2 536 merger_output (out);
381fb12e 537 token_definitions_output (out);
95021767
JD
538 symbol_code_props_output (out, "destructors", &symbol_destructor_get);
539 symbol_code_props_output (out, "printers", &symbol_printer_get);
be2a1a68 540
381fb12e 541 muscles_m4_output (out);
381fb12e 542 xfclose (out);
be2a1a68 543
573312ac 544 /* Read and process m4's output. */
1509d42f 545 timevar_push (TV_M4);
ec4d88f4 546 end_of_output_subpipe (pid, filter_fd);
573312ac
PE
547 in = fdopen (filter_fd[1], "r");
548 if (! in)
04098407
PE
549 error (EXIT_FAILURE, get_errno (),
550 "fdopen");
573312ac 551 scan_skel (in);
573312ac
PE
552 xfclose (in);
553 reap_subpipe (pid, m4);
1509d42f 554 timevar_pop (TV_M4);
26f609ff
RA
555}
556
557static void
558prepare (void)
559{
945e396c
JD
560 /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented
561 for the user. */
562 char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL");
563 bool use_push_for_pull_flag = false;
564 if (use_push_for_pull_env != NULL
565 && use_push_for_pull_env[0] != '\0'
566 && 0 != strcmp (use_push_for_pull_env, "0"))
567 use_push_for_pull_flag = true;
568
7db2ed2d 569 /* Flags. */
327afc7c 570 MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
d0829076 571 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
327afc7c 572 MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
90b9908d 573 MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
d0829076 574 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
90b9908d 575 MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
7172e23e 576 MUSCLE_INSERT_BOOL ("pull_flag", pull_parser);
327afc7c 577 MUSCLE_INSERT_BOOL ("pure_flag", pure_parser);
31c10e38 578 MUSCLE_INSERT_BOOL ("push_flag", push_parser);
d0829076 579 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
ddc8ede1 580 MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
95021767 581 MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
b931235e 582 MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
11d82f03 583
573a6cd3 584 /* File names. */
90b9908d
PB
585 if (spec_name_prefix)
586 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
587
bd9d212b
JD
588 MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
589
2b81e969
AD
590#define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
591 DEFINE (dir_prefix);
592 DEFINE (parser_file_name);
593 DEFINE (spec_defines_file);
594 DEFINE (spec_file_prefix);
595 DEFINE (spec_graph_file);
596 DEFINE (spec_name_prefix);
597 DEFINE (spec_outfile);
598 DEFINE (spec_verbose_file);
599#undef DEFINE
b85810ae 600
0e021770
PE
601 /* Find the right skeleton file, and add muscles about the skeletons. */
602 if (skeleton)
603 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
604 else
605 skeleton = language->skeleton;
381fb12e 606
0e021770 607 /* About the skeletons. */
cf147260 608 {
1bd0deda 609 char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
bd9d212b
JD
610 /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
611 would never be expanded. Hopefully no one has M4-special characters in
612 his Bison installation path. */
613 MUSCLE_INSERT_STRING_RAW ("pkgdatadir",
614 pkgdatadir ? pkgdatadir : PKGDATADIR);
cf147260 615 }
26f609ff 616}
c3e23647 617
93ede233 618
6c89f1c1
AD
619/*----------------------------------------------------------.
620| Output the parsing tables and the parser code to ftable. |
621`----------------------------------------------------------*/
c3e23647 622
6c89f1c1
AD
623void
624output (void)
625{
f87685c3 626 obstack_init (&format_obstack);
dd60faec 627
39912f52 628 prepare_symbols ();
b0940840
AD
629 prepare_rules ();
630 prepare_states ();
536545f3 631 prepare_actions ();
342b8b6e 632
26f609ff 633 prepare ();
652def80 634
9b3add5b
RA
635 /* Process the selected skeleton file. */
636 output_skeleton ();
637
f499b062 638 obstack_free (&format_obstack, NULL);
c3e23647 639}