]> git.saurik.com Git - bison.git/blame - src/output.c
maint: prepare to use date ranges in copyright notices.
[bison.git] / src / output.c
CommitLineData
a932883e 1/* Output the generated parsing program for Bison.
87ceef73 2
7d424de1
PE
3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
c3e23647 5
9ee3c97b 6 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 7
f16b0819
PE
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
c3e23647 12
f16b0819
PE
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c3e23647 17
9ee3c97b 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c3e23647 20
2cec9080 21#include <config.h>
c3e23647 22#include "system.h"
21fd22d6 23
3b2942e6 24#include <configmake.h>
21fd22d6
PE
25#include <error.h>
26#include <get-errno.h>
f39ab286 27#include <pipe.h>
21fd22d6 28#include <quotearg.h>
21fd22d6 29#include <timevar.h>
f39ab286 30#include <wait-process.h>
21fd22d6
PE
31
32#include "complain.h"
c3e23647 33#include "files.h"
21fd22d6 34#include "getargs.h"
c3e23647 35#include "gram.h"
00f5d575 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
b0778bdd 44# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
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)
21fd22d6 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);
d69c9694 147 MUSCLE_INSERT_INT ("symbols_number", nsyms);
39912f52
AD
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;
1cfe6375
JD
161 struct quoting_options *qo = clone_quoting_options (0);
162 set_quoting_style (qo, c_quoting_style);
163 set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
b0940840
AD
164 for (i = 0; i < nsyms; i++)
165 {
1cfe6375 166 char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
d423d460
AD
167 /* Width of the next token, including the two quotes, the
168 comma and the space. */
21fd22d6 169 int width = strlen (cp) + 2;
b0940840 170
21fd22d6 171 if (j + width > 75)
b0940840 172 {
d423d460
AD
173 obstack_sgrow (&format_obstack, "\n ");
174 j = 1;
b0940840
AD
175 }
176
d423d460
AD
177 if (i)
178 obstack_1grow (&format_obstack, ' ');
3813e141 179 MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
1cfe6375 180 free (cp);
d423d460 181 obstack_1grow (&format_obstack, ',');
21fd22d6 182 j += width;
b0940840 183 }
1cfe6375 184 free (qo);
8e1687ae 185 obstack_sgrow (&format_obstack, " ]b4_null[");
c3e23647 186
b0940840
AD
187 /* Finish table and store. */
188 obstack_1grow (&format_obstack, 0);
189 muscle_insert ("tname", obstack_finish (&format_obstack));
190 }
191
12b0043a 192 /* Output YYTOKNUM. */
b2ed6e58
AD
193 {
194 int i;
da2a7671 195 int *values = xnmalloc (ntokens, sizeof *values);
3650b4b8 196 for (i = 0; i < ntokens; ++i)
b0940840 197 values[i] = symbols[i]->user_token_number;
12b0043a 198 muscle_insert_int_table ("toknum", values,
3650b4b8 199 values[0], 1, ntokens);
b0940840 200 free (values);
b2ed6e58 201 }
b0940840 202}
b2ed6e58 203
b0940840 204
3d3bc1fe
AD
205/*----------------------------------------------------------------.
206| Prepare the muscles related to the rules: r1, r2, rline, dprec, |
ca2a6d15 207| merger, immediate. |
3d3bc1fe 208`----------------------------------------------------------------*/
b0940840
AD
209
210static void
211prepare_rules (void)
212{
da2a7671
PE
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);
ca2a6d15 218 int *immediate = xnmalloc (nrules, sizeof *immediate);
4b3d3a8e 219
3d3bc1fe 220 rule_number r;
4b3d3a8e 221 for (r = 0; r < nrules; ++r)
b0940840 222 {
b0940840
AD
223 /* LHS of the rule R. */
224 r1[r] = rules[r].lhs->number;
225 /* Length of rule R's RHS. */
3d3bc1fe 226 r2[r] = rule_rhs_length(&rules[r]);
b0940840 227 /* Line where rule was defined. */
2073702c 228 rline[r] = rules[r].location.start.line;
95612cfa 229 /* Dynamic precedence (GLR). */
676385e2 230 dprec[r] = rules[r].dprec;
95612cfa 231 /* Merger-function index (GLR). */
676385e2 232 merger[r] = rules[r].merger;
ca2a6d15
PH
233 /* Immediate reduction flags (GLR). */
234 immediate[r] = rules[r].is_predicate;
b0940840 235 }
b0940840 236
4b3d3a8e
AD
237 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
238 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
239 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
f6fbd3da
PE
240 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
241 muscle_insert_int_table ("merger", merger, 0, 0, nrules);
ca2a6d15 242 muscle_insert_int_table ("immediate", immediate, 0, 0, nrules);
796d61fb 243
39912f52 244 MUSCLE_INSERT_INT ("rules_number", nrules);
25005f6a 245 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
39912f52 246
5df5f6d5
AD
247 free (rline);
248 free (r1);
b0940840 249 free (r2);
676385e2
PH
250 free (dprec);
251 free (merger);
71431084 252 free (immediate);
c3e23647
RS
253}
254
b0940840
AD
255/*--------------------------------------------.
256| Prepare the muscles related to the states. |
257`--------------------------------------------*/
c3e23647 258
4a120d45 259static void
b0940840 260prepare_states (void)
c3e23647 261{
21fd22d6 262 state_number i;
da2a7671 263 symbol_number *values = xnmalloc (nstates, sizeof *values);
9703cc49 264 for (i = 0; i < nstates; ++i)
29e88316 265 values[i] = states[i]->accessing_symbol;
a49aecd5 266 muscle_insert_symbol_number_table ("stos", values,
d57650a5 267 0, 1, nstates);
87ceef73 268 free (values);
39912f52
AD
269
270 MUSCLE_INSERT_INT ("last", high);
271 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
272 MUSCLE_INSERT_INT ("states_number", nstates);
c3e23647
RS
273}
274
275
4c3cc7da
AD
276/*-------------------------------------------------------.
277| Compare two symbols by type-name, and then by number. |
278`-------------------------------------------------------*/
279
d73e55e0 280static int
4c3cc7da
AD
281symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
282{
283 int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name);
284 if (res)
285 return res;
286 return (*lhs)->number - (*rhs)->number;
287}
288
289
290/*----------------------------------------------------------------.
291| Return a (malloc'ed) table of the symbols sorted by type-name. |
292`----------------------------------------------------------------*/
293
294static symbol **
d73e55e0 295symbols_by_type_name (void)
4c3cc7da
AD
296{
297 typedef int (*qcmp_type) (const void *, const void *);
298 symbol **res = xmemdup (symbols, nsyms * sizeof *res);
299 qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
300 return res;
301}
302
303
304/*------------------------------------------------------------------.
305| Define b4_type_names, which is a list of (lists of the numbers of |
306| symbols with same type-name). |
307`------------------------------------------------------------------*/
308
309static void
310type_names_output (FILE *out)
311{
312 int i;
4c3cc7da
AD
313 symbol **syms = symbols_by_type_name ();
314 fputs ("m4_define([b4_type_names],\n[", out);
5d731440
AD
315 for (i = 0; i < nsyms; /* nothing */)
316 {
317 // The index of the first symbol of the current type-name.
318 int i0 = i;
319 fputs (i ? ",\n[" : "[", out);
320 for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
321 fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
322 fputs ("]", out);
323 }
4c3cc7da
AD
324 fputs ("])\n\n", out);
325 free (syms);
326}
327
c3e23647 328
d69c9694
AD
329/*-------------------------------------.
330| The list of all the symbol numbers. |
331`-------------------------------------*/
5ab8c47b
AD
332
333static void
d69c9694 334symbol_numbers_output (FILE *out)
5ab8c47b
AD
335{
336 int i;
d69c9694 337 fputs ("m4_define([b4_symbol_numbers],\n[", out);
5ab8c47b 338 for (i = 0; i < nsyms; ++i)
d69c9694 339 fprintf (out, "%s[%d]", i ? ", " : "", i);
5ab8c47b
AD
340 fputs ("])\n\n", out);
341}
342
343
bb33f19a
PE
344/*---------------------------------.
345| Output the user actions to OUT. |
346`---------------------------------*/
12b0043a 347
4a120d45 348static void
c6f1a33c 349user_actions_output (FILE *out)
3f96f4dc 350{
21fd22d6 351 rule_number r;
dafdc66f 352
8e1687ae 353 fputs ("m4_define([b4_actions], \n[", out);
4b3d3a8e 354 for (r = 0; r < nrules; ++r)
9222837b 355 if (rules[r].action)
3f96f4dc 356 {
ca2a6d15
PH
357 fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ",
358 rules[r].is_predicate ? "predicate_" : "",
359 r + 1, rules[r].action_location.start.line);
05ac60f3 360 escaped_output (out, rules[r].action_location.start.file);
8e1687ae 361 fprintf (out, ")\n[ %s]])\n\n", rules[r].action);
3f96f4dc 362 }
8e1687ae 363 fputs ("])\n\n", out);
3f96f4dc
AD
364}
365
1de69d6a
AD
366/*------------------------------------.
367| Output the merge functions to OUT. |
368`------------------------------------*/
676385e2 369
41442480 370static void
676385e2
PH
371merger_output (FILE *out)
372{
373 int n;
374 merger_list* p;
375
376 fputs ("m4_define([b4_mergers], \n[[", out);
e0e5bf84 377 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
676385e2 378 {
e0e5bf84 379 if (p->type[0] == '\0')
16caa4f4 380 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
676385e2
PH
381 n, p->name);
382 else
16caa4f4 383 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
676385e2
PH
384 n, p->type, p->name);
385 }
386 fputs ("]])\n\n", out);
387}
3f96f4dc 388
d69c9694 389
d73e55e0
DJ
390/*---------------------------------------------.
391| Prepare the muscles for symbol definitions. |
392`---------------------------------------------*/
d69c9694
AD
393
394static void
d73e55e0 395prepare_symbol_definitions (void)
d69c9694
AD
396{
397 int i;
398 for (i = 0; i < nsyms; ++i)
399 {
400 symbol *sym = symbols[i];
401 const char *key;
aea10ef4 402 const char *value;
d69c9694
AD
403
404#define SET_KEY(Entry) \
405 obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry); \
406 obstack_1grow (&format_obstack, 0); \
407 key = obstack_finish (&format_obstack);
408
aea10ef4
AD
409 // Whether the symbol has an identifier.
410 value = symbol_id_get (sym);
411 SET_KEY("has_id");
412 MUSCLE_INSERT_INT (key, !!value);
413
414 // Its identifier.
415 SET_KEY("id");
416 MUSCLE_INSERT_STRING (key, value ? value : "");
8be046d7 417
aea10ef4 418 // Its tag. Typically for documentation purpose.
d69c9694
AD
419 SET_KEY("tag");
420 MUSCLE_INSERT_STRING (key, sym->tag);
421
422 SET_KEY("user_number");
423 MUSCLE_INSERT_INT (key, sym->user_token_number);
424
5d731440
AD
425 SET_KEY("is_token");
426 MUSCLE_INSERT_INT (key,
427 i < ntokens && sym != errtoken && sym != undeftoken);
428
d69c9694
AD
429 SET_KEY("number");
430 MUSCLE_INSERT_INT (key, sym->number);
431
6659366c 432 SET_KEY("has_type");
5d731440
AD
433 MUSCLE_INSERT_INT (key, !!sym->type_name);
434
6659366c 435 SET_KEY("type");
d69c9694
AD
436 MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
437
2bde9113
AD
438#define CODE_PROP(PropName) \
439 do { \
440 code_props const *p = symbol_ ## PropName ## _get (sym); \
441 SET_KEY("has_" #PropName); \
442 MUSCLE_INSERT_INT (key, !!p->code); \
443 \
444 if (p->code) \
445 { \
446 SET_KEY(#PropName "_file"); \
447 MUSCLE_INSERT_STRING (key, p->location.start.file); \
448 \
449 SET_KEY(#PropName "_line"); \
450 MUSCLE_INSERT_INT (key, p->location.start.line); \
451 \
452 SET_KEY(#PropName); \
453 MUSCLE_INSERT_STRING_RAW (key, p->code); \
454 } \
455 } while (0)
456
457 CODE_PROP(destructor);
458 CODE_PROP(printer);
459#undef CODE_PROP
d69c9694
AD
460#undef SET_KEY
461 }
462}
463
464
ae7453f2
AD
465/*--------------------------------------.
466| Output the tokens definition to OUT. |
467`--------------------------------------*/
091e20bb 468
c6f1a33c 469static void
be2a1a68 470token_definitions_output (FILE *out)
091e20bb
AD
471{
472 int i;
d0829076 473 char const *sep = "";
dafdc66f
AD
474
475 fputs ("m4_define([b4_tokens], \n[", out);
091e20bb
AD
476 for (i = 0; i < ntokens; ++i)
477 {
21fd22d6
PE
478 symbol *sym = symbols[i];
479 int number = sym->user_token_number;
90462b8d 480 uniqstr id = symbol_id_get (sym);
091e20bb 481
dfaa4860
JD
482 /* At this stage, if there are literal string aliases, they are
483 part of SYMBOLS, so we should not find their aliased symbols
484 here. */
485 aver (number != USER_NUMBER_HAS_STRING_ALIAS);
b87f8b21 486
90462b8d
AD
487 /* Skip error token and tokens without identifier. */
488 if (sym != errtoken && id)
489 {
490 fprintf (out, "%s[[[%s]], %d]",
491 sep, id, number);
492 sep = ",\n";
493 }
091e20bb 494 }
dafdc66f 495 fputs ("])\n\n", out);
091e20bb
AD
496}
497
498
4a120d45 499static void
c6f1a33c 500prepare_actions (void)
6c89f1c1 501{
c6f1a33c 502 /* Figure out the actions for the specified state, indexed by
742e4900 503 lookahead token type. */
bbb5bcc6 504
c6f1a33c
AD
505 muscle_insert_rule_number_table ("defact", yydefact,
506 yydefact[0], 1, nstates);
6c89f1c1 507
c6f1a33c
AD
508 /* Figure out what to do after reducing with each rule, depending on
509 the saved state from before the beginning of parsing the data
510 that matched this rule. */
d57650a5
AD
511 muscle_insert_state_number_table ("defgoto", yydefgoto,
512 yydefgoto[0], 1, nsyms - ntokens);
12b0043a 513
12b0043a 514
12b0043a
AD
515 /* Output PACT. */
516 muscle_insert_base_table ("pact", base,
5372019f 517 base[0], 1, nstates);
12b0043a 518 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
c3e23647 519
12b0043a
AD
520 /* Output PGOTO. */
521 muscle_insert_base_table ("pgoto", base,
5372019f 522 base[nstates], nstates + 1, nvectors);
c3e23647 523
12b0043a
AD
524 muscle_insert_base_table ("table", table,
525 table[0], 1, high + 1);
526 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
676385e2 527
12b0043a
AD
528 muscle_insert_base_table ("check", check,
529 check[0], 1, high + 1);
c3e23647 530
ea99527d
AD
531 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
532 YYPACT) so that in states with unresolved conflicts, the default
533 reduction is not used in the conflicted entries, so that there is
534 a place to put a conflict pointer.
535
536 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
537 parser, so we could avoid accidents by not writing them out in
538 that case. Nevertheless, it seems even better to be able to use
539 the GLR skeletons even without the non-deterministic tables. */
540 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
39912f52 541 conflict_table[0], 1, high + 1);
ea99527d 542 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
da2a7671 543 0, 1, conflict_list_cnt);
6c89f1c1 544}
4175f6bb
AD
545
546
547/*--------------------------------------------.
548| Output the definitions of all the muscles. |
549`--------------------------------------------*/
550
551static void
552muscles_output (FILE *out)
553{
554 fputs ("m4_init()\n", out);
4175f6bb 555 merger_output (out);
d69c9694
AD
556 symbol_numbers_output (out);
557 token_definitions_output (out);
4c3cc7da 558 type_names_output (out);
d69c9694 559 user_actions_output (out);
4c3cc7da 560 // Must be last.
4175f6bb
AD
561 muscles_m4_output (out);
562}
652def80 563\f
1239777d
AD
564/*---------------------------.
565| Call the skeleton parser. |
566`---------------------------*/
c3e23647 567
4a120d45 568static void
1239777d 569output_skeleton (void)
9b3add5b 570{
573312ac 571 FILE *in;
573312ac 572 int filter_fd[2];
d8911864 573 char const *argv[10];
573312ac
PE
574 pid_t pid;
575
a9fc7990 576 /* Compute the names of the package data dir and skeleton files. */
573312ac 577 char const m4sugar[] = "m4sugar/m4sugar.m4";
90b9908d 578 char const m4bison[] = "bison.m4";
2fd4e131 579 char *full_m4sugar;
90b9908d 580 char *full_m4bison;
eecf08fe 581 char *full_skeleton;
573312ac
PE
582 char const *p;
583 char const *m4 = (p = getenv ("M4")) ? p : M4;
d4bd2295 584 char const *pkgdatadir = compute_pkgdatadir ();
573312ac
PE
585 size_t skeleton_size = strlen (skeleton) + 1;
586 size_t pkgdatadirlen = strlen (pkgdatadir);
587 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
588 pkgdatadirlen--;
eecf08fe
PE
589 full_skeleton = xmalloc (pkgdatadirlen + 1
590 + (skeleton_size < sizeof m4sugar
591 ? sizeof m4sugar : skeleton_size));
a7867f53 592 strncpy (full_skeleton, pkgdatadir, pkgdatadirlen);
eecf08fe
PE
593 full_skeleton[pkgdatadirlen] = '/';
594 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
595 full_m4sugar = xstrdup (full_skeleton);
90b9908d
PB
596 strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
597 full_m4bison = xstrdup (full_skeleton);
a7867f53
JD
598 if (strchr (skeleton, '/'))
599 strcpy (full_skeleton, skeleton);
600 else
601 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
a9fc7990
JD
602
603 /* Test whether m4sugar.m4 is readable, to check for proper
604 installation. A faulty installation can cause deadlock, so a
605 cheap sanity check is worthwhile. */
2fd4e131 606 xfclose (xfopen (full_m4sugar, "r"));
573312ac
PE
607
608 /* Create an m4 subprocess connected to us via two pipes. */
609
610 if (trace_flag & trace_tools)
90b9908d 611 fprintf (stderr, "running: %s %s - %s %s\n",
a9fc7990 612 m4, full_m4sugar, full_m4bison, full_skeleton);
573312ac 613
a9fc7990
JD
614 /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
615 position-dependent manner. Keep it as the first argument so that all
616 files are traced.
573312ac 617
a9fc7990
JD
618 See the thread starting at
619 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
620 for details. */
621 {
622 int i = 0;
623 argv[i++] = m4;
d8911864
EB
624
625 /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU
626 extensions, which Bison's skeletons depend on. With older M4,
627 it has no effect. M4 1.4.12 added a -g/--gnu command-line
628 option to make it explicit that a program wants GNU M4
629 extensions even when POSIXLY_CORRECT is set.
630
631 See the thread starting at
632 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
633 for details. */
634 if (*M4_GNU_OPTION)
635 argv[i++] = M4_GNU_OPTION;
636
d67c52e8
EB
637 argv[i++] = "-I";
638 argv[i++] = pkgdatadir;
a9fc7990
JD
639 if (trace_flag & trace_m4)
640 argv[i++] = "-dV";
641 argv[i++] = full_m4sugar;
642 argv[i++] = "-";
643 argv[i++] = full_m4bison;
644 argv[i++] = full_skeleton;
645 argv[i++] = NULL;
9789acf0 646 aver (i <= ARRAY_CARDINALITY (argv));
a9fc7990 647 }
a9fc7990 648
f39ab286
JD
649 /* The ugly cast is because gnulib gets the const-ness wrong. */
650 pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
651 true, filter_fd);
2fd4e131 652 free (full_m4sugar);
a9fc7990 653 free (full_m4bison);
eecf08fe 654 free (full_skeleton);
573312ac 655
5263bea9
AD
656 if (trace_flag & trace_muscles)
657 muscles_output (stderr);
658 {
f39ab286 659 FILE *out = fdopen (filter_fd[1], "w");
5263bea9
AD
660 if (! out)
661 error (EXIT_FAILURE, get_errno (),
662 "fdopen");
663 muscles_output (out);
664 xfclose (out);
665 }
be2a1a68 666
573312ac 667 /* Read and process m4's output. */
1509d42f 668 timevar_push (TV_M4);
f39ab286 669 in = fdopen (filter_fd[0], "r");
573312ac 670 if (! in)
04098407
PE
671 error (EXIT_FAILURE, get_errno (),
672 "fdopen");
573312ac 673 scan_skel (in);
f39ab286
JD
674 /* scan_skel should have read all of M4's output. Otherwise, when we
675 close the pipe, we risk letting M4 report a broken-pipe to the
676 Bison user. */
677 aver (feof (in));
573312ac 678 xfclose (in);
f39ab286 679 wait_subprocess (pid, "m4", false, false, true, true, NULL);
1509d42f 680 timevar_pop (TV_M4);
26f609ff
RA
681}
682
683static void
684prepare (void)
685{
945e396c
JD
686 /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented
687 for the user. */
688 char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL");
689 bool use_push_for_pull_flag = false;
690 if (use_push_for_pull_env != NULL
691 && use_push_for_pull_env[0] != '\0'
692 && 0 != strcmp (use_push_for_pull_env, "0"))
693 use_push_for_pull_flag = true;
694
7db2ed2d 695 /* Flags. */
d0829076 696 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
90b9908d 697 MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
90b9908d 698 MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
d0829076 699 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
ddc8ede1 700 MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
95021767 701 MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
b931235e 702 MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
11d82f03 703
573a6cd3 704 /* File names. */
90b9908d
PB
705 if (spec_name_prefix)
706 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
707
bd9d212b
JD
708 MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
709
2b81e969
AD
710#define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
711 DEFINE (dir_prefix);
712 DEFINE (parser_file_name);
713 DEFINE (spec_defines_file);
714 DEFINE (spec_file_prefix);
715 DEFINE (spec_graph_file);
716 DEFINE (spec_name_prefix);
717 DEFINE (spec_outfile);
718 DEFINE (spec_verbose_file);
719#undef DEFINE
b85810ae 720
0e021770
PE
721 /* Find the right skeleton file, and add muscles about the skeletons. */
722 if (skeleton)
723 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
724 else
725 skeleton = language->skeleton;
381fb12e 726
0e021770 727 /* About the skeletons. */
cf147260 728 {
bd9d212b
JD
729 /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
730 would never be expanded. Hopefully no one has M4-special characters in
731 his Bison installation path. */
d4bd2295 732 MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ());
cf147260 733 }
26f609ff 734}
c3e23647 735
93ede233 736
6c89f1c1
AD
737/*----------------------------------------------------------.
738| Output the parsing tables and the parser code to ftable. |
739`----------------------------------------------------------*/
c3e23647 740
6c89f1c1
AD
741void
742output (void)
743{
f87685c3 744 obstack_init (&format_obstack);
dd60faec 745
39912f52 746 prepare_symbols ();
b0940840
AD
747 prepare_rules ();
748 prepare_states ();
536545f3 749 prepare_actions ();
d73e55e0 750 prepare_symbol_definitions ();
342b8b6e 751
26f609ff 752 prepare ();
652def80 753
9b3add5b
RA
754 /* Process the selected skeleton file. */
755 output_skeleton ();
756
f499b062 757 obstack_free (&format_obstack, NULL);
c3e23647 758}
d4bd2295
JD
759
760char const *
761compute_pkgdatadir (void)
762{
763 char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
764 return pkgdatadir ? pkgdatadir : PKGDATADIR;
765}