]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/byacc/output.c
MFC: r257315, r260445, r264803
[FreeBSD/stable/10.git] / contrib / byacc / output.c
1 /* $Id: output.c,v 1.67 2014/04/22 23:16:57 tom Exp $ */
2
3 #include "defs.h"
4
5 #define StaticOrR       (rflag ? "" : "static ")
6 #define CountLine(fp)   (!rflag || ((fp) == code_file))
7
8 #if defined(YYBTYACC)
9 #define PER_STATE 3
10 #else
11 #define PER_STATE 2
12 #endif
13
14 static int nvectors;
15 static int nentries;
16 static Value_t **froms;
17 static Value_t **tos;
18 #if defined(YYBTYACC)
19 static Value_t *conflicts = NULL;
20 static Value_t nconflicts = 0;
21 #endif
22 static Value_t *tally;
23 static Value_t *width;
24 static Value_t *state_count;
25 static Value_t *order;
26 static Value_t *base;
27 static Value_t *pos;
28 static int maxtable;
29 static Value_t *table;
30 static Value_t *check;
31 static int lowzero;
32 static long high;
33
34 static void
35 putc_code(FILE * fp, int c)
36 {
37     if ((c == '\n') && (fp == code_file))
38         ++outline;
39     putc(c, fp);
40 }
41
42 static void
43 putl_code(FILE * fp, const char *s)
44 {
45     if (fp == code_file)
46         ++outline;
47     fputs(s, fp);
48 }
49
50 static void
51 puts_code(FILE * fp, const char *s)
52 {
53     fputs(s, fp);
54 }
55
56 static void
57 write_code_lineno(FILE * fp)
58 {
59     if (!lflag && (fp == code_file))
60     {
61         ++outline;
62         fprintf(fp, line_format, outline + 1, code_file_name);
63     }
64 }
65
66 static void
67 write_input_lineno(void)
68 {
69     if (!lflag)
70     {
71         ++outline;
72         fprintf(code_file, line_format, lineno, input_file_name);
73     }
74 }
75
76 static void
77 define_prefixed(FILE * fp, const char *name)
78 {
79     int bump_line = CountLine(fp);
80     if (bump_line)
81         ++outline;
82     fprintf(fp, "\n");
83
84     if (bump_line)
85         ++outline;
86     fprintf(fp, "#ifndef %s\n", name);
87
88     if (bump_line)
89         ++outline;
90     fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
91
92     if (bump_line)
93         ++outline;
94     fprintf(fp, "#endif /* %s */\n", name);
95 }
96
97 static void
98 output_prefix(FILE * fp)
99 {
100     if (symbol_prefix == NULL)
101     {
102         symbol_prefix = "yy";
103     }
104     else
105     {
106         define_prefixed(fp, "yyparse");
107         define_prefixed(fp, "yylex");
108         define_prefixed(fp, "yyerror");
109         define_prefixed(fp, "yychar");
110         define_prefixed(fp, "yyval");
111         define_prefixed(fp, "yylval");
112         define_prefixed(fp, "yydebug");
113         define_prefixed(fp, "yynerrs");
114         define_prefixed(fp, "yyerrflag");
115         define_prefixed(fp, "yylhs");
116         define_prefixed(fp, "yylen");
117         define_prefixed(fp, "yydefred");
118 #if defined(YYBTYACC)
119         define_prefixed(fp, "yystos");
120 #endif
121         define_prefixed(fp, "yydgoto");
122         define_prefixed(fp, "yysindex");
123         define_prefixed(fp, "yyrindex");
124         define_prefixed(fp, "yygindex");
125         define_prefixed(fp, "yytable");
126         define_prefixed(fp, "yycheck");
127         define_prefixed(fp, "yyname");
128         define_prefixed(fp, "yyrule");
129 #if defined(YYBTYACC)
130         if (locations)
131         {
132             define_prefixed(fp, "yyloc");
133             define_prefixed(fp, "yylloc");
134         }
135         putc_code(fp, '\n');
136         putl_code(fp, "#if YYBTYACC\n");
137
138         define_prefixed(fp, "yycindex");
139         define_prefixed(fp, "yyctable");
140
141         putc_code(fp, '\n');
142         putl_code(fp, "#endif /* YYBTYACC */\n");
143         putc_code(fp, '\n');
144 #endif
145     }
146     if (CountLine(fp))
147         ++outline;
148     fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
149 }
150
151 static void
152 output_newline(void)
153 {
154     if (!rflag)
155         ++outline;
156     putc('\n', output_file);
157 }
158
159 static void
160 output_line(const char *value)
161 {
162     fputs(value, output_file);
163     output_newline();
164 }
165
166 static void
167 output_int(int value)
168 {
169     fprintf(output_file, "%5d,", value);
170 }
171
172 static void
173 start_int_table(const char *name, int value)
174 {
175     int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
176
177     if (need < 6)
178         need = 6;
179     fprintf(output_file,
180             "%sconst YYINT %s%s[] = {%*d,",
181             StaticOrR, symbol_prefix, name, need, value);
182 }
183
184 static void
185 start_str_table(const char *name)
186 {
187     fprintf(output_file,
188             "%sconst char *const %s%s[] = {",
189             StaticOrR, symbol_prefix, name);
190     output_newline();
191 }
192
193 static void
194 end_table(void)
195 {
196     output_newline();
197     output_line("};");
198 }
199
200 static void
201 output_YYINT_typedef(FILE * fp)
202 {
203     /* generate the type used to index the various parser tables */
204     if (CountLine(fp))
205         ++outline;
206     fprintf(fp, "typedef %s YYINT;\n", CONCAT1("", YYINT));
207 }
208
209 static void
210 output_rule_data(void)
211 {
212     int i;
213     int j;
214
215     output_YYINT_typedef(output_file);
216
217     start_int_table("lhs", symbol_value[start_symbol]);
218
219     j = 10;
220     for (i = 3; i < nrules; i++)
221     {
222         if (j >= 10)
223         {
224             output_newline();
225             j = 1;
226         }
227         else
228             ++j;
229
230         output_int(symbol_value[rlhs[i]]);
231     }
232     end_table();
233
234     start_int_table("len", 2);
235
236     j = 10;
237     for (i = 3; i < nrules; i++)
238     {
239         if (j >= 10)
240         {
241             output_newline();
242             j = 1;
243         }
244         else
245             j++;
246
247         output_int(rrhs[i + 1] - rrhs[i] - 1);
248     }
249     end_table();
250 }
251
252 static void
253 output_yydefred(void)
254 {
255     int i, j;
256
257     start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
258
259     j = 10;
260     for (i = 1; i < nstates; i++)
261     {
262         if (j < 10)
263             ++j;
264         else
265         {
266             output_newline();
267             j = 1;
268         }
269
270         output_int((defred[i] ? defred[i] - 2 : 0));
271     }
272
273     end_table();
274 }
275
276 #if defined(YYBTYACC)
277 static void
278 output_accessing_symbols(void)
279 {
280     int i, j;
281     int *translate;
282
283     if (nstates != 0)
284     {
285         translate = TMALLOC(int, nstates);
286         NO_SPACE(translate);
287
288         for (i = 0; i < nstates; ++i)
289         {
290             int gsymb = accessing_symbol[i];
291
292             translate[i] = symbol_pval[gsymb];
293         }
294
295         /* yystos[] may be unused, depending on compile-time defines */
296         start_int_table("stos", translate[0]);
297
298         j = 10;
299         for (i = 1; i < nstates; ++i)
300         {
301             if (j < 10)
302                 ++j;
303             else
304             {
305                 output_newline();
306                 j = 1;
307             }
308
309             output_int(translate[i]);
310         }
311
312         end_table();
313         FREE(translate);
314     }
315 }
316
317 static Value_t
318 find_conflict_base(int cbase)
319 {
320     int i, j;
321
322     for (i = 0; i < cbase; i++)
323     {
324         for (j = 0; j + cbase < nconflicts; j++)
325         {
326             if (conflicts[i + j] != conflicts[cbase + j])
327                 break;
328         }
329         if (j + cbase >= nconflicts)
330             break;
331     }
332     return (Value_t) i;
333 }
334 #endif
335
336 static void
337 token_actions(void)
338 {
339     int i, j;
340     Value_t shiftcount, reducecount;
341 #if defined(YYBTYACC)
342     Value_t conflictcount = 0;
343     Value_t csym = -1;
344     Value_t cbase = 0;
345 #endif
346     int max, min;
347     Value_t *actionrow, *r, *s;
348     action *p;
349
350     actionrow = NEW2(PER_STATE * ntokens, Value_t);
351     for (i = 0; i < nstates; ++i)
352     {
353         if (parser[i])
354         {
355             for (j = 0; j < PER_STATE * ntokens; ++j)
356                 actionrow[j] = 0;
357
358             shiftcount = 0;
359             reducecount = 0;
360 #if defined(YYBTYACC)
361             if (backtrack)
362             {
363                 conflictcount = 0;
364                 csym = -1;
365                 cbase = nconflicts;
366             }
367 #endif
368             for (p = parser[i]; p; p = p->next)
369             {
370 #if defined(YYBTYACC)
371                 if (backtrack)
372                 {
373                     if (csym != -1 && csym != p->symbol)
374                     {
375                         conflictcount++;
376                         conflicts[nconflicts++] = -1;
377                         j = find_conflict_base(cbase);
378                         actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
379                         if (j == cbase)
380                         {
381                             cbase = nconflicts;
382                         }
383                         else
384                         {
385                             if (conflicts[cbase] == -1)
386                                 cbase++;
387                             nconflicts = cbase;
388                         }
389                         csym = -1;
390                     }
391                 }
392 #endif
393                 if (p->suppressed == 0)
394                 {
395                     if (p->action_code == SHIFT)
396                     {
397                         ++shiftcount;
398                         actionrow[p->symbol] = p->number;
399                     }
400                     else if (p->action_code == REDUCE && p->number != defred[i])
401                     {
402                         ++reducecount;
403                         actionrow[p->symbol + ntokens] = p->number;
404                     }
405                 }
406 #if defined(YYBTYACC)
407                 else if (backtrack && p->suppressed == 1)
408                 {
409                     csym = p->symbol;
410                     if (p->action_code == SHIFT)
411                     {
412                         conflicts[nconflicts++] = p->number;
413                     }
414                     else if (p->action_code == REDUCE && p->number != defred[i])
415                     {
416                         if (cbase == nconflicts)
417                         {
418                             if (cbase)
419                                 cbase--;
420                             else
421                                 conflicts[nconflicts++] = -1;
422                         }
423                         conflicts[nconflicts++] = (Value_t) (p->number - 2);
424                     }
425                 }
426 #endif
427             }
428 #if defined(YYBTYACC)
429             if (backtrack && csym != -1)
430             {
431                 conflictcount++;
432                 conflicts[nconflicts++] = -1;
433                 j = find_conflict_base(cbase);
434                 actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
435                 if (j == cbase)
436                 {
437                     cbase = nconflicts;
438                 }
439                 else
440                 {
441                     if (conflicts[cbase] == -1)
442                         cbase++;
443                     nconflicts = cbase;
444                 }
445             }
446 #endif
447
448             tally[i] = shiftcount;
449             tally[nstates + i] = reducecount;
450 #if defined(YYBTYACC)
451             if (backtrack)
452                 tally[2 * nstates + i] = conflictcount;
453 #endif
454             width[i] = 0;
455             width[nstates + i] = 0;
456 #if defined(YYBTYACC)
457             if (backtrack)
458                 width[2 * nstates + i] = 0;
459 #endif
460             if (shiftcount > 0)
461             {
462                 froms[i] = r = NEW2(shiftcount, Value_t);
463                 tos[i] = s = NEW2(shiftcount, Value_t);
464                 min = MAXYYINT;
465                 max = 0;
466                 for (j = 0; j < ntokens; ++j)
467                 {
468                     if (actionrow[j])
469                     {
470                         if (min > symbol_value[j])
471                             min = symbol_value[j];
472                         if (max < symbol_value[j])
473                             max = symbol_value[j];
474                         *r++ = symbol_value[j];
475                         *s++ = actionrow[j];
476                     }
477                 }
478                 width[i] = (Value_t) (max - min + 1);
479             }
480             if (reducecount > 0)
481             {
482                 froms[nstates + i] = r = NEW2(reducecount, Value_t);
483                 tos[nstates + i] = s = NEW2(reducecount, Value_t);
484                 min = MAXYYINT;
485                 max = 0;
486                 for (j = 0; j < ntokens; ++j)
487                 {
488                     if (actionrow[ntokens + j])
489                     {
490                         if (min > symbol_value[j])
491                             min = symbol_value[j];
492                         if (max < symbol_value[j])
493                             max = symbol_value[j];
494                         *r++ = symbol_value[j];
495                         *s++ = (Value_t) (actionrow[ntokens + j] - 2);
496                     }
497                 }
498                 width[nstates + i] = (Value_t) (max - min + 1);
499             }
500 #if defined(YYBTYACC)
501             if (backtrack && conflictcount > 0)
502             {
503                 froms[2 * nstates + i] = r = NEW2(conflictcount, Value_t);
504                 tos[2 * nstates + i] = s = NEW2(conflictcount, Value_t);
505                 min = MAXYYINT;
506                 max = 0;
507                 for (j = 0; j < ntokens; ++j)
508                 {
509                     if (actionrow[2 * ntokens + j])
510                     {
511                         if (min > symbol_value[j])
512                             min = symbol_value[j];
513                         if (max < symbol_value[j])
514                             max = symbol_value[j];
515                         *r++ = symbol_value[j];
516                         *s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
517                     }
518                 }
519                 width[2 * nstates + i] = (Value_t) (max - min + 1);
520             }
521 #endif
522         }
523     }
524     FREE(actionrow);
525 }
526
527 static int
528 default_goto(int symbol)
529 {
530     int i;
531     int m;
532     int n;
533     int default_state;
534     int max;
535
536     m = goto_map[symbol];
537     n = goto_map[symbol + 1];
538
539     if (m == n)
540         return (0);
541
542     for (i = 0; i < nstates; i++)
543         state_count[i] = 0;
544
545     for (i = m; i < n; i++)
546         state_count[to_state[i]]++;
547
548     max = 0;
549     default_state = 0;
550     for (i = 0; i < nstates; i++)
551     {
552         if (state_count[i] > max)
553         {
554             max = state_count[i];
555             default_state = i;
556         }
557     }
558
559     return (default_state);
560 }
561
562 static void
563 save_column(int symbol, int default_state)
564 {
565     int i;
566     int m;
567     int n;
568     Value_t *sp;
569     Value_t *sp1;
570     Value_t *sp2;
571     Value_t count;
572     int symno;
573
574     m = goto_map[symbol];
575     n = goto_map[symbol + 1];
576
577     count = 0;
578     for (i = m; i < n; i++)
579     {
580         if (to_state[i] != default_state)
581             ++count;
582     }
583     if (count == 0)
584         return;
585
586     symno = symbol_value[symbol] + PER_STATE * nstates;
587
588     froms[symno] = sp1 = sp = NEW2(count, Value_t);
589     tos[symno] = sp2 = NEW2(count, Value_t);
590
591     for (i = m; i < n; i++)
592     {
593         if (to_state[i] != default_state)
594         {
595             *sp1++ = from_state[i];
596             *sp2++ = to_state[i];
597         }
598     }
599
600     tally[symno] = count;
601     width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
602 }
603
604 static void
605 goto_actions(void)
606 {
607     int i, j, k;
608
609     state_count = NEW2(nstates, Value_t);
610
611     k = default_goto(start_symbol + 1);
612     start_int_table("dgoto", k);
613     save_column(start_symbol + 1, k);
614
615     j = 10;
616     for (i = start_symbol + 2; i < nsyms; i++)
617     {
618         if (j >= 10)
619         {
620             output_newline();
621             j = 1;
622         }
623         else
624             ++j;
625
626         k = default_goto(i);
627         output_int(k);
628         save_column(i, k);
629     }
630
631     end_table();
632     FREE(state_count);
633 }
634
635 static void
636 sort_actions(void)
637 {
638     Value_t i;
639     int j;
640     int k;
641     int t;
642     int w;
643
644     order = NEW2(nvectors, Value_t);
645     nentries = 0;
646
647     for (i = 0; i < nvectors; i++)
648     {
649         if (tally[i] > 0)
650         {
651             t = tally[i];
652             w = width[i];
653             j = nentries - 1;
654
655             while (j >= 0 && (width[order[j]] < w))
656                 j--;
657
658             while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
659                 j--;
660
661             for (k = nentries - 1; k > j; k--)
662                 order[k + 1] = order[k];
663
664             order[j + 1] = i;
665             nentries++;
666         }
667     }
668 }
669
670 /*  The function matching_vector determines if the vector specified by  */
671 /*  the input parameter matches a previously considered vector.  The    */
672 /*  test at the start of the function checks if the vector represents   */
673 /*  a row of shifts over terminal symbols or a row of reductions, or a  */
674 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not */
675 /*  check if a column of shifts over a nonterminal symbols matches a    */
676 /*  previously considered vector.  Because of the nature of LR parsing  */
677 /*  tables, no two columns can match.  Therefore, the only possible     */
678 /*  match would be between a row and a column.  Such matches are        */
679 /*  unlikely.  Therefore, to save time, no attempt is made to see if a  */
680 /*  column matches a previously considered vector.                      */
681 /*                                                                      */
682 /*  Matching_vector is poorly designed.  The test could easily be made  */
683 /*  faster.  Also, it depends on the vectors being in a specific        */
684 /*  order.                                                              */
685 #if defined(YYBTYACC)
686 /*                                                                      */
687 /*  Not really any point in checking for matching conflicts -- it is    */
688 /*  extremely unlikely to occur, and conflicts are (hopefully) rare.    */
689 #endif
690
691 static int
692 matching_vector(int vector)
693 {
694     int i;
695     int j;
696     int k;
697     int t;
698     int w;
699     int match;
700     int prev;
701
702     i = order[vector];
703     if (i >= 2 * nstates)
704         return (-1);
705
706     t = tally[i];
707     w = width[i];
708
709     for (prev = vector - 1; prev >= 0; prev--)
710     {
711         j = order[prev];
712         if (width[j] != w || tally[j] != t)
713             return (-1);
714
715         match = 1;
716         for (k = 0; match && k < t; k++)
717         {
718             if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
719                 match = 0;
720         }
721
722         if (match)
723             return (j);
724     }
725
726     return (-1);
727 }
728
729 static int
730 pack_vector(int vector)
731 {
732     int i, j, k, l;
733     int t;
734     int loc;
735     int ok;
736     Value_t *from;
737     Value_t *to;
738     int newmax;
739
740     i = order[vector];
741     t = tally[i];
742     assert(t);
743
744     from = froms[i];
745     to = tos[i];
746
747     j = lowzero - from[0];
748     for (k = 1; k < t; ++k)
749         if (lowzero - from[k] > j)
750             j = lowzero - from[k];
751     for (;; ++j)
752     {
753         if (j == 0)
754             continue;
755         ok = 1;
756         for (k = 0; ok && k < t; k++)
757         {
758             loc = j + from[k];
759             if (loc >= maxtable - 1)
760             {
761                 if (loc >= MAXTABLE - 1)
762                     fatal("maximum table size exceeded");
763
764                 newmax = maxtable;
765                 do
766                 {
767                     newmax += 200;
768                 }
769                 while (newmax <= loc);
770
771                 table = TREALLOC(Value_t, table, newmax);
772                 NO_SPACE(table);
773
774                 check = TREALLOC(Value_t, check, newmax);
775                 NO_SPACE(check);
776
777                 for (l = maxtable; l < newmax; ++l)
778                 {
779                     table[l] = 0;
780                     check[l] = -1;
781                 }
782                 maxtable = newmax;
783             }
784
785             if (check[loc] != -1)
786                 ok = 0;
787         }
788         for (k = 0; ok && k < vector; k++)
789         {
790             if (pos[k] == j)
791                 ok = 0;
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                 if (loc > high)
801                     high = loc;
802             }
803
804             while (check[lowzero] != -1)
805                 ++lowzero;
806
807             return (j);
808         }
809     }
810 }
811
812 static void
813 pack_table(void)
814 {
815     int i;
816     Value_t place;
817     int state;
818
819     base = NEW2(nvectors, Value_t);
820     pos = NEW2(nentries, Value_t);
821
822     maxtable = 1000;
823     table = NEW2(maxtable, Value_t);
824     check = NEW2(maxtable, Value_t);
825
826     lowzero = 0;
827     high = 0;
828
829     for (i = 0; i < maxtable; i++)
830         check[i] = -1;
831
832     for (i = 0; i < nentries; i++)
833     {
834         state = matching_vector(i);
835
836         if (state < 0)
837             place = (Value_t) pack_vector(i);
838         else
839             place = base[state];
840
841         pos[i] = place;
842         base[order[i]] = place;
843     }
844
845     for (i = 0; i < nvectors; i++)
846     {
847         if (froms[i])
848             FREE(froms[i]);
849         if (tos[i])
850             FREE(tos[i]);
851     }
852
853     DO_FREE(froms);
854     DO_FREE(tos);
855     DO_FREE(tally);
856     DO_FREE(width);
857     DO_FREE(pos);
858 }
859
860 static void
861 output_base(void)
862 {
863     int i, j;
864
865     start_int_table("sindex", base[0]);
866
867     j = 10;
868     for (i = 1; i < nstates; i++)
869     {
870         if (j >= 10)
871         {
872             output_newline();
873             j = 1;
874         }
875         else
876             ++j;
877
878         output_int(base[i]);
879     }
880
881     end_table();
882
883     start_int_table("rindex", base[nstates]);
884
885     j = 10;
886     for (i = nstates + 1; i < 2 * nstates; i++)
887     {
888         if (j >= 10)
889         {
890             output_newline();
891             j = 1;
892         }
893         else
894             ++j;
895
896         output_int(base[i]);
897     }
898
899     end_table();
900
901 #if defined(YYBTYACC)
902     output_line("#if YYBTYACC");
903     start_int_table("cindex", base[2 * nstates]);
904
905     j = 10;
906     for (i = 2 * nstates + 1; i < 3 * nstates; i++)
907     {
908         if (j >= 10)
909         {
910             output_newline();
911             j = 1;
912         }
913         else
914             ++j;
915
916         output_int(base[i]);
917     }
918
919     end_table();
920     output_line("#endif");
921 #endif
922
923     start_int_table("gindex", base[PER_STATE * nstates]);
924
925     j = 10;
926     for (i = PER_STATE * nstates + 1; i < nvectors - 1; i++)
927     {
928         if (j >= 10)
929         {
930             output_newline();
931             j = 1;
932         }
933         else
934             ++j;
935
936         output_int(base[i]);
937     }
938
939     end_table();
940     FREE(base);
941 }
942
943 static void
944 output_table(void)
945 {
946     int i;
947     int j;
948
949     if (high >= MAXYYINT)
950     {
951         fprintf(stderr, "YYTABLESIZE: %ld\n", high);
952         fprintf(stderr, "Table is longer than %d elements.\n", MAXYYINT);
953         done(1);
954     }
955
956     ++outline;
957     fprintf(code_file, "#define YYTABLESIZE %ld\n", high);
958     start_int_table("table", table[0]);
959
960     j = 10;
961     for (i = 1; i <= high; i++)
962     {
963         if (j >= 10)
964         {
965             output_newline();
966             j = 1;
967         }
968         else
969             ++j;
970
971         output_int(table[i]);
972     }
973
974     end_table();
975     FREE(table);
976 }
977
978 static void
979 output_check(void)
980 {
981     int i;
982     int j;
983
984     start_int_table("check", check[0]);
985
986     j = 10;
987     for (i = 1; i <= high; i++)
988     {
989         if (j >= 10)
990         {
991             output_newline();
992             j = 1;
993         }
994         else
995             ++j;
996
997         output_int(check[i]);
998     }
999
1000     end_table();
1001     FREE(check);
1002 }
1003
1004 #if defined(YYBTYACC)
1005 static void
1006 output_ctable(void)
1007 {
1008     int i;
1009     int j;
1010
1011     if (conflicts)
1012     {
1013         output_line("#if YYBTYACC");
1014         start_int_table("ctable", conflicts[0]);
1015
1016         j = 10;
1017         for (i = 1; i < nconflicts; i++)
1018         {
1019             if (j >= 10)
1020             {
1021                 output_newline();
1022                 j = 1;
1023             }
1024             else
1025                 ++j;
1026
1027             output_int(conflicts[i]);
1028         }
1029
1030         end_table();
1031         output_line("#endif");
1032         FREE(conflicts);
1033     }
1034 }
1035 #endif
1036
1037 static void
1038 output_actions(void)
1039 {
1040     nvectors = PER_STATE * nstates + nvars;
1041
1042     froms = NEW2(nvectors, Value_t *);
1043     tos = NEW2(nvectors, Value_t *);
1044     tally = NEW2(nvectors, Value_t);
1045     width = NEW2(nvectors, Value_t);
1046
1047 #if defined(YYBTYACC)
1048     if (backtrack && (SRtotal + RRtotal) != 0)
1049         conflicts = NEW2(4 * (SRtotal + RRtotal), Value_t);
1050 #endif
1051
1052     token_actions();
1053     FREE(lookaheads);
1054     FREE(LA);
1055     FREE(LAruleno);
1056     FREE(accessing_symbol);
1057
1058     goto_actions();
1059     FREE(goto_map + ntokens);
1060     FREE(from_state);
1061     FREE(to_state);
1062
1063     sort_actions();
1064     pack_table();
1065     output_base();
1066     output_table();
1067     output_check();
1068 #if defined(YYBTYACC)
1069     output_ctable();
1070 #endif
1071 }
1072
1073 static int
1074 is_C_identifier(char *name)
1075 {
1076     char *s;
1077     int c;
1078
1079     s = name;
1080     c = *s;
1081     if (c == '"')
1082     {
1083         c = *++s;
1084         if (!isalpha(c) && c != '_' && c != '$')
1085             return (0);
1086         while ((c = *++s) != '"')
1087         {
1088             if (!isalnum(c) && c != '_' && c != '$')
1089                 return (0);
1090         }
1091         return (1);
1092     }
1093
1094     if (!isalpha(c) && c != '_' && c != '$')
1095         return (0);
1096     while ((c = *++s) != 0)
1097     {
1098         if (!isalnum(c) && c != '_' && c != '$')
1099             return (0);
1100     }
1101     return (1);
1102 }
1103
1104 #if USE_HEADER_GUARDS
1105 static void
1106 start_defines_file(void)
1107 {
1108     fprintf(defines_file, "#ifndef _%s_defines_h_\n", symbol_prefix);
1109     fprintf(defines_file, "#define _%s_defines_h_\n\n", symbol_prefix);
1110 }
1111
1112 static void
1113 end_defines_file(void)
1114 {
1115     fprintf(defines_file, "\n#endif /* _%s_defines_h_ */\n", symbol_prefix);
1116 }
1117 #else
1118 #define start_defines_file()    /* nothing */
1119 #define end_defines_file()      /* nothing */
1120 #endif
1121
1122 static void
1123 output_defines(FILE * fp)
1124 {
1125     int c, i;
1126     char *s;
1127
1128     for (i = 2; i < ntokens; ++i)
1129     {
1130         s = symbol_name[i];
1131         if (is_C_identifier(s) && (!sflag || *s != '"'))
1132         {
1133             fprintf(fp, "#define ");
1134             c = *s;
1135             if (c == '"')
1136             {
1137                 while ((c = *++s) != '"')
1138                 {
1139                     putc(c, fp);
1140                 }
1141             }
1142             else
1143             {
1144                 do
1145                 {
1146                     putc(c, fp);
1147                 }
1148                 while ((c = *++s) != 0);
1149             }
1150             if (fp == code_file)
1151                 ++outline;
1152             fprintf(fp, " %d\n", symbol_value[i]);
1153         }
1154     }
1155
1156     if (fp == code_file)
1157         ++outline;
1158     if (fp != defines_file || iflag)
1159         fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
1160
1161     if (fp == defines_file || (iflag && !dflag))
1162     {
1163         if (unionized)
1164         {
1165             if (union_file != 0)
1166             {
1167                 rewind(union_file);
1168                 while ((c = getc(union_file)) != EOF)
1169                     putc_code(fp, c);
1170             }
1171             fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
1172         }
1173     }
1174 }
1175
1176 static void
1177 output_stored_text(FILE * fp)
1178 {
1179     int c;
1180     FILE *in;
1181
1182     rewind(text_file);
1183     if (text_file == NULL)
1184         open_error("text_file");
1185     in = text_file;
1186     if ((c = getc(in)) == EOF)
1187         return;
1188     putc_code(fp, c);
1189     while ((c = getc(in)) != EOF)
1190     {
1191         putc_code(fp, c);
1192     }
1193     write_code_lineno(fp);
1194 }
1195
1196 static void
1197 output_debug(void)
1198 {
1199     int i, j, k, max, maxtok;
1200     const char **symnam;
1201     const char *s;
1202
1203     ++outline;
1204     fprintf(code_file, "#define YYFINAL %d\n", final_state);
1205
1206     putl_code(code_file, "#ifndef YYDEBUG\n");
1207     ++outline;
1208     fprintf(code_file, "#define YYDEBUG %d\n", tflag);
1209     putl_code(code_file, "#endif\n");
1210
1211     if (rflag)
1212     {
1213         fprintf(output_file, "#ifndef YYDEBUG\n");
1214         fprintf(output_file, "#define YYDEBUG %d\n", tflag);
1215         fprintf(output_file, "#endif\n");
1216     }
1217
1218     maxtok = 0;
1219     for (i = 0; i < ntokens; ++i)
1220         if (symbol_value[i] > maxtok)
1221             maxtok = symbol_value[i];
1222
1223     /* symbol_value[$accept] = -1         */
1224     /* symbol_value[<goal>]  = 0          */
1225     /* remaining non-terminals start at 1 */
1226     max = maxtok;
1227     for (i = ntokens; i < nsyms; ++i)
1228         if (((maxtok + 1) + (symbol_value[i] + 1)) > max)
1229             max = (maxtok + 1) + (symbol_value[i] + 1);
1230
1231     ++outline;
1232     fprintf(code_file, "#define YYMAXTOKEN %d\n", maxtok);
1233
1234     ++outline;
1235     fprintf(code_file, "#define YYUNDFTOKEN %d\n", max + 1);
1236
1237     ++outline;
1238     fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
1239             "YYUNDFTOKEN : (a))\n");
1240
1241     symnam = TMALLOC(const char *, max + 2);
1242     NO_SPACE(symnam);
1243
1244     /* Note that it is not necessary to initialize the element          */
1245     /* symnam[max].                                                     */
1246 #if defined(YYBTYACC)
1247     for (i = 0; i < max; ++i)
1248         symnam[i] = 0;
1249     for (i = nsyms - 1; i >= 0; --i)
1250         symnam[symbol_pval[i]] = symbol_name[i];
1251     symnam[max + 1] = "illegal-symbol";
1252 #else
1253     for (i = 0; i <= max; ++i)
1254         symnam[i] = 0;
1255     for (i = ntokens - 1; i >= 2; --i)
1256         symnam[symbol_value[i]] = symbol_name[i];
1257     symnam[0] = "end-of-file";
1258     symnam[max + 1] = "illegal-symbol";
1259 #endif
1260
1261     /*
1262      * bison's yytname[] array is roughly the same as byacc's yyname[] array.
1263      * The difference is that byacc does not predefine "$undefined".
1264      *
1265      * If the grammar declares "%token-table", define symbol "yytname" so
1266      * an application such as ntpd can build.
1267      */
1268     if (token_table)
1269     {
1270         output_line("#undef yytname");
1271         output_line("#define yytname yyname");
1272     }
1273     else
1274     {
1275         output_line("#if YYDEBUG");
1276     }
1277
1278     start_str_table("name");
1279     j = 80;
1280     for (i = 0; i <= max + 1; ++i)
1281     {
1282         if ((s = symnam[i]) != 0)
1283         {
1284             if (s[0] == '"')
1285             {
1286                 k = 7;
1287                 while (*++s != '"')
1288                 {
1289                     ++k;
1290                     if (*s == '\\')
1291                     {
1292                         k += 2;
1293                         if (*++s == '\\')
1294                             ++k;
1295                     }
1296                 }
1297                 j += k;
1298                 if (j > 80)
1299                 {
1300                     output_newline();
1301                     j = k;
1302                 }
1303                 fprintf(output_file, "\"\\\"");
1304                 s = symnam[i];
1305                 while (*++s != '"')
1306                 {
1307                     if (*s == '\\')
1308                     {
1309                         fprintf(output_file, "\\\\");
1310                         if (*++s == '\\')
1311                             fprintf(output_file, "\\\\");
1312                         else
1313                             putc(*s, output_file);
1314                     }
1315                     else
1316                         putc(*s, output_file);
1317                 }
1318                 fprintf(output_file, "\\\"\",");
1319             }
1320             else if (s[0] == '\'')
1321             {
1322                 if (s[1] == '"')
1323                 {
1324                     j += 7;
1325                     if (j > 80)
1326                     {
1327                         output_newline();
1328                         j = 7;
1329                     }
1330                     fprintf(output_file, "\"'\\\"'\",");
1331                 }
1332                 else
1333                 {
1334                     k = 5;
1335                     while (*++s != '\'')
1336                     {
1337                         ++k;
1338                         if (*s == '\\')
1339                         {
1340                             k += 2;
1341                             if (*++s == '\\')
1342                                 ++k;
1343                         }
1344                     }
1345                     j += k;
1346                     if (j > 80)
1347                     {
1348                         output_newline();
1349                         j = k;
1350                     }
1351                     fprintf(output_file, "\"'");
1352                     s = symnam[i];
1353                     while (*++s != '\'')
1354                     {
1355                         if (*s == '\\')
1356                         {
1357                             fprintf(output_file, "\\\\");
1358                             if (*++s == '\\')
1359                                 fprintf(output_file, "\\\\");
1360                             else
1361                                 putc(*s, output_file);
1362                         }
1363                         else
1364                             putc(*s, output_file);
1365                     }
1366                     fprintf(output_file, "'\",");
1367                 }
1368             }
1369             else
1370             {
1371                 k = (int)strlen(s) + 3;
1372                 j += k;
1373                 if (j > 80)
1374                 {
1375                     output_newline();
1376                     j = k;
1377                 }
1378                 putc('"', output_file);
1379                 do
1380                 {
1381                     putc(*s, output_file);
1382                 }
1383                 while (*++s);
1384                 fprintf(output_file, "\",");
1385             }
1386         }
1387         else
1388         {
1389             j += 2;
1390             if (j > 80)
1391             {
1392                 output_newline();
1393                 j = 2;
1394             }
1395             fprintf(output_file, "0,");
1396         }
1397     }
1398     end_table();
1399     FREE(symnam);
1400
1401     if (token_table)
1402         output_line("#if YYDEBUG");
1403     start_str_table("rule");
1404     for (i = 2; i < nrules; ++i)
1405     {
1406         fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1407         for (j = rrhs[i]; ritem[j] > 0; ++j)
1408         {
1409             s = symbol_name[ritem[j]];
1410             if (s[0] == '"')
1411             {
1412                 fprintf(output_file, " \\\"");
1413                 while (*++s != '"')
1414                 {
1415                     if (*s == '\\')
1416                     {
1417                         if (s[1] == '\\')
1418                             fprintf(output_file, "\\\\\\\\");
1419                         else
1420                             fprintf(output_file, "\\\\%c", s[1]);
1421                         ++s;
1422                     }
1423                     else
1424                         putc(*s, output_file);
1425                 }
1426                 fprintf(output_file, "\\\"");
1427             }
1428             else if (s[0] == '\'')
1429             {
1430                 if (s[1] == '"')
1431                     fprintf(output_file, " '\\\"'");
1432                 else if (s[1] == '\\')
1433                 {
1434                     if (s[2] == '\\')
1435                         fprintf(output_file, " '\\\\\\\\");
1436                     else
1437                         fprintf(output_file, " '\\\\%c", s[2]);
1438                     s += 2;
1439                     while (*++s != '\'')
1440                         putc(*s, output_file);
1441                     putc('\'', output_file);
1442                 }
1443                 else
1444                     fprintf(output_file, " '%c'", s[1]);
1445             }
1446             else
1447                 fprintf(output_file, " %s", s);
1448         }
1449         fprintf(output_file, "\",");
1450         output_newline();
1451     }
1452
1453     end_table();
1454     output_line("#endif");
1455 }
1456
1457 #if defined(YYBTYACC)
1458 static void
1459 output_backtracking_parser(FILE * fp)
1460 {
1461     putl_code(fp, "#undef YYBTYACC\n");
1462 #if defined(YYBTYACC)
1463     if (backtrack)
1464     {
1465         putl_code(fp, "#define YYBTYACC 1\n");
1466         putl_code(fp,
1467                   "#define YYDEBUGSTR (yytrial ? YYPREFIX \"debug(trial)\" : YYPREFIX \"debug\")\n");
1468     }
1469     else
1470 #endif
1471     {
1472         putl_code(fp, "#define YYBTYACC 0\n");
1473         putl_code(fp, "#define YYDEBUGSTR YYPREFIX \"debug\"\n");
1474     }
1475 }
1476 #endif
1477
1478 static void
1479 output_pure_parser(FILE * fp)
1480 {
1481     putc_code(fp, '\n');
1482
1483     if (fp == code_file)
1484         ++outline;
1485     fprintf(fp, "#define YYPURE %d\n", pure_parser);
1486     putc_code(fp, '\n');
1487 }
1488
1489 static void
1490 output_stype(FILE * fp)
1491 {
1492     if (!unionized && ntags == 0)
1493     {
1494         putc_code(fp, '\n');
1495         putl_code(fp, "#if "
1496                   "! defined(YYSTYPE) && "
1497                   "! defined(YYSTYPE_IS_DECLARED)\n");
1498         putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
1499         putl_code(fp, "typedef int YYSTYPE;\n");
1500         putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
1501         putl_code(fp, "#endif\n");
1502     }
1503 }
1504
1505 #if defined(YYBTYACC)
1506 static void
1507 output_ltype(FILE * fp)
1508 {
1509     putc_code(fp, '\n');
1510     putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
1511     putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
1512     putl_code(fp, "typedef struct YYLTYPE\n");
1513     putl_code(fp, "{\n");
1514     putl_code(fp, "    int first_line;\n");
1515     putl_code(fp, "    int first_column;\n");
1516     putl_code(fp, "    int last_line;\n");
1517     putl_code(fp, "    int last_column;\n");
1518     putl_code(fp, "} YYLTYPE;\n");
1519     putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
1520     putl_code(fp, "#endif\n");
1521 }
1522 #endif
1523
1524 static void
1525 output_trailing_text(void)
1526 {
1527     int c, last;
1528     FILE *in;
1529
1530     if (line == 0)
1531         return;
1532
1533     in = input_file;
1534     c = *cptr;
1535     if (c == '\n')
1536     {
1537         ++lineno;
1538         if ((c = getc(in)) == EOF)
1539             return;
1540         write_input_lineno();
1541         putc_code(code_file, c);
1542         last = c;
1543     }
1544     else
1545     {
1546         write_input_lineno();
1547         do
1548         {
1549             putc_code(code_file, c);
1550         }
1551         while ((c = *++cptr) != '\n');
1552         putc_code(code_file, c);
1553         last = '\n';
1554     }
1555
1556     while ((c = getc(in)) != EOF)
1557     {
1558         putc_code(code_file, c);
1559         last = c;
1560     }
1561
1562     if (last != '\n')
1563     {
1564         putc_code(code_file, '\n');
1565     }
1566     write_code_lineno(code_file);
1567 }
1568
1569 static void
1570 output_semantic_actions(void)
1571 {
1572     int c, last;
1573
1574     rewind(action_file);
1575     if ((c = getc(action_file)) == EOF)
1576         return;
1577
1578     last = c;
1579     putc_code(code_file, c);
1580     while ((c = getc(action_file)) != EOF)
1581     {
1582         putc_code(code_file, c);
1583         last = c;
1584     }
1585
1586     if (last != '\n')
1587     {
1588         putc_code(code_file, '\n');
1589     }
1590
1591     write_code_lineno(code_file);
1592 }
1593
1594 static void
1595 output_parse_decl(FILE * fp)
1596 {
1597     putc_code(fp, '\n');
1598     putl_code(fp, "/* compatibility with bison */\n");
1599     putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1600     putl_code(fp, "/* compatibility with FreeBSD */\n");
1601     putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1602     putl_code(fp,
1603               "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1604     putl_code(fp, "# else\n");
1605     putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1606     putl_code(fp, "# endif\n");
1607     putl_code(fp, "#else\n");
1608
1609     puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1610     if (!parse_param)
1611         puts_code(fp, "void");
1612     else
1613     {
1614         param *p;
1615         for (p = parse_param; p; p = p->next)
1616             fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1617                     p->next ? ", " : "");
1618     }
1619     putl_code(fp, ")\n");
1620
1621     putl_code(fp, "#endif\n");
1622 }
1623
1624 static void
1625 output_lex_decl(FILE * fp)
1626 {
1627     putc_code(fp, '\n');
1628     putl_code(fp, "/* Parameters sent to lex. */\n");
1629     putl_code(fp, "#ifdef YYLEX_PARAM\n");
1630     if (pure_parser)
1631     {
1632         putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1633 #if defined(YYBTYACC)
1634         if (locations)
1635         {
1636             putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
1637                       " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1638         }
1639         else
1640 #endif
1641         {
1642             putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1643                       " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1644         }
1645         putl_code(fp, "# else\n");
1646 #if defined(YYBTYACC)
1647         if (locations)
1648         {
1649             putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
1650                       " void * YYLEX_PARAM)\n");
1651         }
1652         else
1653 #endif
1654         {
1655             putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1656                       " void * YYLEX_PARAM)\n");
1657         }
1658         putl_code(fp, "# endif\n");
1659 #if defined(YYBTYACC)
1660         if (locations)
1661             putl_code(fp,
1662                       "# define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)\n");
1663         else
1664 #endif
1665             putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1666     }
1667     else
1668     {
1669         putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1670         putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1671     }
1672     putl_code(fp, "#else\n");
1673     if (pure_parser && lex_param)
1674     {
1675         param *p;
1676
1677 #if defined(YYBTYACC)
1678         if (locations)
1679             puts_code(fp,
1680                       "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc, ");
1681         else
1682 #endif
1683             puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1684         for (p = lex_param; p; p = p->next)
1685             fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1686                     p->next ? ", " : "");
1687         putl_code(fp, ")\n");
1688
1689 #if defined(YYBTYACC)
1690         if (locations)
1691             puts_code(fp, "# define YYLEX yylex(&yylval, &yylloc, ");
1692         else
1693 #endif
1694             puts_code(fp, "# define YYLEX yylex(&yylval, ");
1695         for (p = lex_param; p; p = p->next)
1696             fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1697         putl_code(fp, ")\n");
1698     }
1699     else if (pure_parser)
1700     {
1701 #if defined(YYBTYACC)
1702         if (locations)
1703         {
1704             putl_code(fp,
1705                       "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc)\n");
1706             putl_code(fp, "# define YYLEX yylex(&yylval, &yylloc)\n");
1707         }
1708         else
1709 #endif
1710         {
1711             putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1712             putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1713         }
1714     }
1715     else if (lex_param)
1716     {
1717         param *p;
1718
1719         puts_code(fp, "# define YYLEX_DECL() yylex(");
1720         for (p = lex_param; p; p = p->next)
1721             fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1722                     p->next ? ", " : "");
1723         putl_code(fp, ")\n");
1724
1725         puts_code(fp, "# define YYLEX yylex(");
1726         for (p = lex_param; p; p = p->next)
1727             fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1728         putl_code(fp, ")\n");
1729     }
1730     else
1731     {
1732         putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1733         putl_code(fp, "# define YYLEX yylex()\n");
1734     }
1735     putl_code(fp, "#endif\n");
1736 }
1737
1738 static void
1739 output_error_decl(FILE * fp)
1740 {
1741     param *p;
1742
1743     putc_code(fp, '\n');
1744     putl_code(fp, "/* Parameters sent to yyerror. */\n");
1745     putl_code(fp, "#ifndef YYERROR_DECL\n");
1746     puts_code(fp, "#define YYERROR_DECL() yyerror(");
1747 #if defined(YYBTYACC)
1748     if (locations)
1749         puts_code(fp, "YYLTYPE loc, ");
1750 #endif
1751     for (p = parse_param; p; p = p->next)
1752         fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
1753     putl_code(fp, "const char *s)\n");
1754     putl_code(fp, "#endif\n");
1755
1756     putl_code(fp, "#ifndef YYERROR_CALL\n");
1757     puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1758
1759 #if defined(YYBTYACC)
1760     if (locations)
1761         puts_code(fp, "yylloc, ");
1762 #endif
1763     for (p = parse_param; p; p = p->next)
1764         fprintf(fp, "%s, ", p->name);
1765
1766     putl_code(fp, "msg)\n");
1767     putl_code(fp, "#endif\n");
1768 }
1769
1770 #if defined(YYBTYACC)
1771 static void
1772 output_yydestruct_decl(FILE * fp)
1773 {
1774     putc_code(fp, '\n');
1775     putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
1776 #if defined(YYBTYACC)
1777     if (locations)
1778         putl_code(fp,
1779                   "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val, YYLTYPE *loc)\n");
1780     else
1781 #endif
1782         putl_code(fp,
1783                   "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val)\n");
1784     putl_code(fp, "#endif\n");
1785     putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
1786 #if defined(YYBTYACC)
1787     if (locations)
1788         putl_code(fp,
1789                   "#define YYDESTRUCT_CALL(msg, psymb, val, loc) yydestruct(msg, psymb, val, loc)\n");
1790     else
1791 #endif
1792         putl_code(fp,
1793                   "#define YYDESTRUCT_CALL(msg, psymb, val) yydestruct(msg, psymb, val)\n");
1794     putl_code(fp, "#endif\n");
1795 }
1796
1797 static void
1798 output_yydestruct_impl(void)
1799 {
1800     int i;
1801     char *s, *destructor_code;
1802
1803     putc_code(code_file, '\n');
1804     putl_code(code_file, "/* Release memory associated with symbol. */\n");
1805     putl_code(code_file, "#if ! defined YYDESTRUCT_IS_DECLARED\n");
1806     putl_code(code_file, "static void\n");
1807     putl_code(code_file, "YYDESTRUCT_DECL()\n");
1808     putl_code(code_file, "{\n");
1809     putl_code(code_file, "    switch (psymb)\n");
1810     putl_code(code_file, "    {\n");
1811     for (i = 2; i < nsyms; ++i)
1812     {
1813         if ((destructor_code = symbol_destructor[i]) != NULL)
1814         {
1815             ++outline;
1816             fprintf(code_file, "\tcase %d:\n", symbol_pval[i]);
1817             /* comprehend the number of lines in the destructor code */
1818             for (s = destructor_code; (s = strchr(s, '\n')) != NULL; s++)
1819                 ++outline;
1820             puts_code(code_file, destructor_code);
1821             putc_code(code_file, '\n');
1822             putl_code(code_file, "\tbreak;\n");
1823             write_code_lineno(code_file);
1824             FREE(destructor_code);
1825         }
1826     }
1827     putl_code(code_file, "    }\n");
1828     putl_code(code_file, "}\n");
1829     putl_code(code_file, "#define YYDESTRUCT_IS_DECLARED 1\n");
1830     putl_code(code_file, "#endif\n");
1831
1832     DO_FREE(symbol_destructor);
1833 }
1834 #endif
1835
1836 static void
1837 free_itemsets(void)
1838 {
1839     core *cp, *next;
1840
1841     FREE(state_table);
1842     for (cp = first_state; cp; cp = next)
1843     {
1844         next = cp->next;
1845         FREE(cp);
1846     }
1847 }
1848
1849 static void
1850 free_shifts(void)
1851 {
1852     shifts *sp, *next;
1853
1854     FREE(shift_table);
1855     for (sp = first_shift; sp; sp = next)
1856     {
1857         next = sp->next;
1858         FREE(sp);
1859     }
1860 }
1861
1862 static void
1863 free_reductions(void)
1864 {
1865     reductions *rp, *next;
1866
1867     FREE(reduction_table);
1868     for (rp = first_reduction; rp; rp = next)
1869     {
1870         next = rp->next;
1871         FREE(rp);
1872     }
1873 }
1874
1875 static void
1876 output_externs(FILE * fp, const char *const section[])
1877 {
1878     int i;
1879     const char *s;
1880
1881     for (i = 0; (s = section[i]) != 0; ++i)
1882     {
1883         /* prefix non-blank lines that don't start with
1884            C pre-processor directives with 'extern ' */
1885         if (*s && (*s != '#'))
1886             fputs("extern\t", fp);
1887         if (fp == code_file)
1888             ++outline;
1889         fprintf(fp, "%s\n", s);
1890     }
1891 }
1892
1893 void
1894 output(void)
1895 {
1896     FILE *fp;
1897
1898     free_itemsets();
1899     free_shifts();
1900     free_reductions();
1901
1902 #if defined(YYBTYACC)
1903     output_backtracking_parser(output_file);
1904     if (rflag)
1905         output_backtracking_parser(code_file);
1906 #endif
1907
1908     if (iflag)
1909     {
1910         write_code_lineno(code_file);
1911         ++outline;
1912         fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1913         fp = externs_file;
1914     }
1915     else
1916         fp = code_file;
1917
1918     output_prefix(fp);
1919     output_pure_parser(fp);
1920     output_stored_text(fp);
1921     output_stype(fp);
1922 #if defined(YYBTYACC)
1923     if (locations)
1924         output_ltype(fp);
1925 #endif
1926     output_parse_decl(fp);
1927     output_lex_decl(fp);
1928     output_error_decl(fp);
1929 #if defined(YYBTYACC)
1930     if (destructor)
1931         output_yydestruct_decl(fp);
1932 #endif
1933     if (iflag || !rflag)
1934     {
1935         write_section(fp, xdecls);
1936     }
1937
1938     if (iflag)
1939     {
1940         output_externs(externs_file, global_vars);
1941         if (!pure_parser)
1942             output_externs(externs_file, impure_vars);
1943     }
1944
1945     if (iflag)
1946     {
1947         if (dflag)
1948         {
1949             ++outline;
1950             fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1951         }
1952         else
1953             output_defines(externs_file);
1954     }
1955     else
1956     {
1957         putc_code(code_file, '\n');
1958         output_defines(code_file);
1959     }
1960
1961     if (dflag)
1962     {
1963         start_defines_file();
1964         output_defines(defines_file);
1965         end_defines_file();
1966     }
1967
1968     output_rule_data();
1969     output_yydefred();
1970 #if defined(YYBTYACC)
1971     output_accessing_symbols();
1972 #endif
1973     output_actions();
1974     free_parser();
1975     output_debug();
1976     if (rflag)
1977     {
1978         write_section(code_file, xdecls);
1979         output_YYINT_typedef(code_file);
1980         write_section(code_file, tables);
1981     }
1982     write_section(code_file, global_vars);
1983     if (!pure_parser)
1984     {
1985         write_section(code_file, impure_vars);
1986     }
1987     write_section(code_file, hdr_defs);
1988     if (!pure_parser)
1989     {
1990         write_section(code_file, hdr_vars);
1991     }
1992     output_trailing_text();
1993 #if defined(YYBTYACC)
1994     if (destructor)
1995         output_yydestruct_impl();
1996 #endif
1997     write_section(code_file, body_1);
1998     if (pure_parser)
1999     {
2000         write_section(code_file, body_vars);
2001     }
2002     write_section(code_file, body_2);
2003     output_semantic_actions();
2004     write_section(code_file, trailer);
2005 }
2006
2007 #ifdef NO_LEAKS
2008 void
2009 output_leaks(void)
2010 {
2011     DO_FREE(tally);
2012     DO_FREE(width);
2013     DO_FREE(order);
2014 }
2015 #endif