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