1 /* Output the generated parsing program for Bison.
3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
4 Free Software Foundation, Inc.
6 This file is part of Bison, the GNU Compiler Compiler.
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)
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.
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
20 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #include <get-errno.h>
36 #include "muscle_tab.h"
42 /* From src/scan-skel.l. */
43 void scan_skel (FILE *);
46 static struct obstack format_obstack
;
48 int error_verbose
= 0;
52 /*-------------------------------------------------------------------.
53 | Create a function NAME which associates to the muscle NAME the |
54 | result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
55 | TYPE), and to the muscle NAME_max, the max value of the |
57 `-------------------------------------------------------------------*/
60 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
63 Name (const char *name, \
76 obstack_fgrow1 (&format_obstack, "%6d", first); \
77 for (i = begin; i < end; ++i) \
79 obstack_1grow (&format_obstack, ','); \
82 obstack_sgrow (&format_obstack, "\n "); \
87 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
88 if (table_data[i] < min) \
89 min = table_data[i]; \
90 if (max < table_data[i]) \
91 max = table_data[i]; \
93 obstack_1grow (&format_obstack, 0); \
94 muscle_insert (name, obstack_finish (&format_obstack)); \
98 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
99 obstack_fgrow1 (&format_obstack, "%s_min", name); \
100 obstack_1grow (&format_obstack, 0); \
101 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \
102 obstack_fgrow1 (&format_obstack, "%s_max", name); \
103 obstack_1grow (&format_obstack, 0); \
104 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \
107 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table
, unsigned int)
108 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table
, int)
109 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_short_table
, short)
110 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table
, base_number
)
111 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table
, rule_number
)
112 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table
, symbol_number
)
113 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table
, item_number
)
114 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table
, state_number
)
117 /*----------------------------------------------------------------------.
118 | Print to OUT a representation of FILENAME escaped both for C and M4. |
119 `----------------------------------------------------------------------*/
122 escaped_file_name_output (FILE *out
, char const *filename
)
127 for (p
= quotearg_style (c_quoting_style
, filename
); *p
; p
++)
130 case '$': fputs ("$][", out
); break;
131 case '@': fputs ("@@", out
); break;
132 case '[': fputs ("@{", out
); break;
133 case ']': fputs ("@}", out
); break;
134 default: fputc (*p
, out
); break;
141 /*------------------------------------------------------------------.
142 | Prepare the muscles related to the symbols: translate, tname, and |
144 `------------------------------------------------------------------*/
147 prepare_symbols (void)
149 MUSCLE_INSERT_INT ("tokens_number", ntokens
);
150 MUSCLE_INSERT_INT ("nterms_number", nvars
);
151 MUSCLE_INSERT_INT ("undef_token_number", undeftoken
->number
);
152 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number
);
154 muscle_insert_symbol_number_table ("translate",
156 token_translations
[0],
157 1, max_user_token_number
+ 1);
159 /* tname -- token names. */
163 for (i
= 0; i
< nsyms
; i
++)
165 /* Be sure not to use twice the same QUOTEARG slot:
166 SYMBOL_TAG_GET uses slot 0. */
168 quotearg_n_style (1, c_quoting_style
,
170 /* Width of the next token, including the two quotes, the comma
172 int width
= strlen (cp
) + 2;
176 obstack_sgrow (&format_obstack
, "\n ");
180 MUSCLE_OBSTACK_SGROW (&format_obstack
, cp
);
181 obstack_sgrow (&format_obstack
, ", ");
184 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
186 obstack_sgrow (&format_obstack
, "0");
188 /* Finish table and store. */
189 obstack_1grow (&format_obstack
, 0);
190 muscle_insert ("tname", obstack_finish (&format_obstack
));
193 /* Output YYTOKNUM. */
196 int *values
= MALLOC (values
, ntokens
);
197 for (i
= 0; i
< ntokens
; ++i
)
198 values
[i
] = symbols
[i
]->user_token_number
;
199 muscle_insert_int_table ("toknum", values
,
200 values
[0], 1, ntokens
);
206 /*-------------------------------------------------------------.
207 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
208 | rline, dprec, merger. |
209 `-------------------------------------------------------------*/
216 item_number
*rhs
= MALLOC (rhs
, nritems
);
217 unsigned int *prhs
= MALLOC (prhs
, nrules
);
218 unsigned int *rline
= MALLOC (rline
, nrules
);
219 symbol_number
*r1
= MALLOC (r1
, nrules
);
220 unsigned int *r2
= MALLOC (r2
, nrules
);
221 short *dprec
= MALLOC (dprec
, nrules
);
222 short *merger
= MALLOC (merger
, nrules
);
224 for (r
= 0; r
< nrules
; ++r
)
226 item_number
*rhsp
= NULL
;
227 /* Index of rule R in RHS. */
229 /* RHS of the rule R. */
230 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; ++rhsp
)
232 /* LHS of the rule R. */
233 r1
[r
] = rules
[r
].lhs
->number
;
234 /* Length of rule R's RHS. */
236 /* Separator in RHS. */
238 /* Line where rule was defined. */
239 rline
[r
] = rules
[r
].location
.start
.line
;
240 /* Dynamic precedence (GLR). */
241 dprec
[r
] = rules
[r
].dprec
;
242 /* Merger-function index (GLR). */
243 merger
[r
] = rules
[r
].merger
;
248 muscle_insert_item_number_table ("rhs", rhs
, ritem
[0], 1, nritems
);
249 muscle_insert_unsigned_int_table ("prhs", prhs
, 0, 0, nrules
);
250 muscle_insert_unsigned_int_table ("rline", rline
, 0, 0, nrules
);
251 muscle_insert_symbol_number_table ("r1", r1
, 0, 0, nrules
);
252 muscle_insert_unsigned_int_table ("r2", r2
, 0, 0, nrules
);
253 muscle_insert_short_table ("dprec", dprec
, 0, 0, nrules
);
254 muscle_insert_short_table ("merger", merger
, 0, 0, nrules
);
256 MUSCLE_INSERT_INT ("rules_number", nrules
);
267 /*--------------------------------------------.
268 | Prepare the muscles related to the states. |
269 `--------------------------------------------*/
272 prepare_states (void)
275 symbol_number
*values
= MALLOC (values
, nstates
);
276 for (i
= 0; i
< nstates
; ++i
)
277 values
[i
] = states
[i
]->accessing_symbol
;
278 muscle_insert_symbol_number_table ("stos", values
,
282 MUSCLE_INSERT_INT ("last", high
);
283 MUSCLE_INSERT_INT ("final_state_number", final_state
->number
);
284 MUSCLE_INSERT_INT ("states_number", nstates
);
289 /*---------------------------------.
290 | Output the user actions to OUT. |
291 `---------------------------------*/
294 user_actions_output (FILE *out
)
298 fputs ("m4_define([b4_actions], \n[[", out
);
299 for (r
= 0; r
< nrules
; ++r
)
302 fprintf (out
, " case %d:\n", r
+ 1);
304 fprintf (out
, "]b4_syncline([[%d]], ",
305 rules
[r
].action_location
.start
.line
);
306 escaped_file_name_output (out
, rules
[r
].action_location
.start
.file
);
307 fprintf (out
, ")[\n");
308 fprintf (out
, " %s\n break;\n\n",
311 fputs ("]])\n\n", out
);
314 /*--------------------------------------.
315 | Output the merge functions to OUT. |
316 `--------------------------------------*/
319 merger_output (FILE *out
)
324 fputs ("m4_define([b4_mergers], \n[[", out
);
325 for (n
= 1, p
= merge_functions
; p
!= NULL
; n
+= 1, p
= p
->next
)
327 if (p
->type
[0] == '\0')
328 fprintf (out
, " case %d: yyval = %s (*yy0, *yy1); break;\n",
331 fprintf (out
, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
332 n
, p
->type
, p
->name
);
334 fputs ("]])\n\n", out
);
337 /*--------------------------------------.
338 | Output the tokens definition to OUT. |
339 `--------------------------------------*/
342 token_definitions_output (FILE *out
)
347 fputs ("m4_define([b4_tokens], \n[", out
);
348 for (i
= 0; i
< ntokens
; ++i
)
350 symbol
*sym
= symbols
[i
];
351 int number
= sym
->user_token_number
;
353 /* At this stage, if there are literal aliases, they are part of
354 SYMBOLS, so we should not find symbols which are the aliases
356 if (number
== USER_NUMBER_ALIAS
)
359 /* Skip error token. */
363 /* If this string has an alias, then it is necessarily the alias
364 which is to be output. */
368 /* Don't output literal chars or strings (when defined only as a
369 string). Note that must be done after the alias resolution:
370 think about `%token 'f' "f"'. */
371 if (sym
->tag
[0] == '\'' || sym
->tag
[0] == '\"')
374 /* Don't #define nonliteral tokens whose names contain periods
375 or '$' (as does the default value of the EOF token). */
376 if (strchr (sym
->tag
, '.') || strchr (sym
->tag
, '$'))
379 fprintf (out
, "%s[[[%s]], [%d]]",
380 first
? "" : ",\n", sym
->tag
, number
);
384 fputs ("])\n\n", out
);
388 /*---------------------------------------.
389 | Output the symbol destructors to OUT. |
390 `---------------------------------------*/
393 symbol_destructors_output (FILE *out
)
398 fputs ("m4_define([b4_symbol_destructors], \n[", out
);
399 for (i
= 0; i
< nsyms
; ++i
)
400 if (symbols
[i
]->destructor
)
402 symbol
*sym
= symbols
[i
];
405 Symbol-name, Symbol-number,
406 destructor, typename. */
409 escaped_file_name_output (out
, sym
->destructor_location
.start
.file
);
410 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
411 sym
->destructor_location
.start
.line
,
419 fputs ("])\n\n", out
);
423 /*------------------------------------.
424 | Output the symbol printers to OUT. |
425 `------------------------------------*/
428 symbol_printers_output (FILE *out
)
433 fputs ("m4_define([b4_symbol_printers], \n[", out
);
434 for (i
= 0; i
< nsyms
; ++i
)
435 if (symbols
[i
]->destructor
)
437 symbol
*sym
= symbols
[i
];
440 Symbol-name, Symbol-number,
441 printer, typename. */
444 escaped_file_name_output (out
, sym
->printer_location
.start
.file
);
445 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
446 sym
->printer_location
.start
.line
,
454 fputs ("])\n\n", out
);
459 prepare_actions (void)
461 /* Figure out the actions for the specified state, indexed by
462 lookahead token type. */
464 muscle_insert_rule_number_table ("defact", yydefact
,
465 yydefact
[0], 1, nstates
);
467 /* Figure out what to do after reducing with each rule, depending on
468 the saved state from before the beginning of parsing the data
469 that matched this rule. */
470 muscle_insert_state_number_table ("defgoto", yydefgoto
,
471 yydefgoto
[0], 1, nsyms
- ntokens
);
475 muscle_insert_base_table ("pact", base
,
476 base
[0], 1, nstates
);
477 MUSCLE_INSERT_INT ("pact_ninf", base_ninf
);
480 muscle_insert_base_table ("pgoto", base
,
481 base
[nstates
], nstates
+ 1, nvectors
);
483 muscle_insert_base_table ("table", table
,
484 table
[0], 1, high
+ 1);
485 MUSCLE_INSERT_INT ("table_ninf", table_ninf
);
487 muscle_insert_base_table ("check", check
,
488 check
[0], 1, high
+ 1);
490 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
491 YYPACT) so that in states with unresolved conflicts, the default
492 reduction is not used in the conflicted entries, so that there is
493 a place to put a conflict pointer.
495 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
496 parser, so we could avoid accidents by not writing them out in
497 that case. Nevertheless, it seems even better to be able to use
498 the GLR skeletons even without the non-deterministic tables. */
499 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table
,
500 conflict_table
[0], 1, high
+ 1);
501 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list
,
502 conflict_list
[0], 1, conflict_list_cnt
);
506 /*---------------------------.
507 | Call the skeleton parser. |
508 `---------------------------*/
511 output_skeleton (void)
519 /* Compute the names of the package data dir and skeleton file.
520 Test whether m4sugar.m4 is readable, to check for proper
521 installation. A faulty installation can cause deadlock, so a
522 cheap sanity check is worthwhile. */
523 char const m4sugar
[] = "m4sugar/m4sugar.m4";
526 char const *m4
= (p
= getenv ("M4")) ? p
: M4
;
527 char const *pkgdatadir
= (p
= getenv ("BISON_PKGDATADIR")) ? p
: PKGDATADIR
;
528 size_t skeleton_size
= strlen (skeleton
) + 1;
529 size_t pkgdatadirlen
= strlen (pkgdatadir
);
530 while (pkgdatadirlen
&& pkgdatadir
[pkgdatadirlen
- 1] == '/')
532 full_path
= xmalloc (pkgdatadirlen
+ 1
533 + (skeleton_size
< sizeof m4sugar
534 ? sizeof m4sugar
: skeleton_size
));
535 strcpy (full_path
, pkgdatadir
);
536 full_path
[pkgdatadirlen
] = '/';
537 strcpy (full_path
+ pkgdatadirlen
+ 1, m4sugar
);
538 xfclose (xfopen (full_path
, "r"));
539 strcpy (full_path
+ pkgdatadirlen
+ 1, skeleton
);
541 /* Create an m4 subprocess connected to us via two pipes. */
543 if (trace_flag
& trace_tools
)
544 fprintf (stderr
, "running: %s -I %s %s - %s\n",
545 m4
, pkgdatadir
, m4sugar
, full_path
);
549 argv
[2] = pkgdatadir
;
556 pid
= create_subpipe (argv
, filter_fd
);
559 out
= fdopen (filter_fd
[0], "w");
561 error (EXIT_FAILURE
, get_errno (), "fdopen");
563 /* Output the definitions of all the muscles. */
564 fputs ("m4_init()\n", out
);
566 user_actions_output (out
);
568 token_definitions_output (out
);
569 symbol_destructors_output (out
);
570 symbol_printers_output (out
);
572 muscles_m4_output (out
);
574 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
575 fputs ("m4_divert_push(0)dnl\n", out
);
578 /* Read and process m4's output. */
579 timevar_push (TV_M4
);
580 in
= fdopen (filter_fd
[1], "r");
582 error (EXIT_FAILURE
, get_errno (), "fdopen");
585 reap_subpipe (pid
, m4
);
593 MUSCLE_INSERT_INT ("debug", debug_flag
);
594 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
595 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
596 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
597 MUSCLE_INSERT_INT ("pure", pure_parser
);
598 MUSCLE_INSERT_INT ("synclines_flag", !no_lines_flag
);
601 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
604 obstack_1grow (&pre_prologue_obstack
, 0);
605 obstack_1grow (&post_prologue_obstack
, 0);
606 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack
));
607 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack
));
609 /* Find the right skeleton file. */
618 /* Parse the skeleton file and output the needed parsers. */
619 MUSCLE_INSERT_C_STRING ("skeleton", skeleton
);
623 /*----------------------------------------------------------.
624 | Output the parsing tables and the parser code to ftable. |
625 `----------------------------------------------------------*/
630 obstack_init (&format_obstack
);
639 /* Process the selected skeleton file. */
642 obstack_free (&format_obstack
, NULL
);
643 obstack_free (&pre_prologue_obstack
, NULL
);
644 obstack_free (&post_prologue_obstack
, NULL
);