Imported Upstream version 20100216
[platform/upstream/byacc.git] / output.c
1 /* $Id: output.c,v 1.24 2010/02/17 01:48:22 tom Exp $ */
2
3 #include "defs.h"
4
5 #define StaticOrR       (rflag ? "" : "static ")
6
7 static int nvectors;
8 static int nentries;
9 static Value_t **froms;
10 static Value_t **tos;
11 static Value_t *tally;
12 static Value_t *width;
13 static Value_t *state_count;
14 static Value_t *order;
15 static Value_t *base;
16 static Value_t *pos;
17 static int maxtable;
18 static Value_t *table;
19 static Value_t *check;
20 static int lowzero;
21 static int high;
22
23 static void
24 write_char(FILE * out, int c)
25 {
26     if (c == '\n')
27         ++outline;
28     putc(c, out);
29 }
30
31 static void
32 write_code_lineno(FILE * out)
33 {
34     if (!lflag)
35         fprintf(out, line_format, (outline++) + 1, code_file_name);
36 }
37
38 static void
39 write_input_lineno(FILE * out)
40 {
41     if (!lflag)
42     {
43         ++outline;
44         fprintf(out, line_format, lineno, input_file_name);
45     }
46 }
47
48 static void
49 define_prefixed(FILE * fp, const char *name)
50 {
51     ++outline;
52     fprintf(fp, "\n");
53
54     ++outline;
55     fprintf(fp, "#ifndef %s\n", name);
56
57     ++outline;
58     fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
59
60     ++outline;
61     fprintf(fp, "#endif /* %s */\n", name);
62 }
63
64 static void
65 output_prefix(FILE * fp)
66 {
67     if (symbol_prefix == NULL)
68     {
69         symbol_prefix = "yy";
70     }
71     else
72     {
73         define_prefixed(fp, "yyparse");
74         define_prefixed(fp, "yylex");
75         define_prefixed(fp, "yyerror");
76         define_prefixed(fp, "yychar");
77         define_prefixed(fp, "yyval");
78         define_prefixed(fp, "yylval");
79         define_prefixed(fp, "yydebug");
80         define_prefixed(fp, "yynerrs");
81         define_prefixed(fp, "yyerrflag");
82         define_prefixed(fp, "yylhs");
83         define_prefixed(fp, "yylen");
84         define_prefixed(fp, "yydefred");
85         define_prefixed(fp, "yydgoto");
86         define_prefixed(fp, "yysindex");
87         define_prefixed(fp, "yyrindex");
88         define_prefixed(fp, "yygindex");
89         define_prefixed(fp, "yytable");
90         define_prefixed(fp, "yycheck");
91         define_prefixed(fp, "yyname");
92         define_prefixed(fp, "yyrule");
93     }
94     ++outline;
95     fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
96 }
97
98 static void
99 output_newline(void)
100 {
101     if (!rflag)
102         ++outline;
103     putc('\n', output_file);
104 }
105
106 static void
107 output_line(const char *value)
108 {
109     fputs(value, output_file);
110     output_newline();
111 }
112
113 static void
114 output_int(int value)
115 {
116     fprintf(output_file, "%5d,", value);
117 }
118
119 static void
120 start_int_table(const char *name, int value)
121 {
122     int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
123
124     if (need < 6)
125         need = 6;
126     fprintf(output_file,
127             "%sconst short %s%s[] = {%*d,",
128             StaticOrR, symbol_prefix, name, need, value);
129 }
130
131 static void
132 start_str_table(const char *name)
133 {
134     fprintf(output_file,
135             "%sconst char *%s%s[] = {",
136             StaticOrR, "yy", name);
137     output_newline();
138 }
139
140 static void
141 end_table(void)
142 {
143     output_newline();
144     output_line("};");
145 }
146
147 static void
148 output_rule_data(void)
149 {
150     int i;
151     int j;
152
153     start_int_table("lhs", symbol_value[start_symbol]);
154
155     j = 10;
156     for (i = 3; i < nrules; i++)
157     {
158         if (j >= 10)
159         {
160             output_newline();
161             j = 1;
162         }
163         else
164             ++j;
165
166         output_int(symbol_value[rlhs[i]]);
167     }
168     end_table();
169
170     start_int_table("len", 2);
171
172     j = 10;
173     for (i = 3; i < nrules; i++)
174     {
175         if (j >= 10)
176         {
177             output_newline();
178             j = 1;
179         }
180         else
181             j++;
182
183         output_int(rrhs[i + 1] - rrhs[i] - 1);
184     }
185     end_table();
186 }
187
188 static void
189 output_yydefred(void)
190 {
191     int i, j;
192
193     start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
194
195     j = 10;
196     for (i = 1; i < nstates; i++)
197     {
198         if (j < 10)
199             ++j;
200         else
201         {
202             output_newline();
203             j = 1;
204         }
205
206         output_int((defred[i] ? defred[i] - 2 : 0));
207     }
208
209     end_table();
210 }
211
212 static void
213 token_actions(void)
214 {
215     int i, j;
216     Value_t shiftcount, reducecount;
217     int max, min;
218     Value_t *actionrow, *r, *s;
219     action *p;
220
221     actionrow = NEW2(2 * ntokens, Value_t);
222     for (i = 0; i < nstates; ++i)
223     {
224         if (parser[i])
225         {
226             for (j = 0; j < 2 * ntokens; ++j)
227                 actionrow[j] = 0;
228
229             shiftcount = 0;
230             reducecount = 0;
231             for (p = parser[i]; p; p = p->next)
232             {
233                 if (p->suppressed == 0)
234                 {
235                     if (p->action_code == SHIFT)
236                     {
237                         ++shiftcount;
238                         actionrow[p->symbol] = p->number;
239                     }
240                     else if (p->action_code == REDUCE && p->number != defred[i])
241                     {
242                         ++reducecount;
243                         actionrow[p->symbol + ntokens] = p->number;
244                     }
245                 }
246             }
247
248             tally[i] = shiftcount;
249             tally[nstates + i] = reducecount;
250             width[i] = 0;
251             width[nstates + i] = 0;
252             if (shiftcount > 0)
253             {
254                 froms[i] = r = NEW2(shiftcount, Value_t);
255                 tos[i] = s = NEW2(shiftcount, Value_t);
256                 min = MAXSHORT;
257                 max = 0;
258                 for (j = 0; j < ntokens; ++j)
259                 {
260                     if (actionrow[j])
261                     {
262                         if (min > symbol_value[j])
263                             min = symbol_value[j];
264                         if (max < symbol_value[j])
265                             max = symbol_value[j];
266                         *r++ = symbol_value[j];
267                         *s++ = actionrow[j];
268                     }
269                 }
270                 width[i] = (Value_t) (max - min + 1);
271             }
272             if (reducecount > 0)
273             {
274                 froms[nstates + i] = r = NEW2(reducecount, Value_t);
275                 tos[nstates + i] = s = NEW2(reducecount, Value_t);
276                 min = MAXSHORT;
277                 max = 0;
278                 for (j = 0; j < ntokens; ++j)
279                 {
280                     if (actionrow[ntokens + j])
281                     {
282                         if (min > symbol_value[j])
283                             min = symbol_value[j];
284                         if (max < symbol_value[j])
285                             max = symbol_value[j];
286                         *r++ = symbol_value[j];
287                         *s++ = (Value_t) (actionrow[ntokens + j] - 2);
288                     }
289                 }
290                 width[nstates + i] = (Value_t) (max - min + 1);
291             }
292         }
293     }
294     FREE(actionrow);
295 }
296
297 static int
298 default_goto(int symbol)
299 {
300     int i;
301     int m;
302     int n;
303     int default_state;
304     int max;
305
306     m = goto_map[symbol];
307     n = goto_map[symbol + 1];
308
309     if (m == n)
310         return (0);
311
312     for (i = 0; i < nstates; i++)
313         state_count[i] = 0;
314
315     for (i = m; i < n; i++)
316         state_count[to_state[i]]++;
317
318     max = 0;
319     default_state = 0;
320     for (i = 0; i < nstates; i++)
321     {
322         if (state_count[i] > max)
323         {
324             max = state_count[i];
325             default_state = i;
326         }
327     }
328
329     return (default_state);
330 }
331
332 static void
333 save_column(int symbol, int default_state)
334 {
335     int i;
336     int m;
337     int n;
338     Value_t *sp;
339     Value_t *sp1;
340     Value_t *sp2;
341     Value_t count;
342     int symno;
343
344     m = goto_map[symbol];
345     n = goto_map[symbol + 1];
346
347     count = 0;
348     for (i = m; i < n; i++)
349     {
350         if (to_state[i] != default_state)
351             ++count;
352     }
353     if (count == 0)
354         return;
355
356     symno = symbol_value[symbol] + 2 * nstates;
357
358     froms[symno] = sp1 = sp = NEW2(count, Value_t);
359     tos[symno] = sp2 = NEW2(count, Value_t);
360
361     for (i = m; i < n; i++)
362     {
363         if (to_state[i] != default_state)
364         {
365             *sp1++ = from_state[i];
366             *sp2++ = to_state[i];
367         }
368     }
369
370     tally[symno] = count;
371     width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
372 }
373
374 static void
375 goto_actions(void)
376 {
377     int i, j, k;
378
379     state_count = NEW2(nstates, Value_t);
380
381     k = default_goto(start_symbol + 1);
382     start_int_table("dgoto", k);
383     save_column(start_symbol + 1, k);
384
385     j = 10;
386     for (i = start_symbol + 2; i < nsyms; i++)
387     {
388         if (j >= 10)
389         {
390             output_newline();
391             j = 1;
392         }
393         else
394             ++j;
395
396         k = default_goto(i);
397         output_int(k);
398         save_column(i, k);
399     }
400
401     end_table();
402     FREE(state_count);
403 }
404
405 static void
406 sort_actions(void)
407 {
408     Value_t i;
409     int j;
410     int k;
411     int t;
412     int w;
413
414     order = NEW2(nvectors, Value_t);
415     nentries = 0;
416
417     for (i = 0; i < nvectors; i++)
418     {
419         if (tally[i] > 0)
420         {
421             t = tally[i];
422             w = width[i];
423             j = nentries - 1;
424
425             while (j >= 0 && (width[order[j]] < w))
426                 j--;
427
428             while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
429                 j--;
430
431             for (k = nentries - 1; k > j; k--)
432                 order[k + 1] = order[k];
433
434             order[j + 1] = i;
435             nentries++;
436         }
437     }
438 }
439
440 /*  The function matching_vector determines if the vector specified by  */
441 /*  the input parameter matches a previously considered vector.  The    */
442 /*  test at the start of the function checks if the vector represents   */
443 /*  a row of shifts over terminal symbols or a row of reductions, or a  */
444 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not */
445 /*  check if a column of shifts over a nonterminal symbols matches a    */
446 /*  previously considered vector.  Because of the nature of LR parsing  */
447 /*  tables, no two columns can match.  Therefore, the only possible     */
448 /*  match would be between a row and a column.  Such matches are        */
449 /*  unlikely.  Therefore, to save time, no attempt is made to see if a  */
450 /*  column matches a previously considered vector.                      */
451 /*                                                                      */
452 /*  Matching_vector is poorly designed.  The test could easily be made  */
453 /*  faster.  Also, it depends on the vectors being in a specific        */
454 /*  order.                                                              */
455
456 static int
457 matching_vector(int vector)
458 {
459     int i;
460     int j;
461     int k;
462     int t;
463     int w;
464     int match;
465     int prev;
466
467     i = order[vector];
468     if (i >= 2 * nstates)
469         return (-1);
470
471     t = tally[i];
472     w = width[i];
473
474     for (prev = vector - 1; prev >= 0; prev--)
475     {
476         j = order[prev];
477         if (width[j] != w || tally[j] != t)
478             return (-1);
479
480         match = 1;
481         for (k = 0; match && k < t; k++)
482         {
483             if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
484                 match = 0;
485         }
486
487         if (match)
488             return (j);
489     }
490
491     return (-1);
492 }
493
494 static int
495 pack_vector(int vector)
496 {
497     int i, j, k, l;
498     int t;
499     int loc;
500     int ok;
501     Value_t *from;
502     Value_t *to;
503     int newmax;
504
505     i = order[vector];
506     t = tally[i];
507     assert(t);
508
509     from = froms[i];
510     to = tos[i];
511
512     j = lowzero - from[0];
513     for (k = 1; k < t; ++k)
514         if (lowzero - from[k] > j)
515             j = lowzero - from[k];
516     for (;; ++j)
517     {
518         if (j == 0)
519             continue;
520         ok = 1;
521         for (k = 0; ok && k < t; k++)
522         {
523             loc = j + from[k];
524             if (loc >= maxtable - 1)
525             {
526                 if (loc >= MAXTABLE - 1)
527                     fatal("maximum table size exceeded");
528
529                 newmax = maxtable;
530                 do
531                 {
532                     newmax += 200;
533                 }
534                 while (newmax <= loc);
535                 table = (Value_t *) REALLOC(table, (unsigned)newmax * sizeof(Value_t));
536                 if (table == 0)
537                     no_space();
538                 check = (Value_t *) REALLOC(check, (unsigned)newmax * sizeof(Value_t));
539                 if (check == 0)
540                     no_space();
541                 for (l = maxtable; l < newmax; ++l)
542                 {
543                     table[l] = 0;
544                     check[l] = -1;
545                 }
546                 maxtable = newmax;
547             }
548
549             if (check[loc] != -1)
550                 ok = 0;
551         }
552         for (k = 0; ok && k < vector; k++)
553         {
554             if (pos[k] == j)
555                 ok = 0;
556         }
557         if (ok)
558         {
559             for (k = 0; k < t; k++)
560             {
561                 loc = j + from[k];
562                 table[loc] = to[k];
563                 check[loc] = from[k];
564                 if (loc > high)
565                     high = loc;
566             }
567
568             while (check[lowzero] != -1)
569                 ++lowzero;
570
571             return (j);
572         }
573     }
574 }
575
576 static void
577 pack_table(void)
578 {
579     int i;
580     Value_t place;
581     int state;
582
583     base = NEW2(nvectors, Value_t);
584     pos = NEW2(nentries, Value_t);
585
586     maxtable = 1000;
587     table = NEW2(maxtable, Value_t);
588     check = NEW2(maxtable, Value_t);
589
590     lowzero = 0;
591     high = 0;
592
593     for (i = 0; i < maxtable; i++)
594         check[i] = -1;
595
596     for (i = 0; i < nentries; i++)
597     {
598         state = matching_vector(i);
599
600         if (state < 0)
601             place = (Value_t) pack_vector(i);
602         else
603             place = base[state];
604
605         pos[i] = place;
606         base[order[i]] = place;
607     }
608
609     for (i = 0; i < nvectors; i++)
610     {
611         if (froms[i])
612             FREE(froms[i]);
613         if (tos[i])
614             FREE(tos[i]);
615     }
616
617     FREE(froms);
618     FREE(tos);
619     FREE(pos);
620 }
621
622 static void
623 output_base(void)
624 {
625     int i, j;
626
627     start_int_table("sindex", base[0]);
628
629     j = 10;
630     for (i = 1; i < nstates; i++)
631     {
632         if (j >= 10)
633         {
634             output_newline();
635             j = 1;
636         }
637         else
638             ++j;
639
640         output_int(base[i]);
641     }
642
643     end_table();
644
645     start_int_table("rindex", base[nstates]);
646
647     j = 10;
648     for (i = nstates + 1; i < 2 * nstates; i++)
649     {
650         if (j >= 10)
651         {
652             output_newline();
653             j = 1;
654         }
655         else
656             ++j;
657
658         output_int(base[i]);
659     }
660
661     end_table();
662
663     start_int_table("gindex", base[2 * nstates]);
664
665     j = 10;
666     for (i = 2 * nstates + 1; i < nvectors - 1; i++)
667     {
668         if (j >= 10)
669         {
670             output_newline();
671             j = 1;
672         }
673         else
674             ++j;
675
676         output_int(base[i]);
677     }
678
679     end_table();
680     FREE(base);
681 }
682
683 static void
684 output_table(void)
685 {
686     int i;
687     int j;
688
689     ++outline;
690     fprintf(code_file, "#define YYTABLESIZE %d\n", high);
691     start_int_table("table", table[0]);
692
693     j = 10;
694     for (i = 1; i <= high; i++)
695     {
696         if (j >= 10)
697         {
698             output_newline();
699             j = 1;
700         }
701         else
702             ++j;
703
704         output_int(table[i]);
705     }
706
707     end_table();
708     FREE(table);
709 }
710
711 static void
712 output_check(void)
713 {
714     int i;
715     int j;
716
717     start_int_table("check", check[0]);
718
719     j = 10;
720     for (i = 1; i <= high; i++)
721     {
722         if (j >= 10)
723         {
724             output_newline();
725             j = 1;
726         }
727         else
728             ++j;
729
730         output_int(check[i]);
731     }
732
733     end_table();
734     FREE(check);
735 }
736
737 static void
738 output_actions(void)
739 {
740     nvectors = 2 * nstates + nvars;
741
742     froms = NEW2(nvectors, Value_t *);
743     tos = NEW2(nvectors, Value_t *);
744     tally = NEW2(nvectors, Value_t);
745     width = NEW2(nvectors, Value_t);
746
747     token_actions();
748     FREE(lookaheads);
749     FREE(LA);
750     FREE(LAruleno);
751     FREE(accessing_symbol);
752
753     goto_actions();
754     FREE(goto_map + ntokens);
755     FREE(from_state);
756     FREE(to_state);
757
758     sort_actions();
759     pack_table();
760     output_base();
761     output_table();
762     output_check();
763 }
764
765 static int
766 is_C_identifier(char *name)
767 {
768     char *s;
769     int c;
770
771     s = name;
772     c = *s;
773     if (c == '"')
774     {
775         c = *++s;
776         if (!isalpha(c) && c != '_' && c != '$')
777             return (0);
778         while ((c = *++s) != '"')
779         {
780             if (!isalnum(c) && c != '_' && c != '$')
781                 return (0);
782         }
783         return (1);
784     }
785
786     if (!isalpha(c) && c != '_' && c != '$')
787         return (0);
788     while ((c = *++s) != 0)
789     {
790         if (!isalnum(c) && c != '_' && c != '$')
791             return (0);
792     }
793     return (1);
794 }
795
796 static void
797 output_defines(void)
798 {
799     int c, i;
800     char *s;
801
802     for (i = 2; i < ntokens; ++i)
803     {
804         s = symbol_name[i];
805         if (is_C_identifier(s))
806         {
807             fprintf(code_file, "#define ");
808             if (dflag)
809                 fprintf(defines_file, "#define ");
810             c = *s;
811             if (c == '"')
812             {
813                 while ((c = *++s) != '"')
814                 {
815                     putc(c, code_file);
816                     if (dflag)
817                         putc(c, defines_file);
818                 }
819             }
820             else
821             {
822                 do
823                 {
824                     putc(c, code_file);
825                     if (dflag)
826                         putc(c, defines_file);
827                 }
828                 while ((c = *++s) != 0);
829             }
830             ++outline;
831             fprintf(code_file, " %d\n", symbol_value[i]);
832             if (dflag)
833                 fprintf(defines_file, " %d\n", symbol_value[i]);
834         }
835     }
836
837     ++outline;
838     fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
839
840     if (dflag && unionized)
841     {
842         rewind(union_file);
843         while ((c = getc(union_file)) != EOF)
844             putc(c, defines_file);
845         fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
846                 symbol_prefix);
847     }
848 }
849
850 static void
851 output_stored_text(void)
852 {
853     int c;
854     FILE *in, *out;
855
856     rewind(text_file);
857     if (text_file == NULL)
858         open_error("text_file");
859     in = text_file;
860     if ((c = getc(in)) == EOF)
861         return;
862     out = code_file;
863     write_char(out, c);
864     while ((c = getc(in)) != EOF)
865     {
866         write_char(out, c);
867     }
868     write_code_lineno(out);
869 }
870
871 static void
872 output_debug(void)
873 {
874     int i, j, k, max;
875     const char **symnam;
876     const char *s;
877
878     ++outline;
879     fprintf(code_file, "#define YYFINAL %d\n", final_state);
880
881     outline += 3;
882     fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", tflag);
883
884     if (rflag)
885     {
886         fprintf(output_file, "#ifndef YYDEBUG\n");
887         fprintf(output_file, "#define YYDEBUG %d\n", tflag);
888         fprintf(output_file, "#endif\n");
889     }
890
891     max = 0;
892     for (i = 2; i < ntokens; ++i)
893         if (symbol_value[i] > max)
894             max = symbol_value[i];
895
896     ++outline;
897     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
898
899     symnam = (const char **)MALLOC((unsigned)(max + 1) * sizeof(char *));
900     if (symnam == 0)
901         no_space();
902
903     /* Note that it is  not necessary to initialize the element         */
904     /* symnam[max].                                                     */
905     for (i = 0; i < max; ++i)
906         symnam[i] = 0;
907     for (i = ntokens - 1; i >= 2; --i)
908         symnam[symbol_value[i]] = symbol_name[i];
909     symnam[0] = "end-of-file";
910
911     output_line("#if YYDEBUG");
912
913     start_str_table("name");
914     j = 80;
915     for (i = 0; i <= max; ++i)
916     {
917         if ((s = symnam[i]) != 0)
918         {
919             if (s[0] == '"')
920             {
921                 k = 7;
922                 while (*++s != '"')
923                 {
924                     ++k;
925                     if (*s == '\\')
926                     {
927                         k += 2;
928                         if (*++s == '\\')
929                             ++k;
930                     }
931                 }
932                 j += k;
933                 if (j > 80)
934                 {
935                     output_newline();
936                     j = k;
937                 }
938                 fprintf(output_file, "\"\\\"");
939                 s = symnam[i];
940                 while (*++s != '"')
941                 {
942                     if (*s == '\\')
943                     {
944                         fprintf(output_file, "\\\\");
945                         if (*++s == '\\')
946                             fprintf(output_file, "\\\\");
947                         else
948                             putc(*s, output_file);
949                     }
950                     else
951                         putc(*s, output_file);
952                 }
953                 fprintf(output_file, "\\\"\",");
954             }
955             else if (s[0] == '\'')
956             {
957                 if (s[1] == '"')
958                 {
959                     j += 7;
960                     if (j > 80)
961                     {
962                         output_newline();
963                         j = 7;
964                     }
965                     fprintf(output_file, "\"'\\\"'\",");
966                 }
967                 else
968                 {
969                     k = 5;
970                     while (*++s != '\'')
971                     {
972                         ++k;
973                         if (*s == '\\')
974                         {
975                             k += 2;
976                             if (*++s == '\\')
977                                 ++k;
978                         }
979                     }
980                     j += k;
981                     if (j > 80)
982                     {
983                         output_newline();
984                         j = k;
985                     }
986                     fprintf(output_file, "\"'");
987                     s = symnam[i];
988                     while (*++s != '\'')
989                     {
990                         if (*s == '\\')
991                         {
992                             fprintf(output_file, "\\\\");
993                             if (*++s == '\\')
994                                 fprintf(output_file, "\\\\");
995                             else
996                                 putc(*s, output_file);
997                         }
998                         else
999                             putc(*s, output_file);
1000                     }
1001                     fprintf(output_file, "'\",");
1002                 }
1003             }
1004             else
1005             {
1006                 k = (int)strlen(s) + 3;
1007                 j += k;
1008                 if (j > 80)
1009                 {
1010                     output_newline();
1011                     j = k;
1012                 }
1013                 putc('"', output_file);
1014                 do
1015                 {
1016                     putc(*s, output_file);
1017                 }
1018                 while (*++s);
1019                 fprintf(output_file, "\",");
1020             }
1021         }
1022         else
1023         {
1024             j += 2;
1025             if (j > 80)
1026             {
1027                 output_newline();
1028                 j = 2;
1029             }
1030             fprintf(output_file, "0,");
1031         }
1032     }
1033     end_table();
1034     FREE(symnam);
1035
1036     start_str_table("rule");
1037     for (i = 2; i < nrules; ++i)
1038     {
1039         fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1040         for (j = rrhs[i]; ritem[j] > 0; ++j)
1041         {
1042             s = symbol_name[ritem[j]];
1043             if (s[0] == '"')
1044             {
1045                 fprintf(output_file, " \\\"");
1046                 while (*++s != '"')
1047                 {
1048                     if (*s == '\\')
1049                     {
1050                         if (s[1] == '\\')
1051                             fprintf(output_file, "\\\\\\\\");
1052                         else
1053                             fprintf(output_file, "\\\\%c", s[1]);
1054                         ++s;
1055                     }
1056                     else
1057                         putc(*s, output_file);
1058                 }
1059                 fprintf(output_file, "\\\"");
1060             }
1061             else if (s[0] == '\'')
1062             {
1063                 if (s[1] == '"')
1064                     fprintf(output_file, " '\\\"'");
1065                 else if (s[1] == '\\')
1066                 {
1067                     if (s[2] == '\\')
1068                         fprintf(output_file, " '\\\\\\\\");
1069                     else
1070                         fprintf(output_file, " '\\\\%c", s[2]);
1071                     s += 2;
1072                     while (*++s != '\'')
1073                         putc(*s, output_file);
1074                     putc('\'', output_file);
1075                 }
1076                 else
1077                     fprintf(output_file, " '%c'", s[1]);
1078             }
1079             else
1080                 fprintf(output_file, " %s", s);
1081         }
1082         fprintf(output_file, "\",");
1083         output_newline();
1084     }
1085
1086     end_table();
1087     output_line("#endif");
1088 }
1089
1090 static void
1091 output_pure_parser(void)
1092 {
1093     outline += 3;
1094     fprintf(code_file, "\n#define YYPURE %d\n\n", pure_parser);
1095 }
1096
1097 static void
1098 output_stype(void)
1099 {
1100     if (!unionized && ntags == 0)
1101     {
1102         outline += 3;
1103         fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1104     }
1105 }
1106
1107 static void
1108 output_trailing_text(void)
1109 {
1110     int c, last;
1111     FILE *in, *out;
1112
1113     if (line == 0)
1114         return;
1115
1116     in = input_file;
1117     out = code_file;
1118     c = *cptr;
1119     if (c == '\n')
1120     {
1121         ++lineno;
1122         if ((c = getc(in)) == EOF)
1123             return;
1124         write_input_lineno(out);
1125         write_char(out, c);
1126         last = c;
1127     }
1128     else
1129     {
1130         write_input_lineno(out);
1131         do
1132         {
1133             putc(c, out);
1134         }
1135         while ((c = *++cptr) != '\n');
1136         write_char(out, c);
1137         last = '\n';
1138     }
1139
1140     while ((c = getc(in)) != EOF)
1141     {
1142         write_char(out, c);
1143         last = c;
1144     }
1145
1146     if (last != '\n')
1147     {
1148         write_char(out, '\n');
1149     }
1150     write_code_lineno(out);
1151 }
1152
1153 static void
1154 output_semantic_actions(void)
1155 {
1156     int c, last;
1157     FILE *out;
1158
1159     rewind(action_file);
1160     if ((c = getc(action_file)) == EOF)
1161         return;
1162
1163     out = code_file;
1164     last = c;
1165     write_char(out, c);
1166     while ((c = getc(action_file)) != EOF)
1167     {
1168         write_char(out, c);
1169         last = c;
1170     }
1171
1172     if (last != '\n')
1173     {
1174         write_char(out, '\n');
1175     }
1176
1177     write_code_lineno(out);
1178 }
1179
1180 static void
1181 free_itemsets(void)
1182 {
1183     core *cp, *next;
1184
1185     FREE(state_table);
1186     for (cp = first_state; cp; cp = next)
1187     {
1188         next = cp->next;
1189         FREE(cp);
1190     }
1191 }
1192
1193 static void
1194 free_shifts(void)
1195 {
1196     shifts *sp, *next;
1197
1198     FREE(shift_table);
1199     for (sp = first_shift; sp; sp = next)
1200     {
1201         next = sp->next;
1202         FREE(sp);
1203     }
1204 }
1205
1206 static void
1207 free_reductions(void)
1208 {
1209     reductions *rp, *next;
1210
1211     FREE(reduction_table);
1212     for (rp = first_reduction; rp; rp = next)
1213     {
1214         next = rp->next;
1215         FREE(rp);
1216     }
1217 }
1218
1219 void
1220 output(void)
1221 {
1222     free_itemsets();
1223     free_shifts();
1224     free_reductions();
1225     output_prefix(output_file);
1226     write_section(xdecls);
1227     output_stored_text();
1228     output_defines();
1229     output_rule_data();
1230     output_yydefred();
1231     output_actions();
1232     free_parser();
1233     output_debug();
1234     output_stype();
1235     if (rflag)
1236     {
1237         output_prefix(code_file);
1238         write_section(xdecls);
1239         write_section(tables);
1240     }
1241     write_section(hdr_defs);
1242     output_pure_parser();
1243     if (!pure_parser)
1244     {
1245         write_section(hdr_vars);
1246     }
1247     output_trailing_text();
1248     write_section(body_1);
1249     if (pure_parser)
1250     {
1251         write_section(body_vars);
1252     }
1253     write_section(body_2);
1254     output_semantic_actions();
1255     write_section(trailer);
1256 }
1257
1258 #ifdef NO_LEAKS
1259 void
1260 output_leaks(void)
1261 {
1262     DO_FREE(tally);
1263     DO_FREE(width);
1264     DO_FREE(order);
1265 }
1266 #endif