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