]> git.saurik.com Git - bison.git/blob - src/output.c
* src/muscle_tab.h (MUSCLE_INSERT_INT, MUSCLE_INSERT_STRING)
[bison.git] / src / output.c
1 /* Output the generated parsing program for bison,
2 Copyright 1984, 1986, 1989, 1992, 2000, 2001
3 Free Software Foundation, Inc.
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
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)
10 any later version.
11
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.
16
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
20 02111-1307, USA. */
21
22
23 /* The parser tables consist of these tables. Marked ones needed only
24 for the semantic parser. Double marked are output only if switches
25 are set.
26
27 YYTRANSLATE = vector mapping yylex's token numbers into bison's
28 token numbers.
29
30 ++ YYTNAME = vector of string-names indexed by bison token number.
31
32 ++ YYTOKNUM = vector of yylex token numbers corresponding to
33 entries in YYTNAME.
34
35 YYRLINE = vector of line-numbers of all rules. For yydebug
36 printouts.
37
38 YYRHS = vector of items of all rules. This is exactly what RITEMS
39 contains. For yydebug and for semantic parser.
40
41 YYPRHS[R] = index in YYRHS of first item for rule R.
42
43 YYR1[R] = symbol number of symbol that rule R derives.
44
45 YYR2[R] = number of symbols composing right hand side of rule R.
46
47 + YYSTOS[S] = the symbol number of the symbol that leads to state
48 S.
49
50 YYDEFACT[S] = default rule to reduce with in state s, when YYTABLE
51 doesn't specify something else to do. Zero means the default is an
52 error.
53
54 YYDEFGOTO[I] = default state to go to after a reduction of a rule
55 that generates variable NTOKENS + I, except when YYTABLE specifies
56 something else to do.
57
58 YYPACT[S] = index in YYTABLE of the portion describing state S.
59 The lookahead token's type is used to index that portion to find
60 out what to do.
61
62 If the value in YYTABLE is positive, we shift the token and go to
63 that state.
64
65 If the value is negative, it is minus a rule number to reduce by.
66
67 If the value is zero, the default action from YYDEFACT[S] is used.
68
69 YYPGOTO[I] = the index in YYTABLE of the portion describing what to
70 do after reducing a rule that derives variable I + NTOKENS. This
71 portion is indexed by the parser state number, S, as of before the
72 text for this nonterminal was read. The value from YYTABLE is the
73 state to go to if the corresponding value in YYCHECK is S.
74
75 YYTABLE = a vector filled with portions for different uses, found
76 via YYPACT and YYPGOTO.
77
78 YYCHECK = a vector indexed in parallel with YYTABLE. It indicates,
79 in a roundabout way, the bounds of the portion you are trying to
80 examine.
81
82 Suppose that the portion of yytable starts at index P and the index
83 to be examined within the portion is I. Then if YYCHECK[P+I] != I,
84 I is outside the bounds of what is actually allocated, and the
85 default (from YYDEFACT or YYDEFGOTO) should be used. Otherwise,
86 YYTABLE[P+I] should be used.
87
88 YYFINAL = the state number of the termination state. YYFLAG = most
89 negative short int. Used to flag ?? */
90
91 #include "system.h"
92 #include "quotearg.h"
93 #include "getargs.h"
94 #include "files.h"
95 #include "gram.h"
96 #include "LR0.h"
97 #include "complain.h"
98 #include "output.h"
99 #include "lalr.h"
100 #include "reader.h"
101 #include "symtab.h"
102 #include "conflicts.h"
103 #include "muscle_tab.h"
104
105
106 static int nvectors;
107 static int nentries;
108 static short **froms = NULL;
109 static short **tos = NULL;
110 static short *tally = NULL;
111 static short *width = NULL;
112 static short *actrow = NULL;
113 static short *state_count = NULL;
114 static short *order = NULL;
115 static short *base = NULL;
116 static short *pos = NULL;
117 static short *table = NULL;
118 static short *check = NULL;
119 static int lowzero;
120 static int high;
121
122 struct obstack muscle_obstack;
123 static struct obstack format_obstack;
124
125 int error_verbose = 0;
126
127 /* Returns the number of lines of S. */
128 size_t
129 get_lines_number (const char *s)
130 {
131 size_t lines = 0;
132
133 size_t i;
134 for (i = 0; s[i]; ++i)
135 if (s[i] == '\n')
136 ++lines;
137
138 return lines;
139 }
140
141
142 /* FIXME. */
143
144 static inline void
145 output_table_data (struct obstack *oout,
146 short *table_data,
147 short first,
148 int begin,
149 int end)
150 {
151 int i;
152 int j = 1;
153
154 obstack_fgrow1 (oout, "%6d", first);
155 for (i = begin; i < end; ++i)
156 {
157 obstack_1grow (oout, ',');
158 if (j >= 10)
159 {
160 obstack_sgrow (oout, "\n ");
161 j = 1;
162 }
163 else
164 ++j;
165 obstack_fgrow1 (oout, "%6d", table_data[i]);
166 }
167 obstack_1grow (oout, 0);
168 }
169
170
171 static void
172 output_token_translations (void)
173 {
174 output_table_data (&format_obstack, token_translations,
175 0, 1, max_user_token_number + 1);
176 muscle_insert ("translate", obstack_finish (&format_obstack));
177 XFREE (token_translations);
178 }
179
180
181 static void
182 output_gram (void)
183 {
184 {
185 int i;
186 short *values = XCALLOC (short, nrules + 1);
187 for (i = 0; i < nrules + 1; ++i)
188 values[i] = rules[i].rhs;
189 output_table_data (&format_obstack, values,
190 0, 1, nrules + 1);
191 XFREE (values);
192 }
193
194 muscle_insert ("prhs", obstack_finish (&format_obstack));
195
196 {
197 short *yyrhs;
198 int i;
199
200 yyrhs = XMALLOC (short, nritems);
201
202 for (i = 1; i < nritems; ++i)
203 yyrhs[i] = ritem[i] >= 0 ? ritem[i] : -1;
204
205 output_table_data (&format_obstack, yyrhs,
206 ritem[0], 1, nritems);
207 muscle_insert ("rhs", obstack_finish (&format_obstack));
208
209 XFREE (yyrhs);
210 }
211
212 #if 0
213 if (!semantic_parser)
214 obstack_sgrow (&table_obstack, "\n#endif\n");
215 #endif
216 }
217
218
219 static void
220 output_stos (void)
221 {
222 int i;
223 short *values = (short *) alloca (sizeof (short) * nstates);
224 for (i = 0; i < nstates; ++i)
225 values[i] = states[i]->accessing_symbol;
226 output_table_data (&format_obstack, values,
227 0, 1, nstates);
228 muscle_insert ("stos", obstack_finish (&format_obstack));
229 }
230
231
232 static void
233 output_rule_data (void)
234 {
235 int i;
236 int j;
237 short *short_tab = NULL;
238
239 {
240 short *values = XCALLOC (short, nrules + 1);
241 for (i = 0; i < nrules + 1; ++i)
242 values[i] = rules[i].line;
243 output_table_data (&format_obstack, values,
244 0, 1, nrules + 1);
245 muscle_insert ("rline", obstack_finish (&format_obstack));
246 XFREE (values);
247 }
248
249
250 j = 0;
251 for (i = 0; i < nsyms; i++)
252 {
253 /* Be sure not to use twice the same quotearg slot. */
254 const char *cp =
255 quotearg_n_style (1, c_quoting_style,
256 quotearg_style (escape_quoting_style, symbols[i]->tag));
257 /* Width of the next token, including the two quotes, the coma
258 and the space. */
259 int strsize = strlen (cp) + 2;
260
261 if (j + strsize > 75)
262 {
263 obstack_sgrow (&format_obstack, "\n ");
264 j = 2;
265 }
266
267 obstack_sgrow (&format_obstack, cp);
268 obstack_sgrow (&format_obstack, ", ");
269 j += strsize;
270 }
271 /* add a NULL entry to list of tokens */
272 obstack_sgrow (&format_obstack, "NULL");
273
274 /* Finish table and store. */
275 obstack_1grow (&format_obstack, 0);
276 muscle_insert ("tname", obstack_finish (&format_obstack));
277
278 /* Output YYTOKNUM. */
279 {
280 short *values = XCALLOC (short, ntokens + 1);
281 for (i = 0; i < ntokens + 1; ++i)
282 values[i] = symbols[i]->user_token_number;
283 output_table_data (&format_obstack, values,
284 0, 1, ntokens + 1);
285 muscle_insert ("toknum", obstack_finish (&format_obstack));
286 XFREE (values);
287 }
288
289
290 /* Output YYR1. */
291 {
292 short *values = XCALLOC (short, nrules + 1);
293 for (i = 0; i < nrules + 1; ++i)
294 values[i] = rules[i].lhs;
295 output_table_data (&format_obstack, values,
296 0, 1, nrules + 1);
297 muscle_insert ("r1", obstack_finish (&format_obstack));
298 XFREE (values);
299 }
300
301 /* Output YYR2. */
302 short_tab = XMALLOC (short, nrules + 1);
303 for (i = 1; i < nrules; i++)
304 short_tab[i] = rules[i + 1].rhs - rules[i].rhs - 1;
305 short_tab[nrules] = nritems - rules[nrules].rhs - 1;
306 output_table_data (&format_obstack, short_tab,
307 0, 1, nrules + 1);
308 muscle_insert ("r2", obstack_finish (&format_obstack));
309 XFREE (short_tab);
310 }
311
312 /*------------------------------------------------------------------.
313 | Decide what to do for each type of token if seen as the lookahead |
314 | token in specified state. The value returned is used as the |
315 | default action (yydefact) for the state. In addition, actrow is |
316 | filled with what to do for each kind of token, index by symbol |
317 | number, with zero meaning do the default action. The value |
318 | MINSHORT, a very negative number, means this situation is an |
319 | error. The parser recognizes this value specially. |
320 | |
321 | This is where conflicts are resolved. The loop over lookahead |
322 | rules considered lower-numbered rules last, and the last rule |
323 | considered that likes a token gets to handle it. |
324 `------------------------------------------------------------------*/
325
326 static int
327 action_row (state_t *state)
328 {
329 int i;
330 int default_rule = 0;
331 reductions *redp = state->reductions;
332 shifts *shiftp = state->shifts;
333 errs *errp = state->errs;
334 /* set nonzero to inhibit having any default reduction */
335 int nodefault = 0;
336
337 for (i = 0; i < ntokens; i++)
338 actrow[i] = 0;
339
340 if (redp->nreds >= 1)
341 {
342 int j;
343 /* loop over all the rules available here which require
344 lookahead */
345 for (i = state->nlookaheads - 1; i >= 0; --i)
346 /* and find each token which the rule finds acceptable
347 to come next */
348 for (j = 0; j < ntokens; j++)
349 /* and record this rule as the rule to use if that
350 token follows. */
351 if (BITISSET (LA (state->lookaheadsp + i), j))
352 actrow[j] = -LAruleno[state->lookaheadsp + i];
353 }
354
355 /* Now see which tokens are allowed for shifts in this state. For
356 them, record the shift as the thing to do. So shift is preferred
357 to reduce. */
358 for (i = 0; i < shiftp->nshifts; i++)
359 {
360 int symbol;
361 int shift_state = shiftp->shifts[i];
362 if (!shift_state)
363 continue;
364
365 symbol = states[shift_state]->accessing_symbol;
366
367 if (ISVAR (symbol))
368 break;
369
370 actrow[symbol] = shift_state;
371
372 /* Do not use any default reduction if there is a shift for
373 error */
374 if (symbol == error_token_number)
375 nodefault = 1;
376 }
377
378 /* See which tokens are an explicit error in this state (due to
379 %nonassoc). For them, record MINSHORT as the action. */
380 for (i = 0; i < errp->nerrs; i++)
381 {
382 int symbol = errp->errs[i];
383 actrow[symbol] = MINSHORT;
384 }
385
386 /* Now find the most common reduction and make it the default action
387 for this state. */
388
389 if (redp->nreds >= 1 && !nodefault)
390 {
391 if (state->consistent)
392 default_rule = redp->rules[0];
393 else
394 {
395 int max = 0;
396 for (i = 0; i < state->nlookaheads; i++)
397 {
398 int count = 0;
399 int rule = -LAruleno[state->lookaheadsp + i];
400 int j;
401
402 for (j = 0; j < ntokens; j++)
403 if (actrow[j] == rule)
404 count++;
405
406 if (count > max)
407 {
408 max = count;
409 default_rule = rule;
410 }
411 }
412
413 /* actions which match the default are replaced with zero,
414 which means "use the default" */
415
416 if (max > 0)
417 {
418 int j;
419 for (j = 0; j < ntokens; j++)
420 if (actrow[j] == default_rule)
421 actrow[j] = 0;
422
423 default_rule = -default_rule;
424 }
425 }
426 }
427
428 /* If have no default rule, the default is an error.
429 So replace any action which says "error" with "use default". */
430
431 if (default_rule == 0)
432 for (i = 0; i < ntokens; i++)
433 if (actrow[i] == MINSHORT)
434 actrow[i] = 0;
435
436 return default_rule;
437 }
438
439
440 static void
441 save_row (int state)
442 {
443 int i;
444 int count;
445 short *sp;
446 short *sp1;
447 short *sp2;
448
449 count = 0;
450 for (i = 0; i < ntokens; i++)
451 if (actrow[i] != 0)
452 count++;
453
454 if (count == 0)
455 return;
456
457 froms[state] = sp1 = sp = XCALLOC (short, count);
458 tos[state] = sp2 = XCALLOC (short, count);
459
460 for (i = 0; i < ntokens; i++)
461 if (actrow[i] != 0)
462 {
463 *sp1++ = i;
464 *sp2++ = actrow[i];
465 }
466
467 tally[state] = count;
468 width[state] = sp1[-1] - sp[0] + 1;
469 }
470
471
472 /*------------------------------------------------------------------.
473 | Figure out the actions for the specified state, indexed by |
474 | lookahead token type. |
475 | |
476 | The YYDEFACT table is output now. The detailed info is saved for |
477 | putting into YYTABLE later. |
478 `------------------------------------------------------------------*/
479
480 static void
481 token_actions (void)
482 {
483 int i;
484 short *yydefact = XCALLOC (short, nstates);
485
486 actrow = XCALLOC (short, ntokens);
487 for (i = 0; i < nstates; ++i)
488 {
489 yydefact[i] = action_row (states[i]);
490 save_row (i);
491 }
492
493 output_table_data (&format_obstack, yydefact,
494 yydefact[0], 1, nstates);
495 muscle_insert ("defact", obstack_finish (&format_obstack));
496
497 XFREE (actrow);
498 XFREE (yydefact);
499 }
500
501
502 /*-----------------------------.
503 | Output the actions to OOUT. |
504 `-----------------------------*/
505
506 void
507 actions_output (FILE *out, size_t *line)
508 {
509 int rule;
510 for (rule = 1; rule < nrules + 1; ++rule)
511 if (rules[rule].action)
512 {
513 fprintf (out, " case %d:\n", rule);
514
515 if (!no_lines_flag)
516 fprintf (out, muscle_find ("linef"),
517 rules[rule].action_line,
518 quotearg_style (c_quoting_style,
519 muscle_find ("filename")));
520 /* As a Bison extension, add the ending semicolon. Since some
521 Yacc don't do that, help people using bison as a Yacc
522 finding their missing semicolons. */
523 fprintf (out, "{ %s%s }\n break;\n\n",
524 rules[rule].action,
525 yacc_flag ? ";" : "");
526
527 /* We always output 4 '\n' per action. */
528 *line += 4;
529 /* Plus one if !no_lines_flag. */
530 if (!no_lines_flag)
531 ++*line;
532 /* Get the number of lines written by the user. */
533 *line += get_lines_number (rules[rule].action);
534 }
535 }
536
537
538 /*----------------------------.
539 | Output the guards to OOUT. |
540 `----------------------------*/
541
542 void
543 guards_output (FILE *out, size_t *line)
544 {
545 int rule;
546 for (rule = 1; rule < nrules + 1; ++rule)
547 if (rules[rule].action)
548 {
549 fprintf (out, " case %d:\n", rule);
550
551 if (!no_lines_flag)
552 fprintf (out, muscle_find ("linef"),
553 rules[rule].guard_line,
554 quotearg_style (c_quoting_style,
555 muscle_find ("filename")));
556 fprintf (out, "{ %s; }\n break;\n\n",
557 rules[rule].guard);
558
559 /* We always output 4 '\n' per action. */
560 *line += 4;
561 /* Plus one if !no_lines_flag. */
562 if (!no_lines_flag)
563 ++*line;
564 /* Get the number of lines written by the user. */
565 *line += get_lines_number (rules[rule].guard);
566 }
567 }
568
569
570 /*---------------------------------------.
571 | Output the tokens definition to OOUT. |
572 `---------------------------------------*/
573
574 void
575 token_definitions_output (FILE *out, size_t *line)
576 {
577 int i;
578 for (i = 0; i < ntokens; ++i)
579 {
580 bucket *symbol = symbols[i];
581 int number = symbol->user_token_number;
582
583 if (number == SALIAS)
584 continue;
585 /* Skip error token. */
586 if (symbol->value == error_token_number)
587 continue;
588 if (symbol->tag[0] == '\'')
589 continue; /* skip literal character */
590 if (symbol->tag[0] == '\"')
591 {
592 /* use literal string only if given a symbol with an alias */
593 if (symbol->alias)
594 symbol = symbol->alias;
595 else
596 continue;
597 }
598
599 /* Don't #define nonliteral tokens whose names contain periods
600 or '$' (as does the default value of the EOF token). */
601 if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$'))
602 continue;
603
604 fprintf (out, "# define %s\t%d\n",
605 symbol->tag, number);
606 ++*line;
607 if (semantic_parser)
608 {
609 /* FIXME: This is probably wrong, and should be just as
610 above. --akim. */
611 fprintf (out, "# define T%s\t%d\n", symbol->tag, symbol->value);
612 ++*line;
613 }
614 }
615 }
616
617
618 static void
619 save_column (int symbol, int default_state)
620 {
621 int i;
622 short *sp;
623 short *sp1;
624 short *sp2;
625 int count;
626 int symno = symbol - ntokens + nstates;
627
628 short begin = goto_map[symbol];
629 short end = goto_map[symbol + 1];
630
631 count = 0;
632 for (i = begin; i < end; i++)
633 if (to_state[i] != default_state)
634 count++;
635
636 if (count == 0)
637 return;
638
639 froms[symno] = sp1 = sp = XCALLOC (short, count);
640 tos[symno] = sp2 = XCALLOC (short, count);
641
642 for (i = begin; i < end; i++)
643 if (to_state[i] != default_state)
644 {
645 *sp1++ = from_state[i];
646 *sp2++ = to_state[i];
647 }
648
649 tally[symno] = count;
650 width[symno] = sp1[-1] - sp[0] + 1;
651 }
652
653 static int
654 default_goto (int symbol)
655 {
656 int i;
657 int m = goto_map[symbol];
658 int n = goto_map[symbol + 1];
659 int default_state = -1;
660 int max = 0;
661
662 if (m == n)
663 return -1;
664
665 for (i = 0; i < nstates; i++)
666 state_count[i] = 0;
667
668 for (i = m; i < n; i++)
669 state_count[to_state[i]]++;
670
671 for (i = 0; i < nstates; i++)
672 if (state_count[i] > max)
673 {
674 max = state_count[i];
675 default_state = i;
676 }
677
678 return default_state;
679 }
680
681
682 /*-------------------------------------------------------------------.
683 | Figure out what to do after reducing with each rule, depending on |
684 | the saved state from before the beginning of parsing the data that |
685 | matched this rule. |
686 | |
687 | The YYDEFGOTO table is output now. The detailed info is saved for |
688 | putting into YYTABLE later. |
689 `-------------------------------------------------------------------*/
690
691 static void
692 goto_actions (void)
693 {
694 int i;
695 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
696
697 state_count = XCALLOC (short, nstates);
698 for (i = ntokens; i < nsyms; ++i)
699 {
700 int default_state = default_goto (i);
701 save_column (i, default_state);
702 yydefgoto[i - ntokens] = default_state;
703 }
704
705 output_table_data (&format_obstack, yydefgoto,
706 yydefgoto[0], 1, nsyms - ntokens);
707 muscle_insert ("defgoto", obstack_finish (&format_obstack));
708
709 XFREE (state_count);
710 XFREE (yydefgoto);
711 }
712
713
714 /* The next few functions decide how to pack the actions and gotos
715 information into yytable. */
716
717 static void
718 sort_actions (void)
719 {
720 int i;
721
722 order = XCALLOC (short, nvectors);
723 nentries = 0;
724
725 for (i = 0; i < nvectors; i++)
726 if (tally[i] > 0)
727 {
728 int k;
729 int t = tally[i];
730 int w = width[i];
731 int j = nentries - 1;
732
733 while (j >= 0 && (width[order[j]] < w))
734 j--;
735
736 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
737 j--;
738
739 for (k = nentries - 1; k > j; k--)
740 order[k + 1] = order[k];
741
742 order[j + 1] = i;
743 nentries++;
744 }
745 }
746
747
748 static int
749 matching_state (int vector)
750 {
751 int i = order[vector];
752 int t;
753 int w;
754 int prev;
755
756 if (i >= nstates)
757 return -1;
758
759 t = tally[i];
760 w = width[i];
761
762 for (prev = vector - 1; prev >= 0; prev--)
763 {
764 int j = order[prev];
765 int k;
766 int match = 1;
767
768 if (width[j] != w || tally[j] != t)
769 return -1;
770
771 for (k = 0; match && k < t; k++)
772 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
773 match = 0;
774
775 if (match)
776 return j;
777 }
778
779 return -1;
780 }
781
782
783 static int
784 pack_vector (int vector)
785 {
786 int i = order[vector];
787 int j;
788 int t = tally[i];
789 int loc = 0;
790 short *from = froms[i];
791 short *to = tos[i];
792
793 assert (t);
794
795 for (j = lowzero - from[0]; j < MAXTABLE; j++)
796 {
797 int k;
798 int ok = 1;
799
800 for (k = 0; ok && k < t; k++)
801 {
802 loc = j + from[k];
803 if (loc > MAXTABLE)
804 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
805
806 if (table[loc] != 0)
807 ok = 0;
808 }
809
810 for (k = 0; ok && k < vector; k++)
811 if (pos[k] == j)
812 ok = 0;
813
814 if (ok)
815 {
816 for (k = 0; k < t; k++)
817 {
818 loc = j + from[k];
819 table[loc] = to[k];
820 check[loc] = from[k];
821 }
822
823 while (table[lowzero] != 0)
824 lowzero++;
825
826 if (loc > high)
827 high = loc;
828
829 return j;
830 }
831 }
832 #define pack_vector_succeeded 0
833 assert (pack_vector_succeeded);
834 return 0;
835 }
836
837
838 static void
839 pack_table (void)
840 {
841 int i;
842 int place;
843 int state;
844
845 base = XCALLOC (short, nvectors);
846 pos = XCALLOC (short, nentries);
847 table = XCALLOC (short, MAXTABLE);
848 check = XCALLOC (short, MAXTABLE);
849
850 lowzero = 0;
851 high = 0;
852
853 for (i = 0; i < nvectors; i++)
854 base[i] = MINSHORT;
855
856 for (i = 0; i < MAXTABLE; i++)
857 check[i] = -1;
858
859 for (i = 0; i < nentries; i++)
860 {
861 state = matching_state (i);
862
863 if (state < 0)
864 place = pack_vector (i);
865 else
866 place = base[state];
867
868 pos[i] = place;
869 base[order[i]] = place;
870 }
871
872 for (i = 0; i < nvectors; i++)
873 {
874 XFREE (froms[i]);
875 XFREE (tos[i]);
876 }
877
878 XFREE (froms);
879 XFREE (tos);
880 XFREE (pos);
881 }
882
883 /* the following functions output yytable, yycheck
884 and the vectors whose elements index the portion starts */
885
886 static void
887 output_base (void)
888 {
889 /* Output pact. */
890 output_table_data (&format_obstack, base,
891 base[0], 1, nstates);
892 muscle_insert ("pact", obstack_finish (&format_obstack));
893
894 /* Output pgoto. */
895 output_table_data (&format_obstack, base,
896 base[nstates], nstates + 1, nvectors);
897 muscle_insert ("pgoto", obstack_finish (&format_obstack));
898
899 XFREE (base);
900 }
901
902
903 static void
904 output_table (void)
905 {
906 output_table_data (&format_obstack, table,
907 table[0], 1, high + 1);
908 muscle_insert ("table", obstack_finish (&format_obstack));
909 XFREE (table);
910 }
911
912
913 static void
914 output_check (void)
915 {
916 output_table_data (&format_obstack, check,
917 check[0], 1, high + 1);
918 muscle_insert ("check", obstack_finish (&format_obstack));
919 XFREE (check);
920 }
921
922 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
923 and yycheck. */
924
925 static void
926 output_actions (void)
927 {
928 int i;
929 nvectors = nstates + nvars;
930
931 froms = XCALLOC (short *, nvectors);
932 tos = XCALLOC (short *, nvectors);
933 tally = XCALLOC (short, nvectors);
934 width = XCALLOC (short, nvectors);
935
936 token_actions ();
937 XFREE (LA);
938 XFREE (LAruleno);
939
940 goto_actions ();
941 XFREE (goto_map + ntokens);
942 XFREE (from_state);
943 XFREE (to_state);
944
945 sort_actions ();
946 pack_table ();
947
948 output_base ();
949 output_table ();
950
951 output_check ();
952
953 for (i = 0; i < nstates; ++i)
954 {
955 free (states[i]->shifts);
956 XFREE (states[i]->reductions);
957 free (states[i]->errs);
958 free (states[i]);
959 }
960 XFREE (states);
961 }
962
963 \f
964 /*------------------------------------------------------------.
965 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
966 | and do the muscle substitution. |
967 `------------------------------------------------------------*/
968
969 static void
970 output_parser (const char *skel_filename, FILE *out)
971 {
972 int c;
973 FILE *fskel;
974 size_t output_line;
975 size_t skeleton_line;
976
977 fskel = xfopen (skel_filename, "r");
978
979 /* New output code. */
980 output_line = 1;
981 skeleton_line = 1;
982 c = getc (fskel);
983 while (c != EOF)
984 {
985 if (c != '%')
986 {
987 if (c == '\n')
988 {
989 ++output_line;
990 ++skeleton_line;
991 }
992 putc (c, out);
993 c = getc (fskel);
994 }
995 else if ((c = getc (fskel)) == '%')
996 {
997 /* Read the muscle. */
998 const char *muscle_key = 0;
999 const char *muscle_value = 0;
1000
1001 while (isalnum (c = getc (fskel)) || c == '-')
1002 obstack_1grow (&muscle_obstack, c);
1003 obstack_1grow (&muscle_obstack, 0);
1004
1005 /* Output the right value, or see if it's something special. */
1006 muscle_key = obstack_finish (&muscle_obstack);
1007 muscle_value = muscle_find (muscle_key);
1008 if (!strcmp (muscle_key, "actions"))
1009 actions_output (out, &output_line);
1010 else if (!strcmp (muscle_key, "guards"))
1011 guards_output (out, &output_line);
1012 else if (!strcmp (muscle_key, "line"))
1013 fprintf (out, "%d", output_line);
1014 else if (!strcmp (muscle_key, "tokendef"))
1015 token_definitions_output (out, &output_line);
1016 else if (!strcmp (muscle_key, "skeleton-line"))
1017 fprintf (out, "%d", skeleton_line);
1018 else if (muscle_value)
1019 {
1020 fputs (muscle_value, out);
1021 output_line += get_lines_number (muscle_value);
1022 }
1023 else
1024 {
1025 fputs ("%%", out);
1026 fputs (muscle_key, out);
1027 }
1028 }
1029 else
1030 putc ('%', out);
1031 }
1032
1033 /* End. */
1034 xfclose (fskel);
1035 }
1036
1037 /*----------------------------------------.
1038 | Prepare the master parser to be output |
1039 `----------------------------------------*/
1040
1041 static void
1042 output_master_parser (void)
1043 {
1044 FILE *parser = xfopen (parser_file_name, "w");
1045
1046 /* FIXME: Remove the two following lines. */
1047 printf ("Test: %s\n", infile);
1048 printf ("Test: %s\n", parser_file_name);
1049
1050 if (!skeleton)
1051 {
1052 if (semantic_parser)
1053 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1054 else
1055 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1056 }
1057 muscle_insert ("skeleton", skeleton);
1058 muscle_insert ("parser-file-name", parser_file_name);
1059
1060 output_parser (skeleton, parser);
1061 xfclose (parser);
1062 }
1063
1064 /* Call the skeleton parser. */
1065
1066 static
1067 void
1068 output_skeleton ()
1069 {
1070 /* Find the right skeleton file. */
1071 if (!skeleton)
1072 {
1073 if (semantic_parser)
1074 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1075 else
1076 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1077 }
1078
1079 /* Parse the skeleton file and output the needed parsers. */
1080 muscle_insert ("skeleton", skeleton);
1081 process_skeleton (infile, skeleton);
1082 }
1083
1084 static void
1085 prepare (void)
1086 {
1087 MUSCLE_INSERT_INT ("last", high);
1088 MUSCLE_INSERT_INT ("flag", MINSHORT);
1089 MUSCLE_INSERT_INT ("pure", pure_parser);
1090 MUSCLE_INSERT_INT ("nsym", nsyms);
1091 MUSCLE_INSERT_INT ("debug", debug_flag);
1092 MUSCLE_INSERT_INT ("final", final_state);
1093 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1094 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
1095 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
1096
1097 MUSCLE_INSERT_INT ("nnts", nvars);
1098 MUSCLE_INSERT_INT ("nrules", nrules);
1099 MUSCLE_INSERT_INT ("nstates", nstates);
1100 MUSCLE_INSERT_INT ("ntokens", ntokens);
1101
1102 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
1103 }
1104
1105 /*-------------------------.
1106 | Output the header file. |
1107 `-------------------------*/
1108
1109 static void
1110 header_output (void)
1111 {
1112 size_t dummy_line;
1113 FILE *out = xfopen (spec_defines_file, "w");
1114 char *macro_name = compute_header_macro ();
1115
1116 fprintf (out, "#ifndef %s\n", macro_name);
1117 fprintf (out, "# define %s\n\n", macro_name);
1118
1119 token_definitions_output (out, &dummy_line);
1120 fprintf (out, "\
1121 #ifndef YYSTYPE\n\
1122 typedef %s
1123 yystype;\n\
1124 # define YYSTYPE yystype\n\
1125 #endif\n",
1126 muscle_find ("stype"));
1127
1128 if (!pure_parser)
1129 fprintf (out, "\nextern YYSTYPE %slval;\n",
1130 spec_name_prefix ? spec_name_prefix : "yy");
1131
1132 if (locations_flag)
1133 {
1134 fputs ("\n\n", out);
1135 fprintf (out, "\
1136 #ifndef YYLTYPE\n\
1137 typedef struct yyltype\n\
1138 {\n\
1139 int first_line;\n\
1140 int first_column;\n\
1141 int last_line;\n\
1142 int last_column;\n\
1143 } yyltype;\n\
1144 # define YYLTYPE yyltype\n\
1145 #endif\n");
1146 if (!pure_parser)
1147 fprintf (out, "\nextern YYLTYPE %slloc;\n",
1148 spec_name_prefix ? spec_name_prefix : "yy");
1149 }
1150
1151 if (semantic_parser)
1152 {
1153 int i;
1154
1155 for (i = ntokens; i < nsyms; i++)
1156 /* don't make these for dummy nonterminals made by gensym. */
1157 if (*symbols[i]->tag != '@')
1158 fprintf (out, "# define NT%s\t%d\n", symbols[i]->tag, i);
1159 }
1160
1161 fprintf (out, "\n#endif /* not %s */\n", macro_name);
1162 free (macro_name);
1163 xfclose (out);
1164 }
1165
1166
1167 /*----------------------------------------------------------.
1168 | Output the parsing tables and the parser code to ftable. |
1169 `----------------------------------------------------------*/
1170
1171 void
1172 output (void)
1173 {
1174 obstack_init (&format_obstack);
1175
1176 output_token_translations ();
1177 output_gram ();
1178
1179 XFREE (ritem);
1180 if (semantic_parser)
1181 output_stos ();
1182 output_rule_data ();
1183 output_actions ();
1184
1185 prepare ();
1186 /* Copy definitions in directive. */
1187 obstack_1grow (&attrs_obstack, 0);
1188 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1189
1190 /* Process the selected skeleton file. */
1191 output_skeleton ();
1192
1193 /* Output the parser. */
1194 #if 0
1195 output_master_parser ();
1196 #endif
1197 /* Output the header if needed. */
1198 if (defines_flag)
1199 header_output ();
1200
1201 free (rules + 1);
1202 obstack_free (&muscle_obstack, NULL);
1203 obstack_free (&format_obstack, NULL);
1204 obstack_free (&action_obstack, NULL);
1205 obstack_free (&attrs_obstack, NULL);
1206 }