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
.first_line
;
233 /* Dynamic precedence (GLR) */
234 dprec
[r
] = rules
[r
].dprec
;
235 /* Merger-function index (GLR) */
236 merger
[r
] = rules
[r
].merger
;
238 assert (i
== nritems
);
240 muscle_insert_item_number_table ("rhs", rhs
, ritem
[0], 1, nritems
);
241 muscle_insert_unsigned_int_table ("prhs", prhs
, 0, 0, nrules
);
242 muscle_insert_unsigned_int_table ("rline", rline
, 0, 0, nrules
);
243 muscle_insert_symbol_number_table ("r1", r1
, 0, 0, nrules
);
244 muscle_insert_unsigned_int_table ("r2", r2
, 0, 0, nrules
);
245 muscle_insert_short_table ("dprec", dprec
, 0, 0, nrules
);
246 muscle_insert_short_table ("merger", merger
, 0, 0, nrules
);
248 MUSCLE_INSERT_INT ("rules_number", nrules
);
259 /*--------------------------------------------.
260 | Prepare the muscles related to the states. |
261 `--------------------------------------------*/
264 prepare_states (void)
267 symbol_number_t
*values
=
268 (symbol_number_t
*) alloca (sizeof (symbol_number_t
) * nstates
);
269 for (i
= 0; i
< nstates
; ++i
)
270 values
[i
] = states
[i
]->accessing_symbol
;
271 muscle_insert_symbol_number_table ("stos", values
,
274 MUSCLE_INSERT_INT ("last", high
);
275 MUSCLE_INSERT_INT ("final_state_number", final_state
->number
);
276 MUSCLE_INSERT_INT ("states_number", nstates
);
281 /*---------------------------------.
282 | Output the user actions to OUT. |
283 `---------------------------------*/
286 user_actions_output (FILE *out
)
290 fputs ("m4_define([b4_actions], \n[[", out
);
291 for (r
= 0; r
< nrules
; ++r
)
294 fprintf (out
, " case %d:\n", r
+ 1);
296 fprintf (out
, "]b4_syncline([[%d]], ",
297 rules
[r
].action_location
.first_line
);
298 escaped_file_name_output (out
, rules
[r
].action_location
.file
);
299 fprintf (out
, ")[\n");
300 fprintf (out
, " %s\n break;\n\n",
303 fputs ("]])\n\n", out
);
306 /*--------------------------------------.
307 | Output the merge functions to OUT. |
308 `--------------------------------------*/
311 merger_output (FILE *out
)
316 fputs ("m4_define([b4_mergers], \n[[", out
);
317 for (n
= 1, p
= merge_functions
; p
!= NULL
; n
+= 1, p
= p
->next
)
319 if (p
->type
[0] == '\0')
320 fprintf (out
, " case %d: yyval = %s (*yy0, *yy1); break;\n",
323 fprintf (out
, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
324 n
, p
->type
, p
->name
);
326 fputs ("]])\n\n", out
);
329 /*--------------------------------------.
330 | Output the tokens definition to OUT. |
331 `--------------------------------------*/
334 token_definitions_output (FILE *out
)
339 fputs ("m4_define([b4_tokens], \n[", out
);
340 for (i
= 0; i
< ntokens
; ++i
)
342 symbol_t
*symbol
= symbols
[i
];
343 int number
= symbol
->user_token_number
;
345 /* At this stage, if there are literal aliases, they are part of
346 SYMBOLS, so we should not find symbols which are the aliases
348 assert (number
!= USER_NUMBER_ALIAS
);
350 /* Skip error token. */
351 if (symbol
== errtoken
)
354 /* If this string has an alias, then it is necessarily the alias
355 which is to be output. */
357 symbol
= symbol
->alias
;
359 /* Don't output literal chars or strings (when defined only as a
360 string). Note that must be done after the alias resolution:
361 think about `%token 'f' "f"'. */
362 if (symbol
->tag
[0] == '\'' || symbol
->tag
[0] == '\"')
365 /* Don't #define nonliteral tokens whose names contain periods
366 or '$' (as does the default value of the EOF token). */
367 if (strchr (symbol
->tag
, '.') || strchr (symbol
->tag
, '$'))
370 fprintf (out
, "%s[[[%s]], [%d]]",
371 first
? "" : ",\n", symbol
->tag
, number
);
375 fputs ("])\n\n", out
);
379 /*---------------------------------------.
380 | Output the symbol destructors to OUT. |
381 `---------------------------------------*/
384 symbol_destructors_output (FILE *out
)
389 fputs ("m4_define([b4_symbol_destructors], \n[", out
);
390 for (i
= 0; i
< nsyms
; ++i
)
391 if (symbols
[i
]->destructor
)
393 symbol_t
*symbol
= symbols
[i
];
396 Symbol-name, Symbol-number,
397 destructor, typename. */
400 escaped_file_name_output (out
, symbol
->destructor_location
.file
);
401 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
402 symbol
->destructor_location
.first_line
,
410 fputs ("])\n\n", out
);
414 /*------------------------------------.
415 | Output the symbol printers to OUT. |
416 `------------------------------------*/
419 symbol_printers_output (FILE *out
)
424 fputs ("m4_define([b4_symbol_printers], \n[", out
);
425 for (i
= 0; i
< nsyms
; ++i
)
426 if (symbols
[i
]->destructor
)
428 symbol_t
*symbol
= symbols
[i
];
431 Symbol-name, Symbol-number,
432 printer, typename. */
435 escaped_file_name_output (out
, symbol
->printer_location
.file
);
436 fprintf (out
, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
437 symbol
->printer_location
.first_line
,
445 fputs ("])\n\n", out
);
450 prepare_actions (void)
452 /* Figure out the actions for the specified state, indexed by
453 lookahead token type. */
455 muscle_insert_rule_number_table ("defact", yydefact
,
456 yydefact
[0], 1, nstates
);
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. */
461 muscle_insert_state_number_table ("defgoto", yydefgoto
,
462 yydefgoto
[0], 1, nsyms
- ntokens
);
466 muscle_insert_base_table ("pact", base
,
467 base
[0], 1, nstates
);
468 MUSCLE_INSERT_INT ("pact_ninf", base_ninf
);
471 muscle_insert_base_table ("pgoto", base
,
472 base
[nstates
], nstates
+ 1, nvectors
);
474 muscle_insert_base_table ("table", table
,
475 table
[0], 1, high
+ 1);
476 MUSCLE_INSERT_INT ("table_ninf", table_ninf
);
478 muscle_insert_base_table ("check", check
,
479 check
[0], 1, high
+ 1);
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.
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
,
491 conflict_table
[0], 1, high
+ 1);
492 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list
,
493 conflict_list
[0], 1, conflict_list_cnt
);
497 /*---------------------------.
498 | Call the skeleton parser. |
499 `---------------------------*/
502 output_skeleton (void)
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";
517 char const *m4
= (p
= getenv ("M4")) ? p
: M4
;
518 char const *pkgdatadir
= (p
= getenv ("BISON_PKGDATADIR")) ? p
: PKGDATADIR
;
519 size_t skeleton_size
= strlen (skeleton
) + 1;
520 size_t pkgdatadirlen
= strlen (pkgdatadir
);
521 while (pkgdatadirlen
&& pkgdatadir
[pkgdatadirlen
- 1] == '/')
523 full_path
= xmalloc (pkgdatadirlen
+ 1
524 + (skeleton_size
< sizeof m4sugar
525 ? sizeof m4sugar
: skeleton_size
));
526 strcpy (full_path
, pkgdatadir
);
527 full_path
[pkgdatadirlen
] = '/';
528 strcpy (full_path
+ pkgdatadirlen
+ 1, m4sugar
);
529 in
= fopen (full_path
, "r");
531 error (EXIT_FAILURE
, errno
, "%s", full_path
);
533 strcpy (full_path
+ pkgdatadirlen
+ 1, skeleton
);
535 /* Create an m4 subprocess connected to us via two pipes. */
537 if (trace_flag
& trace_tools
)
538 fprintf (stderr
, "running: %s -I %s %s - %s\n",
539 m4
, pkgdatadir
, m4sugar
, full_path
);
543 argv
[2] = pkgdatadir
;
550 pid
= create_subpipe (argv
, filter_fd
);
553 out
= fdopen (filter_fd
[0], "w");
555 error (EXIT_FAILURE
, errno
, "fdopen");
557 /* Output the definitions of all the muscles. */
558 fputs ("m4_init()\n", out
);
560 user_actions_output (out
);
562 token_definitions_output (out
);
563 symbol_destructors_output (out
);
564 symbol_printers_output (out
);
566 muscles_m4_output (out
);
568 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
569 fputs ("m4_divert_push(0)dnl\n", out
);
572 /* Read and process m4's output. */
573 timevar_push (TV_M4
);
574 in
= fdopen (filter_fd
[1], "r");
576 error (EXIT_FAILURE
, errno
, "fdopen");
579 reap_subpipe (pid
, m4
);
587 MUSCLE_INSERT_INT ("debug", debug_flag
);
588 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
589 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
590 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
591 MUSCLE_INSERT_INT ("pure", pure_parser
);
592 MUSCLE_INSERT_INT ("synclines_flag", !no_lines_flag
);
594 /* FIXME: This is wrong: the muscles should decide whether they hold
595 a copy or not, but the situation is too obscure currently. */
596 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
599 obstack_1grow (&pre_prologue_obstack
, 0);
600 obstack_1grow (&post_prologue_obstack
, 0);
601 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack
));
602 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack
));
604 /* Find the right skeleton file. */
613 /* Parse the skeleton file and output the needed parsers. */
614 MUSCLE_INSERT_C_STRING ("skeleton", skeleton
);
618 /*----------------------------------------------------------.
619 | Output the parsing tables and the parser code to ftable. |
620 `----------------------------------------------------------*/
625 obstack_init (&format_obstack
);
634 /* Process the selected skeleton file. */
637 obstack_free (&format_obstack
, NULL
);
638 obstack_free (&pre_prologue_obstack
, NULL
);
639 obstack_free (&post_prologue_obstack
, NULL
);