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