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