]> git.saurik.com Git - bison.git/blame_incremental - src/output.c
Add src/state.c to the repo.
[bison.git] / src / output.c
... / ...
CommitLineData
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
107extern void berror PARAMS((const char *));
108
109static int nvectors;
110static int nentries;
111static short **froms = NULL;
112static short **tos = NULL;
113static short *tally = NULL;
114static short *width = NULL;
115static short *actrow = NULL;
116static short *state_count = NULL;
117static short *order = NULL;
118static short *base = NULL;
119static short *pos = NULL;
120static short *table = NULL;
121static short *check = NULL;
122static int lowzero;
123static int high;
124
125struct obstack muscle_obstack;
126struct obstack output_obstack;
127
128int error_verbose = 0;
129
130/* FIXME. */
131
132static inline void
133output_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
159static void
160output_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
169static void
170output_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
210static void
211output_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
223static void
224output_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
336static int
337action_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 /* Now see which tokens are allowed for shifts in this state. For
403 them, record the shift as the thing to do. So shift is preferred
404 to reduce. */
405 shiftp = state_table[state].shift_table;
406
407 for (i = 0; i < shiftp->nshifts; i++)
408 {
409 shift_state = shiftp->shifts[i];
410 if (!shift_state)
411 continue;
412
413 symbol = state_table[shift_state].accessing_symbol;
414
415 if (ISVAR (symbol))
416 break;
417
418 actrow[symbol] = shift_state;
419
420 /* Do not use any default reduction if there is a shift for
421 error */
422 if (symbol == error_token_number)
423 nodefault = 1;
424 }
425
426 /* See which tokens are an explicit error in this state (due to
427 %nonassoc). For them, record MINSHORT as the action. */
428 errp = err_table[state];
429
430 if (errp)
431 {
432 k = errp->nerrs;
433
434 for (i = 0; i < k; i++)
435 {
436 symbol = errp->errs[i];
437 actrow[symbol] = MINSHORT;
438 }
439 }
440
441 /* Now find the most common reduction and make it the default action
442 for this state. */
443
444 if (nreds >= 1 && !nodefault)
445 {
446 if (state_table[state].consistent)
447 default_rule = redp->rules[0];
448 else
449 {
450 max = 0;
451 for (i = m; i < n; i++)
452 {
453 count = 0;
454 rule = -LAruleno[i];
455
456 for (j = 0; j < ntokens; j++)
457 {
458 if (actrow[j] == rule)
459 count++;
460 }
461
462 if (count > max)
463 {
464 max = count;
465 default_rule = rule;
466 }
467 }
468
469 /* actions which match the default are replaced with zero,
470 which means "use the default" */
471
472 if (max > 0)
473 {
474 for (j = 0; j < ntokens; j++)
475 {
476 if (actrow[j] == default_rule)
477 actrow[j] = 0;
478 }
479
480 default_rule = -default_rule;
481 }
482 }
483 }
484
485 /* If have no default rule, the default is an error.
486 So replace any action which says "error" with "use default". */
487
488 if (default_rule == 0)
489 for (j = 0; j < ntokens; j++)
490 {
491 if (actrow[j] == MINSHORT)
492 actrow[j] = 0;
493 }
494
495 return default_rule;
496}
497
498
499static void
500save_row (int state)
501{
502 int i;
503 int count;
504 short *sp;
505 short *sp1;
506 short *sp2;
507
508 count = 0;
509 for (i = 0; i < ntokens; i++)
510 {
511 if (actrow[i] != 0)
512 count++;
513 }
514
515 if (count == 0)
516 return;
517
518 froms[state] = sp1 = sp = XCALLOC (short, count);
519 tos[state] = sp2 = XCALLOC (short, count);
520
521 for (i = 0; i < ntokens; i++)
522 {
523 if (actrow[i] != 0)
524 {
525 *sp1++ = i;
526 *sp2++ = actrow[i];
527 }
528 }
529
530 tally[state] = count;
531 width[state] = sp1[-1] - sp[0] + 1;
532}
533
534
535/*------------------------------------------------------------------.
536| Figure out the actions for the specified state, indexed by |
537| lookahead token type. |
538| |
539| The YYDEFACT table is output now. The detailed info is saved for |
540| putting into YYTABLE later. |
541`------------------------------------------------------------------*/
542
543static void
544token_actions (void)
545{
546 int i;
547 short *yydefact = XCALLOC (short, nstates);
548
549 actrow = XCALLOC (short, ntokens);
550 for (i = 0; i < nstates; ++i)
551 {
552 yydefact[i] = action_row (i);
553 save_row (i);
554 }
555
556 output_table_data (&output_obstack, yydefact,
557 yydefact[0], 1, nstates);
558 muscle_insert ("defact", obstack_finish (&output_obstack));
559
560 XFREE (actrow);
561 XFREE (yydefact);
562}
563
564
565static void
566save_column (int symbol, int default_state)
567{
568 int i;
569 short *sp;
570 short *sp1;
571 short *sp2;
572 int count;
573 int symno;
574
575 short begin = goto_map[symbol];
576 short end = goto_map[symbol + 1];
577
578 count = 0;
579 for (i = begin; i < end; i++)
580 {
581 if (to_state[i] != default_state)
582 count++;
583 }
584
585 if (count == 0)
586 return;
587
588 symno = symbol - ntokens + nstates;
589
590 froms[symno] = sp1 = sp = XCALLOC (short, count);
591 tos[symno] = sp2 = XCALLOC (short, count);
592
593 for (i = begin; i < end; i++)
594 {
595 if (to_state[i] != default_state)
596 {
597 *sp1++ = from_state[i];
598 *sp2++ = to_state[i];
599 }
600 }
601
602 tally[symno] = count;
603 width[symno] = sp1[-1] - sp[0] + 1;
604}
605
606static int
607default_goto (int symbol)
608{
609 int i;
610 int m;
611 int n;
612 int default_state;
613 int max;
614
615 m = goto_map[symbol];
616 n = goto_map[symbol + 1];
617
618 if (m == n)
619 return -1;
620
621 for (i = 0; i < nstates; i++)
622 state_count[i] = 0;
623
624 for (i = m; i < n; i++)
625 state_count[to_state[i]]++;
626
627 max = 0;
628 default_state = -1;
629
630 for (i = 0; i < nstates; i++)
631 {
632 if (state_count[i] > max)
633 {
634 max = state_count[i];
635 default_state = i;
636 }
637 }
638
639 return default_state;
640}
641
642
643/*-------------------------------------------------------------------.
644| Figure out what to do after reducing with each rule, depending on |
645| the saved state from before the beginning of parsing the data that |
646| matched this rule. |
647| |
648| The YYDEFGOTO table is output now. The detailed info is saved for |
649| putting into YYTABLE later. |
650`-------------------------------------------------------------------*/
651
652static void
653goto_actions (void)
654{
655 int i;
656 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
657
658 state_count = XCALLOC (short, nstates);
659 for (i = ntokens; i < nsyms; ++i)
660 {
661 int default_state = default_goto (i);
662 save_column (i, default_state);
663 yydefgoto[i - ntokens] = default_state;
664 }
665
666 output_table_data (&output_obstack, yydefgoto,
667 yydefgoto[0], 1, nsyms - ntokens);
668 muscle_insert ("defgoto", obstack_finish (&output_obstack));
669
670 XFREE (state_count);
671 XFREE (yydefgoto);
672}
673
674
675/* The next few functions decide how to pack the actions and gotos
676 information into yytable. */
677
678static void
679sort_actions (void)
680{
681 int i;
682 int j;
683 int k;
684 int t;
685 int w;
686
687 order = XCALLOC (short, nvectors);
688 nentries = 0;
689
690 for (i = 0; i < nvectors; i++)
691 {
692 if (tally[i] > 0)
693 {
694 t = tally[i];
695 w = width[i];
696 j = nentries - 1;
697
698 while (j >= 0 && (width[order[j]] < w))
699 j--;
700
701 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
702 j--;
703
704 for (k = nentries - 1; k > j; k--)
705 order[k + 1] = order[k];
706
707 order[j + 1] = i;
708 nentries++;
709 }
710 }
711}
712
713
714static int
715matching_state (int vector)
716{
717 int i;
718 int j;
719 int k;
720 int t;
721 int w;
722 int match;
723 int prev;
724
725 i = order[vector];
726 if (i >= nstates)
727 return -1;
728
729 t = tally[i];
730 w = width[i];
731
732 for (prev = vector - 1; prev >= 0; prev--)
733 {
734 j = order[prev];
735 if (width[j] != w || tally[j] != t)
736 return -1;
737
738 match = 1;
739 for (k = 0; match && k < t; k++)
740 {
741 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
742 match = 0;
743 }
744
745 if (match)
746 return j;
747 }
748
749 return -1;
750}
751
752
753static int
754pack_vector (int vector)
755{
756 int i;
757 int j;
758 int k;
759 int t;
760 int loc = 0;
761 int ok;
762 short *from;
763 short *to;
764
765 i = order[vector];
766 t = tally[i];
767
768 assert (t);
769
770 from = froms[i];
771 to = tos[i];
772
773 for (j = lowzero - from[0]; j < MAXTABLE; j++)
774 {
775 ok = 1;
776
777 for (k = 0; ok && k < t; k++)
778 {
779 loc = j + from[k];
780 if (loc > MAXTABLE)
781 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
782
783 if (table[loc] != 0)
784 ok = 0;
785 }
786
787 for (k = 0; ok && k < vector; k++)
788 {
789 if (pos[k] == j)
790 ok = 0;
791 }
792
793 if (ok)
794 {
795 for (k = 0; k < t; k++)
796 {
797 loc = j + from[k];
798 table[loc] = to[k];
799 check[loc] = from[k];
800 }
801
802 while (table[lowzero] != 0)
803 lowzero++;
804
805 if (loc > high)
806 high = loc;
807
808 return j;
809 }
810 }
811
812 berror ("pack_vector");
813 return 0; /* JF keep lint happy */
814}
815
816
817static void
818pack_table (void)
819{
820 int i;
821 int place;
822 int state;
823
824 base = XCALLOC (short, nvectors);
825 pos = XCALLOC (short, nentries);
826 table = XCALLOC (short, MAXTABLE);
827 check = XCALLOC (short, MAXTABLE);
828
829 lowzero = 0;
830 high = 0;
831
832 for (i = 0; i < nvectors; i++)
833 base[i] = MINSHORT;
834
835 for (i = 0; i < MAXTABLE; i++)
836 check[i] = -1;
837
838 for (i = 0; i < nentries; i++)
839 {
840 state = matching_state (i);
841
842 if (state < 0)
843 place = pack_vector (i);
844 else
845 place = base[state];
846
847 pos[i] = place;
848 base[order[i]] = place;
849 }
850
851 for (i = 0; i < nvectors; i++)
852 {
853 if (froms[i])
854 XFREE (froms[i]);
855 if (tos[i])
856 XFREE (tos[i]);
857 }
858
859 XFREE (froms);
860 XFREE (tos);
861 XFREE (pos);
862}
863
864/* the following functions output yytable, yycheck
865 and the vectors whose elements index the portion starts */
866
867static void
868output_base (void)
869{
870 /* Output pact. */
871 output_table_data (&output_obstack, base,
872 base[0], 1, nstates);
873 muscle_insert ("pact", obstack_finish (&output_obstack));
874
875 /* Output pgoto. */
876 output_table_data (&output_obstack, base,
877 base[nstates], nstates + 1, nvectors);
878 muscle_insert ("pgoto", obstack_finish (&output_obstack));
879
880 XFREE (base);
881}
882
883
884static void
885output_table (void)
886{
887 output_table_data (&output_obstack, table,
888 table[0], 1, high + 1);
889 muscle_insert ("table", obstack_finish (&output_obstack));
890 XFREE (table);
891}
892
893
894static void
895output_check (void)
896{
897 output_table_data (&output_obstack, check,
898 check[0], 1, high + 1);
899 muscle_insert ("check", obstack_finish (&output_obstack));
900 XFREE (check);
901}
902
903/* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
904 and yycheck. */
905
906static void
907output_actions (void)
908{
909 nvectors = nstates + nvars;
910
911 froms = XCALLOC (short *, nvectors);
912 tos = XCALLOC (short *, nvectors);
913 tally = XCALLOC (short, nvectors);
914 width = XCALLOC (short, nvectors);
915
916 token_actions ();
917 LIST_FREE (shifts, first_shift);
918 LIST_FREE (reductions, first_reduction);
919 XFREE (LA);
920 XFREE (LAruleno);
921
922 goto_actions ();
923 XFREE (goto_map + ntokens);
924 XFREE (from_state);
925 XFREE (to_state);
926
927 sort_actions ();
928 pack_table ();
929
930 output_base ();
931 output_table ();
932
933 output_check ();
934 XFREE (state_table);
935}
936
937\f
938/*------------------------------------------------------------.
939| Copy the parser code from SKEL_FILENAME into OOUT obstack. |
940| and do the muscle substitution. |
941`------------------------------------------------------------*/
942
943static void
944output_parser (const char *skel_filename, struct obstack *oout)
945{
946 int c;
947 FILE *fskel;
948 size_t line;
949
950 fskel = xfopen (skel_filename, "r");
951
952 /* New output code. */
953 line = 1;
954 c = getc (fskel);
955 while (c != EOF)
956 {
957 if (c != '%')
958 {
959 if (c == '\n')
960 ++line;
961 obstack_1grow (oout, c);
962 c = getc (fskel);
963 }
964 else if ((c = getc (fskel)) == '%')
965 {
966 /* Read the muscle. */
967 const char *muscle_key = 0;
968 const char *muscle_value = 0;
969
970 while (isalnum (c = getc (fskel)) || c == '-')
971 obstack_1grow (&muscle_obstack, c);
972 obstack_1grow (&muscle_obstack, 0);
973
974 /* Output the right value, or see if it's something special. */
975 muscle_key = obstack_finish (&muscle_obstack);
976 muscle_value = muscle_find (muscle_key);
977 if (muscle_value)
978 obstack_sgrow (oout, muscle_value);
979 else if (!strcmp (muscle_key, "line"))
980 obstack_fgrow1 (oout, "%d", line + 1);
981 else if (!strcmp (muscle_key, "input-line"))
982 obstack_fgrow1 (oout, "%d", lineno);
983 else
984 {
985 obstack_sgrow (oout, "%%");
986 obstack_sgrow (oout, muscle_key);
987 }
988 }
989 else
990 obstack_1grow (oout, '%');
991 }
992
993 /* End. */
994 xfclose (fskel);
995}
996
997/*----------------------------------------.
998| Prepare the master parser to be output |
999`----------------------------------------*/
1000
1001static void
1002output_master_parser (void)
1003{
1004 if (!skeleton)
1005 {
1006 if (semantic_parser)
1007 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1008 else
1009 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1010 }
1011 muscle_insert ("skeleton", skeleton);
1012 output_parser (skeleton, &table_obstack);
1013}
1014
1015
1016/* FIXME. */
1017
1018#define MUSCLE_INSERT_INT(Key, Value) \
1019{ \
1020 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1021 obstack_1grow (&muscle_obstack, 0); \
1022 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1023}
1024
1025#define MUSCLE_INSERT_STRING(Key, Value) \
1026{ \
1027 obstack_sgrow (&muscle_obstack, Value); \
1028 obstack_1grow (&muscle_obstack, 0); \
1029 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1030}
1031
1032#define MUSCLE_INSERT_PREFIX(Key, Value) \
1033{ \
1034 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1035 obstack_1grow (&muscle_obstack, 0); \
1036 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1037}
1038
1039static void
1040prepare (void)
1041{
1042 MUSCLE_INSERT_INT ("last", high);
1043 MUSCLE_INSERT_INT ("flag", MINSHORT);
1044 MUSCLE_INSERT_INT ("pure", pure_parser);
1045 MUSCLE_INSERT_INT ("nsym", nsyms);
1046 MUSCLE_INSERT_INT ("debug", debug_flag);
1047 MUSCLE_INSERT_INT ("final", final_state);
1048 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1049 MUSCLE_INSERT_INT ("ntbase", ntokens);
1050 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
1051
1052 MUSCLE_INSERT_INT ("nnts", nvars);
1053 MUSCLE_INSERT_INT ("nrules", nrules);
1054 MUSCLE_INSERT_INT ("nstates", nstates);
1055 MUSCLE_INSERT_INT ("ntokens", ntokens);
1056
1057 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
1058
1059 /* We need to save the actions in the muscle %%action. */
1060 muscle_insert ("action", obstack_finish (&action_obstack));
1061
1062 if (spec_name_prefix)
1063 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
1064}
1065
1066/*----------------------------------------------------------.
1067| Output the parsing tables and the parser code to ftable. |
1068`----------------------------------------------------------*/
1069
1070void
1071output (void)
1072{
1073 obstack_init (&output_obstack);
1074
1075 LIST_FREE (core, first_state);
1076
1077 output_token_translations ();
1078 output_gram ();
1079
1080 XFREE (ritem);
1081 if (semantic_parser)
1082 output_stos ();
1083 output_rule_data ();
1084 XFREE (user_toknums);
1085 output_actions ();
1086
1087#if 0
1088 if (!no_parser_flag) */
1089#endif
1090 prepare ();
1091 /* Copy definitions in directive. */
1092 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1093
1094 output_master_parser ();
1095
1096 obstack_free (&muscle_obstack, 0);
1097 obstack_free (&output_obstack, 0);
1098 obstack_free (&action_obstack, 0);
1099}