1 /* Output the generated parsing program for Bison.
2 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of Bison, the GNU Compiler Compiler.
7 Bison is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bison is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include "muscle_tab.h"
37 /* From src/scan-skel.l. */
38 void scan_skel (FILE *);
41 static struct obstack format_obstack
;
43 int error_verbose
= 0;
47 /*-------------------------------------------------------------------.
48 | Create a function NAME which associates to the muscle NAME the |
49 | result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
50 | TYPE), and to the muscle NAME_max, the max value of the |
52 `-------------------------------------------------------------------*/
55 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
58 Name (const char *name, \
69 obstack_fgrow1 (&format_obstack, "%6d", first); \
70 for (i = begin; i < end; ++i) \
72 obstack_1grow (&format_obstack, ','); \
75 obstack_sgrow (&format_obstack, "\n "); \
80 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
81 if (table_data[i] < min) \
82 min = table_data[i]; \
83 if (max < table_data[i]) \
84 max = table_data[i]; \
86 obstack_1grow (&format_obstack, 0); \
87 muscle_insert (name, obstack_finish (&format_obstack)); \
89 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
90 obstack_fgrow1 (&format_obstack, "%s_min", name); \
91 obstack_1grow (&format_obstack, 0); \
92 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
94 obstack_fgrow1 (&format_obstack, "%s_max", name); \
95 obstack_1grow (&format_obstack, 0); \
96 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
100 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table
, unsigned int)
101 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table
, int)
102 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_short_table
, short)
103 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table
, base_t
)
104 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table
, rule_number_t
)
105 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table
, symbol_number_t
)
106 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table
, item_number_t
)
107 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table
, state_number_t
)
110 /*----------------------------------------------------------------------.
111 | Print to OUT a representation of FILENAME escaped both for C and M4. |
112 `----------------------------------------------------------------------*/
115 escaped_file_name_output (FILE *out
, char const *filename
)
120 for (p
= quotearg_style (c_quoting_style
, filename
); *p
; p
++)
123 case '$': fputs ("$][", out
); break;
124 case '@': fputs ("@@", out
); break;
125 case '[': fputs ("@{", out
); break;
126 case ']': fputs ("@}", out
); break;
127 default: fputc (*p
, out
); break;
134 /*------------------------------------------------------------------.
135 | Prepare the muscles related to the symbols: translate, tname, and |
137 `------------------------------------------------------------------*/
140 prepare_symbols (void)
142 MUSCLE_INSERT_INT ("tokens_number", ntokens
);
143 MUSCLE_INSERT_INT ("nterms_number", nvars
);
144 MUSCLE_INSERT_INT ("undef_token_number", undeftoken
->number
);
145 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number
);
147 muscle_insert_symbol_number_table ("translate",
149 token_translations
[0],
150 1, max_user_token_number
+ 1);
152 /* tname -- token names. */
156 for (i
= 0; i
< nsyms
; i
++)
158 /* Be sure not to use twice the same QUOTEARG slot:
159 SYMBOL_TAG_GET uses slot 0. */
161 quotearg_n_style (1, c_quoting_style
,
163 /* Width of the next token, including the two quotes, the comma
165 int strsize
= strlen (cp
) + 2;
167 if (j
+ strsize
> 75)
169 obstack_sgrow (&format_obstack
, "\n ");
173 MUSCLE_OBSTACK_SGROW (&format_obstack
, cp
);
174 obstack_sgrow (&format_obstack
, ", ");
177 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
179 obstack_sgrow (&format_obstack
, "0");
181 /* Finish table and store. */
182 obstack_1grow (&format_obstack
, 0);
183 muscle_insert ("tname", obstack_finish (&format_obstack
));
186 /* Output YYTOKNUM. */
189 int *values
= XCALLOC (int, ntokens
);
190 for (i
= 0; i
< ntokens
; ++i
)
191 values
[i
] = symbols
[i
]->user_token_number
;
192 muscle_insert_int_table ("toknum", values
,
193 values
[0], 1, ntokens
);
199 /*-------------------------------------------------------------.
200 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
201 | rline, dprec, merger. |
202 `-------------------------------------------------------------*/
209 item_number_t
*rhs
= XMALLOC (item_number_t
, nritems
);
210 unsigned int *prhs
= XMALLOC (unsigned int, nrules
);
211 unsigned int *rline
= XMALLOC (unsigned int, nrules
);
212 symbol_number_t
*r1
= XMALLOC (symbol_number_t
, nrules
);
213 unsigned int *r2
= XMALLOC (unsigned int, nrules
);
214 short *dprec
= XMALLOC (short, nrules
);
215 short *merger
= XMALLOC (short, nrules
);
217 for (r
= 0; r
< nrules
; ++r
)
219 item_number_t
*rhsp
= NULL
;
220 /* Index of rule R in RHS. */
222 /* RHS of the rule R. */
223 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; ++rhsp
)
225 /* LHS of the rule R. */
226 r1
[r
] = rules
[r
].lhs
->number
;
227 /* Length of rule R's RHS. */
229 /* Separator in RHS. */
231 /* Line where rule was defined. */
232 rline
[r
] = rules
[r
].location
.start
.line
;
233 /* Dynamic precedence (GLR). */
234 dprec
[r
] = rules
[r
].dprec
;
235 /* Merger-function index (GLR). */
236 merger
[r
] = rules
[r
].merger
;
241 muscle_insert_item_number_table ("rhs", rhs
, ritem
[0], 1, nritems
);
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
);
246 muscle_insert_short_table ("dprec", dprec
, 0, 0, nrules
);
247 muscle_insert_short_table ("merger", merger
, 0, 0, nrules
);
249 MUSCLE_INSERT_INT ("rules_number", nrules
);
260 /*--------------------------------------------.
261 | Prepare the muscles related to the states. |
262 `--------------------------------------------*/
265 prepare_states (void)
268 symbol_number_t
*values
=
269 (symbol_number_t
*) alloca (sizeof (symbol_number_t
) * nstates
);
270 for (i
= 0; i
< nstates
; ++i
)
271 values
[i
] = states
[i
]->accessing_symbol
;
272 muscle_insert_symbol_number_table ("stos", values
,
275 MUSCLE_INSERT_INT ("last", high
);
276 MUSCLE_INSERT_INT ("final_state_number", final_state
->number
);
277 MUSCLE_INSERT_INT ("states_number", nstates
);
282 /*---------------------------------.
283 | Output the user actions to OUT. |
284 `---------------------------------*/
287 user_actions_output (FILE *out
)
291 fputs ("m4_define([b4_actions], \n[[", out
);
292 for (r
= 0; r
< nrules
; ++r
)
295 fprintf (out
, " case %d:\n", r
+ 1);
297 fprintf (out
, "]b4_syncline([[%d]], ",
298 rules
[r
].action_location
.start
.line
);
299 escaped_file_name_output (out
, rules
[r
].action_location
.start
.file
);
300 fprintf (out
, ")[\n");
301 fprintf (out
, " %s\n break;\n\n",
304 fputs ("]])\n\n", out
);
307 /*--------------------------------------.
308 | Output the merge functions to OUT. |
309 `--------------------------------------*/
312 merger_output (FILE *out
)
317 fputs ("m4_define([b4_mergers], \n[[", out
);
318 for (n
= 1, p
= merge_functions
; p
!= NULL
; n
+= 1, p
= p
->next
)
320 if (p
->type
[0] == '\0')
321 fprintf (out
, " case %d: yyval = %s (*yy0, *yy1); break;\n",
324 fprintf (out
, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
325 n
, p
->type
, p
->name
);
327 fputs ("]])\n\n", out
);
330 /*--------------------------------------.
331 | Output the tokens definition to OUT. |
332 `--------------------------------------*/
335 token_definitions_output (FILE *out
)
340 fputs ("m4_define([b4_tokens], \n[", out
);
341 for (i
= 0; i
< ntokens
; ++i
)
343 symbol_t
*symbol
= symbols
[i
];
344 int number
= symbol
->user_token_number
;
346 /* At this stage, if there are literal aliases, they are part of
347 SYMBOLS, so we should not find symbols which are the aliases
349 if (number
== USER_NUMBER_ALIAS
)
352 /* Skip error token. */
353 if (symbol
== errtoken
)
356 /* If this string has an alias, then it is necessarily the alias
357 which is to be output. */
359 symbol
= symbol
->alias
;
361 /* Don't output literal chars or strings (when defined only as a
362 string). Note that must be done after the alias resolution:
363 think about `%token 'f' "f"'. */
364 if (symbol
->tag
[0] == '\'' || symbol
->tag
[0] == '\"')
367 /* Don't #define nonliteral tokens whose names contain periods
368 or '$' (as does the default value of the EOF token). */
369 if (strchr (symbol
->tag
, '.') || strchr (symbol
->tag
, '$'))
372 fprintf (out
, "%s[[[%s]], [%d]]",
373 first
? "" : ",\n", symbol
->tag
, number
);
377 fputs ("])\n\n", out
);
381 /*---------------------------------------.
382 | Output the symbol destructors to OUT. |
383 `---------------------------------------*/
386 symbol_destructors_output (FILE *out
)
391 fputs ("m4_define([b4_symbol_destructors], \n[", out
);
392 for (i
= 0; i
< nsyms
; ++i
)
393 if (symbols
[i
]->destructor
)
395 symbol_t
*symbol
= symbols
[i
];
398 Symbol-name, Symbol-number,
399 destructor, typename. */
402 escaped_file_name_output (out
, symbol
->destructor_location
.start
.file
);
403 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
404 symbol
->destructor_location
.start
.line
,
412 fputs ("])\n\n", out
);
416 /*------------------------------------.
417 | Output the symbol printers to OUT. |
418 `------------------------------------*/
421 symbol_printers_output (FILE *out
)
426 fputs ("m4_define([b4_symbol_printers], \n[", out
);
427 for (i
= 0; i
< nsyms
; ++i
)
428 if (symbols
[i
]->destructor
)
430 symbol_t
*symbol
= symbols
[i
];
433 Symbol-name, Symbol-number,
434 printer, typename. */
437 escaped_file_name_output (out
, symbol
->printer_location
.start
.file
);
438 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
439 symbol
->printer_location
.start
.line
,
447 fputs ("])\n\n", out
);
452 prepare_actions (void)
454 /* Figure out the actions for the specified state, indexed by
455 lookahead token type. */
457 muscle_insert_rule_number_table ("defact", yydefact
,
458 yydefact
[0], 1, nstates
);
460 /* Figure out what to do after reducing with each rule, depending on
461 the saved state from before the beginning of parsing the data
462 that matched this rule. */
463 muscle_insert_state_number_table ("defgoto", yydefgoto
,
464 yydefgoto
[0], 1, nsyms
- ntokens
);
468 muscle_insert_base_table ("pact", base
,
469 base
[0], 1, nstates
);
470 MUSCLE_INSERT_INT ("pact_ninf", base_ninf
);
473 muscle_insert_base_table ("pgoto", base
,
474 base
[nstates
], nstates
+ 1, nvectors
);
476 muscle_insert_base_table ("table", table
,
477 table
[0], 1, high
+ 1);
478 MUSCLE_INSERT_INT ("table_ninf", table_ninf
);
480 muscle_insert_base_table ("check", check
,
481 check
[0], 1, high
+ 1);
483 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
484 YYPACT) so that in states with unresolved conflicts, the default
485 reduction is not used in the conflicted entries, so that there is
486 a place to put a conflict pointer.
488 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
489 parser, so we could avoid accidents by not writing them out in
490 that case. Nevertheless, it seems even better to be able to use
491 the GLR skeletons even without the non-deterministic tables. */
492 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table
,
493 conflict_table
[0], 1, high
+ 1);
494 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list
,
495 conflict_list
[0], 1, conflict_list_cnt
);
499 /*---------------------------.
500 | Call the skeleton parser. |
501 `---------------------------*/
504 output_skeleton (void)
512 /* Compute the names of the package data dir and skeleton file.
513 Test whether m4sugar.m4 is readable, to check for proper
514 installation. A faulty installation can cause deadlock, so a
515 cheap sanity check is worthwhile. */
516 char const m4sugar
[] = "m4sugar/m4sugar.m4";
519 char const *m4
= (p
= getenv ("M4")) ? p
: M4
;
520 char const *pkgdatadir
= (p
= getenv ("BISON_PKGDATADIR")) ? p
: PKGDATADIR
;
521 size_t skeleton_size
= strlen (skeleton
) + 1;
522 size_t pkgdatadirlen
= strlen (pkgdatadir
);
523 while (pkgdatadirlen
&& pkgdatadir
[pkgdatadirlen
- 1] == '/')
525 full_path
= xmalloc (pkgdatadirlen
+ 1
526 + (skeleton_size
< sizeof m4sugar
527 ? sizeof m4sugar
: skeleton_size
));
528 strcpy (full_path
, pkgdatadir
);
529 full_path
[pkgdatadirlen
] = '/';
530 strcpy (full_path
+ pkgdatadirlen
+ 1, m4sugar
);
531 xfclose (xfopen (full_path
, "r"));
532 strcpy (full_path
+ pkgdatadirlen
+ 1, skeleton
);
534 /* Create an m4 subprocess connected to us via two pipes. */
536 if (trace_flag
& trace_tools
)
537 fprintf (stderr
, "running: %s -I %s %s - %s\n",
538 m4
, pkgdatadir
, m4sugar
, full_path
);
542 argv
[2] = pkgdatadir
;
549 pid
= create_subpipe (argv
, filter_fd
);
552 out
= fdopen (filter_fd
[0], "w");
554 error (EXIT_FAILURE
, errno
, "fdopen");
556 /* Output the definitions of all the muscles. */
557 fputs ("m4_init()\n", out
);
559 user_actions_output (out
);
561 token_definitions_output (out
);
562 symbol_destructors_output (out
);
563 symbol_printers_output (out
);
565 muscles_m4_output (out
);
567 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
568 fputs ("m4_divert_push(0)dnl\n", out
);
571 /* Read and process m4's output. */
572 timevar_push (TV_M4
);
573 in
= fdopen (filter_fd
[1], "r");
575 error (EXIT_FAILURE
, errno
, "fdopen");
578 reap_subpipe (pid
, m4
);
586 MUSCLE_INSERT_INT ("debug", debug_flag
);
587 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
588 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
589 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
590 MUSCLE_INSERT_INT ("pure", pure_parser
);
591 MUSCLE_INSERT_INT ("synclines_flag", !no_lines_flag
);
594 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
597 obstack_1grow (&pre_prologue_obstack
, 0);
598 obstack_1grow (&post_prologue_obstack
, 0);
599 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack
));
600 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack
));
602 /* Find the right skeleton file. */
611 /* Parse the skeleton file and output the needed parsers. */
612 MUSCLE_INSERT_C_STRING ("skeleton", skeleton
);
616 /*----------------------------------------------------------.
617 | Output the parsing tables and the parser code to ftable. |
618 `----------------------------------------------------------*/
623 obstack_init (&format_obstack
);
632 /* Process the selected skeleton file. */
635 obstack_free (&format_obstack
, NULL
);
636 obstack_free (&pre_prologue_obstack
, NULL
);
637 obstack_free (&post_prologue_obstack
, NULL
);