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