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