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