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