]> git.saurik.com Git - bison.git/blob - src/output.c
2a45c39af3bf8e9d14414a18b78332f27c488916
[bison.git] / src / output.c
1 /* Output the generated parsing program for Bison.
2
3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
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.
12
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.
17
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., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23
24 #include "system.h"
25
26 #include <error.h>
27 #include <get-errno.h>
28 #include <quotearg.h>
29 #include <subpipe.h>
30 #include <timevar.h>
31
32 #include "complain.h"
33 #include "files.h"
34 #include "getargs.h"
35 #include "gram.h"
36 #include "muscle_tab.h"
37 #include "output.h"
38 #include "reader.h"
39 #include "symtab.h"
40 #include "tables.h"
41
42 /* From src/scan-skel.l. */
43 void scan_skel (FILE *);
44
45
46 static struct obstack format_obstack;
47
48 bool error_verbose = false;
49
50
51
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 |
56 | TABLE_DATA. |
57 `-------------------------------------------------------------------*/
58
59
60 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
61 \
62 static void \
63 Name (const char *name, \
64 Type *table_data, \
65 Type first, \
66 int begin, \
67 int end) \
68 { \
69 Type min = first; \
70 Type max = first; \
71 long int lmin; \
72 long int lmax; \
73 int i; \
74 int j = 1; \
75 \
76 obstack_fgrow1 (&format_obstack, "%6d", first); \
77 for (i = begin; i < end; ++i) \
78 { \
79 obstack_1grow (&format_obstack, ','); \
80 if (j >= 10) \
81 { \
82 obstack_sgrow (&format_obstack, "\n "); \
83 j = 1; \
84 } \
85 else \
86 ++j; \
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]; \
92 } \
93 obstack_1grow (&format_obstack, 0); \
94 muscle_insert (name, obstack_finish (&format_obstack)); \
95 \
96 lmin = min; \
97 lmax = max; \
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); \
105 }
106
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_base_table, base_number)
110 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
111 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
112 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
113 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
114
115
116 /*--------------------------------------------------------------------.
117 | Print to OUT a representation of STRING escaped both for C and M4. |
118 `--------------------------------------------------------------------*/
119
120 static void
121 escaped_output (FILE *out, char const *string)
122 {
123 char const *p;
124 fprintf (out, "[[");
125
126 for (p = quotearg_style (c_quoting_style, string); *p; p++)
127 switch (*p)
128 {
129 case '$': fputs ("$][", out); break;
130 case '@': fputs ("@@", out); break;
131 case '[': fputs ("@{", out); break;
132 case ']': fputs ("@}", out); break;
133 default: fputc (*p, out); break;
134 }
135
136 fprintf (out, "]]");
137 }
138
139
140 /*------------------------------------------------------------------.
141 | Prepare the muscles related to the symbols: translate, tname, and |
142 | toknum. |
143 `------------------------------------------------------------------*/
144
145 static void
146 prepare_symbols (void)
147 {
148 MUSCLE_INSERT_INT ("tokens_number", ntokens);
149 MUSCLE_INSERT_INT ("nterms_number", nvars);
150 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
151 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
152
153 muscle_insert_symbol_number_table ("translate",
154 token_translations,
155 token_translations[0],
156 1, max_user_token_number + 1);
157
158 /* tname -- token names. */
159 {
160 int i;
161 /* We assume that the table will be output starting at column 2. */
162 int j = 2;
163 for (i = 0; i < nsyms; i++)
164 {
165 char const *tag = symbols[i]->tag;
166 char const *cp = (*tag == '"'
167 ? tag
168 : quotearg_style (c_quoting_style, tag));
169 /* Width of the next token, including the two quotes, the
170 comma and the space. */
171 int width = strlen (cp) + 2;
172
173 if (j + width > 75)
174 {
175 obstack_sgrow (&format_obstack, "\n ");
176 j = 1;
177 }
178
179 if (i)
180 obstack_1grow (&format_obstack, ' ');
181 MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
182 obstack_1grow (&format_obstack, ',');
183 j += width;
184 }
185 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
186 defined). */
187 obstack_sgrow (&format_obstack, " 0");
188
189 /* Finish table and store. */
190 obstack_1grow (&format_obstack, 0);
191 muscle_insert ("tname", obstack_finish (&format_obstack));
192 }
193
194 /* Output YYTOKNUM. */
195 {
196 int i;
197 int *values = xnmalloc (ntokens, sizeof *values);
198 for (i = 0; i < ntokens; ++i)
199 values[i] = symbols[i]->user_token_number;
200 muscle_insert_int_table ("toknum", values,
201 values[0], 1, ntokens);
202 free (values);
203 }
204 }
205
206
207 /*-------------------------------------------------------------.
208 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
209 | rline, dprec, merger. |
210 `-------------------------------------------------------------*/
211
212 static void
213 prepare_rules (void)
214 {
215 rule_number r;
216 unsigned int i = 0;
217 item_number *rhs = xnmalloc (nritems, sizeof *rhs);
218 unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
219 unsigned int *rline = xnmalloc (nrules, sizeof *rline);
220 symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
221 unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
222 int *dprec = xnmalloc (nrules, sizeof *dprec);
223 int *merger = xnmalloc (nrules, sizeof *merger);
224
225 for (r = 0; r < nrules; ++r)
226 {
227 item_number *rhsp = NULL;
228 /* Index of rule R in RHS. */
229 prhs[r] = i;
230 /* RHS of the rule R. */
231 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
232 rhs[i++] = *rhsp;
233 /* LHS of the rule R. */
234 r1[r] = rules[r].lhs->number;
235 /* Length of rule R's RHS. */
236 r2[r] = i - prhs[r];
237 /* Separator in RHS. */
238 rhs[i++] = -1;
239 /* Line where rule was defined. */
240 rline[r] = rules[r].location.start.line;
241 /* Dynamic precedence (GLR). */
242 dprec[r] = rules[r].dprec;
243 /* Merger-function index (GLR). */
244 merger[r] = rules[r].merger;
245 }
246 if (i != nritems)
247 abort ();
248
249 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
250 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
251 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
252 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
253 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
254 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
255 muscle_insert_int_table ("merger", merger, 0, 0, nrules);
256
257 MUSCLE_INSERT_INT ("rules_number", nrules);
258 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
259
260 free (rhs);
261 free (prhs);
262 free (rline);
263 free (r1);
264 free (r2);
265 free (dprec);
266 free (merger);
267 }
268
269 /*--------------------------------------------.
270 | Prepare the muscles related to the states. |
271 `--------------------------------------------*/
272
273 static void
274 prepare_states (void)
275 {
276 state_number i;
277 symbol_number *values = xnmalloc (nstates, sizeof *values);
278 for (i = 0; i < nstates; ++i)
279 values[i] = states[i]->accessing_symbol;
280 muscle_insert_symbol_number_table ("stos", values,
281 0, 1, nstates);
282 free (values);
283
284 MUSCLE_INSERT_INT ("last", high);
285 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
286 MUSCLE_INSERT_INT ("states_number", nstates);
287 }
288
289
290
291 /*---------------------------------.
292 | Output the user actions to OUT. |
293 `---------------------------------*/
294
295 static void
296 user_actions_output (FILE *out)
297 {
298 rule_number r;
299
300 fputs ("m4_define([b4_actions], \n[[", out);
301 for (r = 0; r < nrules; ++r)
302 if (rules[r].action)
303 {
304 fprintf (out, " case %d:\n", r + 1);
305
306 fprintf (out, "]b4_syncline(%d, ",
307 rules[r].action_location.start.line);
308 escaped_output (out, rules[r].action_location.start.file);
309 fprintf (out, ")[\n");
310 fprintf (out, " %s\n break;\n\n",
311 rules[r].action);
312 }
313 fputs ("]])\n\n", out);
314 }
315
316 /*--------------------------------------.
317 | Output the merge functions to OUT. |
318 `--------------------------------------*/
319
320 static void
321 merger_output (FILE *out)
322 {
323 int n;
324 merger_list* p;
325
326 fputs ("m4_define([b4_mergers], \n[[", out);
327 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
328 {
329 if (p->type[0] == '\0')
330 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
331 n, p->name);
332 else
333 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
334 n, p->type, p->name);
335 }
336 fputs ("]])\n\n", out);
337 }
338
339 /*--------------------------------------.
340 | Output the tokens definition to OUT. |
341 `--------------------------------------*/
342
343 static void
344 token_definitions_output (FILE *out)
345 {
346 int i;
347 char const *sep = "";
348
349 fputs ("m4_define([b4_tokens], \n[", out);
350 for (i = 0; i < ntokens; ++i)
351 {
352 symbol *sym = symbols[i];
353 int number = sym->user_token_number;
354
355 /* At this stage, if there are literal aliases, they are part of
356 SYMBOLS, so we should not find symbols which are the aliases
357 here. */
358 if (number == USER_NUMBER_ALIAS)
359 abort ();
360
361 /* Skip error token. */
362 if (sym == errtoken)
363 continue;
364
365 /* If this string has an alias, then it is necessarily the alias
366 which is to be output. */
367 if (sym->alias)
368 sym = sym->alias;
369
370 /* Don't output literal chars or strings (when defined only as a
371 string). Note that must be done after the alias resolution:
372 think about `%token 'f' "f"'. */
373 if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
374 continue;
375
376 /* Don't #define nonliteral tokens whose names contain periods
377 or '$' (as does the default value of the EOF token). */
378 if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
379 continue;
380
381 fprintf (out, "%s[[[%s]], %d]",
382 sep, sym->tag, number);
383 sep = ",\n";
384 }
385 fputs ("])\n\n", out);
386 }
387
388
389 /*---------------------------------------.
390 | Output the symbol destructors to OUT. |
391 `---------------------------------------*/
392
393 static void
394 symbol_destructors_output (FILE *out)
395 {
396 int i;
397 char const *sep = "";
398
399 fputs ("m4_define([b4_symbol_destructors], \n[", out);
400 for (i = 0; i < nsyms; ++i)
401 if (symbols[i]->destructor)
402 {
403 symbol *sym = symbols[i];
404
405 /* Filename, lineno,
406 Symbol-name, Symbol-number,
407 destructor, optional typename. */
408 fprintf (out, "%s[", sep);
409 sep = ",\n";
410 escaped_output (out, sym->destructor_location.start.file);
411 fprintf (out, ", %d, ", sym->destructor_location.start.line);
412 escaped_output (out, sym->tag);
413 fprintf (out, ", %d, [[%s]]", sym->number, sym->destructor);
414 if (sym->type_name)
415 fprintf (out, ", [[%s]]", sym->type_name);
416 fputc (']', out);
417 }
418 fputs ("])\n\n", out);
419 }
420
421
422 /*------------------------------------.
423 | Output the symbol printers to OUT. |
424 `------------------------------------*/
425
426 static void
427 symbol_printers_output (FILE *out)
428 {
429 int i;
430 char const *sep = "";
431
432 fputs ("m4_define([b4_symbol_printers], \n[", out);
433 for (i = 0; i < nsyms; ++i)
434 if (symbols[i]->printer)
435 {
436 symbol *sym = symbols[i];
437
438 /* Filename, lineno,
439 Symbol-name, Symbol-number,
440 printer, optional typename. */
441 fprintf (out, "%s[", sep);
442 sep = ",\n";
443 escaped_output (out, sym->printer_location.start.file);
444 fprintf (out, ", %d, ", sym->printer_location.start.line);
445 escaped_output (out, sym->tag);
446 fprintf (out, ", %d, [[%s]]", sym->number, sym->printer);
447 if (sym->type_name)
448 fprintf (out, ", [[%s]]", sym->type_name);
449 fputc (']', out);
450 }
451 fputs ("])\n\n", out);
452 }
453
454
455 static void
456 prepare_actions (void)
457 {
458 /* Figure out the actions for the specified state, indexed by
459 look-ahead token type. */
460
461 muscle_insert_rule_number_table ("defact", yydefact,
462 yydefact[0], 1, nstates);
463
464 /* Figure out what to do after reducing with each rule, depending on
465 the saved state from before the beginning of parsing the data
466 that matched this rule. */
467 muscle_insert_state_number_table ("defgoto", yydefgoto,
468 yydefgoto[0], 1, nsyms - ntokens);
469
470
471 /* Output PACT. */
472 muscle_insert_base_table ("pact", base,
473 base[0], 1, nstates);
474 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
475
476 /* Output PGOTO. */
477 muscle_insert_base_table ("pgoto", base,
478 base[nstates], nstates + 1, nvectors);
479
480 muscle_insert_base_table ("table", table,
481 table[0], 1, high + 1);
482 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
483
484 muscle_insert_base_table ("check", check,
485 check[0], 1, high + 1);
486
487 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
488 YYPACT) so that in states with unresolved conflicts, the default
489 reduction is not used in the conflicted entries, so that there is
490 a place to put a conflict pointer.
491
492 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
493 parser, so we could avoid accidents by not writing them out in
494 that case. Nevertheless, it seems even better to be able to use
495 the GLR skeletons even without the non-deterministic tables. */
496 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
497 conflict_table[0], 1, high + 1);
498 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
499 0, 1, conflict_list_cnt);
500 }
501
502 \f
503 /*---------------------------.
504 | Call the skeleton parser. |
505 `---------------------------*/
506
507 static void
508 output_skeleton (void)
509 {
510 FILE *in;
511 FILE *out;
512 int filter_fd[2];
513 char const *argv[6];
514 pid_t pid;
515
516 /* Compute the names of the package data dir and skeleton file.
517 Test whether m4sugar.m4 is readable, to check for proper
518 installation. A faulty installation can cause deadlock, so a
519 cheap sanity check is worthwhile. */
520 char const m4sugar[] = "m4sugar/m4sugar.m4";
521 char *full_m4sugar;
522 char *full_cm4;
523 char *full_skeleton;
524 char const *p;
525 char const *m4 = (p = getenv ("M4")) ? p : M4;
526 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
527 size_t skeleton_size = strlen (skeleton) + 1;
528 size_t pkgdatadirlen = strlen (pkgdatadir);
529 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
530 pkgdatadirlen--;
531 full_skeleton = xmalloc (pkgdatadirlen + 1
532 + (skeleton_size < sizeof m4sugar
533 ? sizeof m4sugar : skeleton_size));
534 strcpy (full_skeleton, pkgdatadir);
535 full_skeleton[pkgdatadirlen] = '/';
536 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
537 full_m4sugar = xstrdup (full_skeleton);
538 strcpy (full_skeleton + pkgdatadirlen + 1, "c.m4");
539 full_cm4 = xstrdup (full_skeleton);
540 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
541 xfclose (xfopen (full_m4sugar, "r"));
542
543 /* Create an m4 subprocess connected to us via two pipes. */
544
545 if (trace_flag & trace_tools)
546 fprintf (stderr, "running: %s %s - %s %s\n",
547 m4, full_m4sugar, full_cm4, full_skeleton);
548
549 argv[0] = m4;
550 argv[1] = full_m4sugar;
551 argv[2] = "-";
552 argv[3] = full_cm4;
553 argv[4] = full_skeleton;
554 argv[5] = NULL;
555
556 init_subpipe ();
557 pid = create_subpipe (argv, filter_fd);
558 free (full_m4sugar);
559 free (full_cm4);
560 free (full_skeleton);
561
562 out = fdopen (filter_fd[0], "w");
563 if (! out)
564 error (EXIT_FAILURE, get_errno (), "fdopen");
565
566 /* Output the definitions of all the muscles. */
567 fputs ("m4_init()\n", out);
568
569 user_actions_output (out);
570 merger_output (out);
571 token_definitions_output (out);
572 symbol_destructors_output (out);
573 symbol_printers_output (out);
574
575 muscles_m4_output (out);
576
577 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
578 fputs ("m4_divert_push(0)dnl\n", out);
579 xfclose (out);
580
581 /* Read and process m4's output. */
582 timevar_push (TV_M4);
583 in = fdopen (filter_fd[1], "r");
584 if (! in)
585 error (EXIT_FAILURE, get_errno (), "fdopen");
586 scan_skel (in);
587 xfclose (in);
588 reap_subpipe (pid, m4);
589 timevar_pop (TV_M4);
590 }
591
592 static void
593 prepare (void)
594 {
595 /* Flags. */
596 MUSCLE_INSERT_BOOL ("debug", debug_flag);
597 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
598 MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
599 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
600 MUSCLE_INSERT_BOOL ("pure", pure_parser);
601 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
602
603 /* File names. */
604 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
605
606 /* User Code. */
607 obstack_1grow (&pre_prologue_obstack, 0);
608 obstack_1grow (&post_prologue_obstack, 0);
609 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
610 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
611
612 /* Find the right skeleton file. */
613 if (!skeleton)
614 {
615 if (glr_parser || nondeterministic_parser)
616 skeleton = "glr.c";
617 else
618 skeleton = "yacc.c";
619 }
620
621 /* Parse the skeleton file and output the needed parsers. */
622 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
623 }
624
625
626 /*----------------------------------------------------------.
627 | Output the parsing tables and the parser code to ftable. |
628 `----------------------------------------------------------*/
629
630 void
631 output (void)
632 {
633 obstack_init (&format_obstack);
634
635 prepare_symbols ();
636 prepare_rules ();
637 prepare_states ();
638 prepare_actions ();
639
640 prepare ();
641
642 /* Process the selected skeleton file. */
643 output_skeleton ();
644
645 obstack_free (&format_obstack, NULL);
646 obstack_free (&pre_prologue_obstack, NULL);
647 obstack_free (&post_prologue_obstack, NULL);
648 }