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