]> git.saurik.com Git - bison.git/blob - src/output.c
* src/lex.c, src/lex.h (xgetc): No longer static.
[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
290 /*------------------------------------------------------------------.
291 | Decide what to do for each type of token if seen as the lookahead |
292 | token in specified state. The value returned is used as the |
293 | default action (yydefact) for the state. In addition, actrow is |
294 | filled with what to do for each kind of token, index by symbol |
295 | number, with zero meaning do the default action. The value |
296 | MINSHORT, a very negative number, means this situation is an |
297 | error. The parser recognizes this value specially. |
298 | |
299 | This is where conflicts are resolved. The loop over lookahead |
300 | rules considered lower-numbered rules last, and the last rule |
301 | considered that likes a token gets to handle it. |
302 `------------------------------------------------------------------*/
303
304 static int
305 action_row (int state)
306 {
307 int i;
308 int j;
309 int k;
310 int m = 0;
311 int n = 0;
312 int default_rule;
313 int nreds;
314 int rule;
315 int shift_state;
316 int symbol;
317 reductions *redp;
318 shifts *shiftp;
319 errs *errp;
320 int nodefault = 0; /* set nonzero to inhibit having any default reduction */
321
322 for (i = 0; i < ntokens; i++)
323 actrow[i] = 0;
324
325 default_rule = 0;
326 nreds = 0;
327 redp = state_table[state]->reductions;
328
329 if (redp)
330 {
331 nreds = redp->nreds;
332
333 if (nreds >= 1)
334 {
335 /* loop over all the rules available here which require
336 lookahead */
337 m = state_table[state]->lookaheads;
338 n = state_table[state + 1]->lookaheads;
339
340 for (i = n - 1; i >= m; i--)
341 /* and find each token which the rule finds acceptable
342 to come next */
343 for (j = 0; j < ntokens; j++)
344 /* and record this rule as the rule to use if that
345 token follows. */
346 if (BITISSET (LA (i), j))
347 actrow[j] = -LAruleno[i];
348 }
349 }
350
351 /* Now see which tokens are allowed for shifts in this state. For
352 them, record the shift as the thing to do. So shift is preferred
353 to reduce. */
354 shiftp = state_table[state]->shifts;
355 for (i = 0; i < shiftp->nshifts; i++)
356 {
357 shift_state = shiftp->shifts[i];
358 if (!shift_state)
359 continue;
360
361 symbol = state_table[shift_state]->accessing_symbol;
362
363 if (ISVAR (symbol))
364 break;
365
366 actrow[symbol] = shift_state;
367
368 /* Do not use any default reduction if there is a shift for
369 error */
370 if (symbol == error_token_number)
371 nodefault = 1;
372 }
373
374 /* See which tokens are an explicit error in this state (due to
375 %nonassoc). For them, record MINSHORT as the action. */
376 errp = state_table[state]->errs;
377
378 if (errp)
379 {
380 k = errp->nerrs;
381
382 for (i = 0; i < k; i++)
383 {
384 symbol = errp->errs[i];
385 actrow[symbol] = MINSHORT;
386 }
387 }
388
389 /* Now find the most common reduction and make it the default action
390 for this state. */
391
392 if (nreds >= 1 && !nodefault)
393 {
394 if (state_table[state]->consistent)
395 default_rule = redp->rules[0];
396 else
397 {
398 int max = 0;
399 for (i = m; i < n; i++)
400 {
401 int count = 0;
402 rule = -LAruleno[i];
403
404 for (j = 0; j < ntokens; j++)
405 {
406 if (actrow[j] == rule)
407 count++;
408 }
409
410 if (count > max)
411 {
412 max = count;
413 default_rule = rule;
414 }
415 }
416
417 /* actions which match the default are replaced with zero,
418 which means "use the default" */
419
420 if (max > 0)
421 {
422 for (j = 0; j < ntokens; j++)
423 {
424 if (actrow[j] == default_rule)
425 actrow[j] = 0;
426 }
427
428 default_rule = -default_rule;
429 }
430 }
431 }
432
433 /* If have no default rule, the default is an error.
434 So replace any action which says "error" with "use default". */
435
436 if (default_rule == 0)
437 for (j = 0; j < ntokens; j++)
438 {
439 if (actrow[j] == MINSHORT)
440 actrow[j] = 0;
441 }
442
443 return default_rule;
444 }
445
446
447 static void
448 save_row (int state)
449 {
450 int i;
451 int count;
452 short *sp;
453 short *sp1;
454 short *sp2;
455
456 count = 0;
457 for (i = 0; i < ntokens; i++)
458 {
459 if (actrow[i] != 0)
460 count++;
461 }
462
463 if (count == 0)
464 return;
465
466 froms[state] = sp1 = sp = XCALLOC (short, count);
467 tos[state] = sp2 = XCALLOC (short, count);
468
469 for (i = 0; i < ntokens; i++)
470 {
471 if (actrow[i] != 0)
472 {
473 *sp1++ = i;
474 *sp2++ = actrow[i];
475 }
476 }
477
478 tally[state] = count;
479 width[state] = sp1[-1] - sp[0] + 1;
480 }
481
482
483 /*------------------------------------------------------------------.
484 | Figure out the actions for the specified state, indexed by |
485 | lookahead token type. |
486 | |
487 | The YYDEFACT table is output now. The detailed info is saved for |
488 | putting into YYTABLE later. |
489 `------------------------------------------------------------------*/
490
491 static void
492 token_actions (void)
493 {
494 int i;
495 short *yydefact = XCALLOC (short, nstates);
496
497 actrow = XCALLOC (short, ntokens);
498 for (i = 0; i < nstates; ++i)
499 {
500 yydefact[i] = action_row (i);
501 save_row (i);
502 }
503
504 output_table_data (&output_obstack, yydefact,
505 yydefact[0], 1, nstates);
506 muscle_insert ("defact", obstack_finish (&output_obstack));
507
508 XFREE (actrow);
509 XFREE (yydefact);
510 }
511
512
513 /*-----------------------------.
514 | Output the actions to OOUT. |
515 `-----------------------------*/
516
517 static void
518 actions_output (FILE *out)
519 {
520 int rule;
521 for (rule = 1; rule < nrules + 1; ++rule)
522 if (rule_table[rule].action)
523 {
524 fprintf (out, " case %d:\n", rule);
525
526 if (!no_lines_flag)
527 fprintf (out, muscle_find ("linef"),
528 rule_table[rule].action_line,
529 quotearg_style (c_quoting_style,
530 muscle_find ("filename")));
531 /* As a Bison extension, add the ending semicolon. Since some
532 Yacc don't do that, help people using bison as a Yacc
533 finding their missing semicolons. */
534 fprintf (out, "{ %s%s }\n break;\n\n",
535 rule_table[rule].action,
536 yacc_flag ? ";" : "");
537 }
538 }
539
540
541 static void
542 save_column (int symbol, int default_state)
543 {
544 int i;
545 short *sp;
546 short *sp1;
547 short *sp2;
548 int count;
549 int symno;
550
551 short begin = goto_map[symbol];
552 short end = goto_map[symbol + 1];
553
554 count = 0;
555 for (i = begin; i < end; i++)
556 {
557 if (to_state[i] != default_state)
558 count++;
559 }
560
561 if (count == 0)
562 return;
563
564 symno = symbol - ntokens + nstates;
565
566 froms[symno] = sp1 = sp = XCALLOC (short, count);
567 tos[symno] = sp2 = XCALLOC (short, count);
568
569 for (i = begin; i < end; i++)
570 {
571 if (to_state[i] != default_state)
572 {
573 *sp1++ = from_state[i];
574 *sp2++ = to_state[i];
575 }
576 }
577
578 tally[symno] = count;
579 width[symno] = sp1[-1] - sp[0] + 1;
580 }
581
582 static int
583 default_goto (int symbol)
584 {
585 int i;
586 int m;
587 int n;
588 int default_state;
589 int max;
590
591 m = goto_map[symbol];
592 n = goto_map[symbol + 1];
593
594 if (m == n)
595 return -1;
596
597 for (i = 0; i < nstates; i++)
598 state_count[i] = 0;
599
600 for (i = m; i < n; i++)
601 state_count[to_state[i]]++;
602
603 max = 0;
604 default_state = -1;
605
606 for (i = 0; i < nstates; i++)
607 {
608 if (state_count[i] > max)
609 {
610 max = state_count[i];
611 default_state = i;
612 }
613 }
614
615 return default_state;
616 }
617
618
619 /*-------------------------------------------------------------------.
620 | Figure out what to do after reducing with each rule, depending on |
621 | the saved state from before the beginning of parsing the data that |
622 | matched this rule. |
623 | |
624 | The YYDEFGOTO table is output now. The detailed info is saved for |
625 | putting into YYTABLE later. |
626 `-------------------------------------------------------------------*/
627
628 static void
629 goto_actions (void)
630 {
631 int i;
632 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
633
634 state_count = XCALLOC (short, nstates);
635 for (i = ntokens; i < nsyms; ++i)
636 {
637 int default_state = default_goto (i);
638 save_column (i, default_state);
639 yydefgoto[i - ntokens] = default_state;
640 }
641
642 output_table_data (&output_obstack, yydefgoto,
643 yydefgoto[0], 1, nsyms - ntokens);
644 muscle_insert ("defgoto", obstack_finish (&output_obstack));
645
646 XFREE (state_count);
647 XFREE (yydefgoto);
648 }
649
650
651 /* The next few functions decide how to pack the actions and gotos
652 information into yytable. */
653
654 static void
655 sort_actions (void)
656 {
657 int i;
658 int j;
659 int k;
660 int t;
661 int w;
662
663 order = XCALLOC (short, nvectors);
664 nentries = 0;
665
666 for (i = 0; i < nvectors; i++)
667 {
668 if (tally[i] > 0)
669 {
670 t = tally[i];
671 w = width[i];
672 j = nentries - 1;
673
674 while (j >= 0 && (width[order[j]] < w))
675 j--;
676
677 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
678 j--;
679
680 for (k = nentries - 1; k > j; k--)
681 order[k + 1] = order[k];
682
683 order[j + 1] = i;
684 nentries++;
685 }
686 }
687 }
688
689
690 static int
691 matching_state (int vector)
692 {
693 int i;
694 int j;
695 int k;
696 int t;
697 int w;
698 int match;
699 int prev;
700
701 i = order[vector];
702 if (i >= nstates)
703 return -1;
704
705 t = tally[i];
706 w = width[i];
707
708 for (prev = vector - 1; prev >= 0; prev--)
709 {
710 j = order[prev];
711 if (width[j] != w || tally[j] != t)
712 return -1;
713
714 match = 1;
715 for (k = 0; match && k < t; k++)
716 {
717 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
718 match = 0;
719 }
720
721 if (match)
722 return j;
723 }
724
725 return -1;
726 }
727
728
729 static int
730 pack_vector (int vector)
731 {
732 int i;
733 int j;
734 int k;
735 int t;
736 int loc = 0;
737 int ok;
738 short *from;
739 short *to;
740
741 i = order[vector];
742 t = tally[i];
743
744 assert (t);
745
746 from = froms[i];
747 to = tos[i];
748
749 for (j = lowzero - from[0]; j < MAXTABLE; j++)
750 {
751 ok = 1;
752
753 for (k = 0; ok && k < t; k++)
754 {
755 loc = j + from[k];
756 if (loc > MAXTABLE)
757 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
758
759 if (table[loc] != 0)
760 ok = 0;
761 }
762
763 for (k = 0; ok && k < vector; k++)
764 {
765 if (pos[k] == j)
766 ok = 0;
767 }
768
769 if (ok)
770 {
771 for (k = 0; k < t; k++)
772 {
773 loc = j + from[k];
774 table[loc] = to[k];
775 check[loc] = from[k];
776 }
777
778 while (table[lowzero] != 0)
779 lowzero++;
780
781 if (loc > high)
782 high = loc;
783
784 return j;
785 }
786 }
787
788 assert (!"pack_vector");
789 return 0;
790 }
791
792
793 static void
794 pack_table (void)
795 {
796 int i;
797 int place;
798 int state;
799
800 base = XCALLOC (short, nvectors);
801 pos = XCALLOC (short, nentries);
802 table = XCALLOC (short, MAXTABLE);
803 check = XCALLOC (short, MAXTABLE);
804
805 lowzero = 0;
806 high = 0;
807
808 for (i = 0; i < nvectors; i++)
809 base[i] = MINSHORT;
810
811 for (i = 0; i < MAXTABLE; i++)
812 check[i] = -1;
813
814 for (i = 0; i < nentries; i++)
815 {
816 state = matching_state (i);
817
818 if (state < 0)
819 place = pack_vector (i);
820 else
821 place = base[state];
822
823 pos[i] = place;
824 base[order[i]] = place;
825 }
826
827 for (i = 0; i < nvectors; i++)
828 {
829 if (froms[i])
830 XFREE (froms[i]);
831 if (tos[i])
832 XFREE (tos[i]);
833 }
834
835 XFREE (froms);
836 XFREE (tos);
837 XFREE (pos);
838 }
839
840 /* the following functions output yytable, yycheck
841 and the vectors whose elements index the portion starts */
842
843 static void
844 output_base (void)
845 {
846 /* Output pact. */
847 output_table_data (&output_obstack, base,
848 base[0], 1, nstates);
849 muscle_insert ("pact", obstack_finish (&output_obstack));
850
851 /* Output pgoto. */
852 output_table_data (&output_obstack, base,
853 base[nstates], nstates + 1, nvectors);
854 muscle_insert ("pgoto", obstack_finish (&output_obstack));
855
856 XFREE (base);
857 }
858
859
860 static void
861 output_table (void)
862 {
863 output_table_data (&output_obstack, table,
864 table[0], 1, high + 1);
865 muscle_insert ("table", obstack_finish (&output_obstack));
866 XFREE (table);
867 }
868
869
870 static void
871 output_check (void)
872 {
873 output_table_data (&output_obstack, check,
874 check[0], 1, high + 1);
875 muscle_insert ("check", obstack_finish (&output_obstack));
876 XFREE (check);
877 }
878
879 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
880 and yycheck. */
881
882 static void
883 output_actions (void)
884 {
885 int i;
886 nvectors = nstates + nvars;
887
888 froms = XCALLOC (short *, nvectors);
889 tos = XCALLOC (short *, nvectors);
890 tally = XCALLOC (short, nvectors);
891 width = XCALLOC (short, nvectors);
892
893 token_actions ();
894 XFREE (LA);
895 XFREE (LAruleno);
896
897 goto_actions ();
898 XFREE (goto_map + ntokens);
899 XFREE (from_state);
900 XFREE (to_state);
901
902 sort_actions ();
903 pack_table ();
904
905 output_base ();
906 output_table ();
907
908 output_check ();
909
910 for (i = 0; i < nstates; ++i)
911 {
912 XFREE (state_table[i]->shifts);
913 XFREE (state_table[i]->reductions);
914 XFREE (state_table[i]->errs);
915 free (state_table[i]);
916 }
917 XFREE (state_table);
918 }
919
920 \f
921 /*------------------------------------------------------------.
922 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
923 | and do the muscle substitution. |
924 `------------------------------------------------------------*/
925
926 static void
927 output_parser (const char *skel_filename, FILE *out)
928 {
929 int c;
930 FILE *fskel;
931 size_t line;
932
933 fskel = xfopen (skel_filename, "r");
934
935 /* New output code. */
936 line = 1;
937 c = getc (fskel);
938 while (c != EOF)
939 {
940 if (c != '%')
941 {
942 if (c == '\n')
943 ++line;
944 putc (c, out);
945 c = getc (fskel);
946 }
947 else if ((c = getc (fskel)) == '%')
948 {
949 /* Read the muscle. */
950 const char *muscle_key = 0;
951 const char *muscle_value = 0;
952
953 while (isalnum (c = getc (fskel)) || c == '-')
954 obstack_1grow (&muscle_obstack, c);
955 obstack_1grow (&muscle_obstack, 0);
956
957 /* Output the right value, or see if it's something special. */
958 muscle_key = obstack_finish (&muscle_obstack);
959 muscle_value = muscle_find (muscle_key);
960 if (!strcmp (muscle_key, "actions"))
961 actions_output (out);
962 else if (!strcmp (muscle_key, "line"))
963 fprintf (out, "%d", line + 1);
964 else if (muscle_value)
965 fputs (muscle_value, out);
966 else
967 {
968 fputs ("%%", out);
969 fputs (muscle_key, out);
970 }
971 }
972 else
973 putc ('%', out);
974 }
975
976 /* End. */
977 xfclose (fskel);
978 }
979
980 /*----------------------------------------.
981 | Prepare the master parser to be output |
982 `----------------------------------------*/
983
984 static void
985 output_master_parser (void)
986 {
987 FILE *parser = xfopen (parser_file_name, "w");
988 if (!skeleton)
989 {
990 if (semantic_parser)
991 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
992 else
993 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
994 }
995 muscle_insert ("skeleton", skeleton);
996
997 output_parser (skeleton, parser);
998 xfclose (parser);
999 }
1000
1001
1002 /* FIXME. */
1003
1004 #define MUSCLE_INSERT_INT(Key, Value) \
1005 { \
1006 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1007 obstack_1grow (&muscle_obstack, 0); \
1008 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1009 }
1010
1011 #define MUSCLE_INSERT_STRING(Key, Value) \
1012 { \
1013 obstack_sgrow (&muscle_obstack, Value); \
1014 obstack_1grow (&muscle_obstack, 0); \
1015 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1016 }
1017
1018 #define MUSCLE_INSERT_PREFIX(Key, Value) \
1019 { \
1020 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1021 obstack_1grow (&muscle_obstack, 0); \
1022 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1023 }
1024
1025 static void
1026 prepare (void)
1027 {
1028 MUSCLE_INSERT_INT ("last", high);
1029 MUSCLE_INSERT_INT ("flag", MINSHORT);
1030 MUSCLE_INSERT_INT ("pure", pure_parser);
1031 MUSCLE_INSERT_INT ("nsym", nsyms);
1032 MUSCLE_INSERT_INT ("debug", debug_flag);
1033 MUSCLE_INSERT_INT ("final", final_state);
1034 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1035 MUSCLE_INSERT_INT ("ntbase", ntokens);
1036 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
1037 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
1038
1039 MUSCLE_INSERT_INT ("nnts", nvars);
1040 MUSCLE_INSERT_INT ("nrules", nrules);
1041 MUSCLE_INSERT_INT ("nstates", nstates);
1042 MUSCLE_INSERT_INT ("ntokens", ntokens);
1043
1044 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
1045 }
1046
1047 /*----------------------------------------------------------.
1048 | Output the parsing tables and the parser code to ftable. |
1049 `----------------------------------------------------------*/
1050
1051 void
1052 output (void)
1053 {
1054 obstack_init (&output_obstack);
1055
1056 output_token_translations ();
1057 output_gram ();
1058
1059 XFREE (ritem);
1060 if (semantic_parser)
1061 output_stos ();
1062 output_rule_data ();
1063 XFREE (user_toknums);
1064 output_actions ();
1065
1066 prepare ();
1067 /* Copy definitions in directive. */
1068 obstack_1grow (&attrs_obstack, 0);
1069 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1070
1071 output_master_parser ();
1072
1073 free (rule_table + 1);
1074 obstack_free (&muscle_obstack, 0);
1075 obstack_free (&output_obstack, 0);
1076 obstack_free (&action_obstack, 0);
1077 }