output.c revision 272655
1/* $Id: output.c,v 1.74 2014/10/05 23:21:09 tom Exp $ */
2
3#include "defs.h"
4
5#define StaticOrR	(rflag ? "" : "static ")
6#define CountLine(fp)   (!rflag || ((fp) == code_file))
7
8#if defined(YYBTYACC)
9#define PER_STATE 3
10#else
11#define PER_STATE 2
12#endif
13
14static int nvectors;
15static int nentries;
16static Value_t **froms;
17static Value_t **tos;
18#if defined(YYBTYACC)
19static Value_t *conflicts = NULL;
20static Value_t nconflicts = 0;
21#endif
22static Value_t *tally;
23static Value_t *width;
24static Value_t *state_count;
25static Value_t *order;
26static Value_t *base;
27static Value_t *pos;
28static int maxtable;
29static Value_t *table;
30static Value_t *check;
31static int lowzero;
32static long high;
33
34static void
35putc_code(FILE * fp, int c)
36{
37    if ((c == '\n') && (fp == code_file))
38	++outline;
39    putc(c, fp);
40}
41
42static void
43putl_code(FILE * fp, const char *s)
44{
45    if (fp == code_file)
46	++outline;
47    fputs(s, fp);
48}
49
50static void
51puts_code(FILE * fp, const char *s)
52{
53    fputs(s, fp);
54}
55
56static void
57puts_param_types(FILE * fp, param * list, int more)
58{
59    param *p;
60
61    if (list != 0)
62    {
63	for (p = list; p; p = p->next)
64	{
65	    size_t len_type = strlen(p->type);
66	    fprintf(fp, "%s%s%s%s%s", p->type,
67		    (((len_type != 0) && (p->type[len_type - 1] == '*'))
68		     ? ""
69		     : " "),
70		    p->name, p->type2,
71		    ((more || p->next) ? ", " : ""));
72	}
73    }
74    else
75    {
76	if (!more)
77	    fprintf(fp, "void");
78    }
79}
80
81static void
82puts_param_names(FILE * fp, param * list, int more)
83{
84    param *p;
85
86    for (p = list; p; p = p->next)
87    {
88	fprintf(fp, "%s%s", p->name,
89		((more || p->next) ? ", " : ""));
90    }
91}
92
93static void
94write_code_lineno(FILE * fp)
95{
96    if (!lflag && (fp == code_file))
97    {
98	++outline;
99	fprintf(fp, line_format, outline + 1, code_file_name);
100    }
101}
102
103static void
104write_input_lineno(void)
105{
106    if (!lflag)
107    {
108	++outline;
109	fprintf(code_file, line_format, lineno, input_file_name);
110    }
111}
112
113static void
114define_prefixed(FILE * fp, const char *name)
115{
116    int bump_line = CountLine(fp);
117    if (bump_line)
118	++outline;
119    fprintf(fp, "\n");
120
121    if (bump_line)
122	++outline;
123    fprintf(fp, "#ifndef %s\n", name);
124
125    if (bump_line)
126	++outline;
127    fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
128
129    if (bump_line)
130	++outline;
131    fprintf(fp, "#endif /* %s */\n", name);
132}
133
134static void
135output_prefix(FILE * fp)
136{
137    if (symbol_prefix == NULL)
138    {
139	symbol_prefix = "yy";
140    }
141    else
142    {
143	define_prefixed(fp, "yyparse");
144	define_prefixed(fp, "yylex");
145	define_prefixed(fp, "yyerror");
146	define_prefixed(fp, "yychar");
147	define_prefixed(fp, "yyval");
148	define_prefixed(fp, "yylval");
149	define_prefixed(fp, "yydebug");
150	define_prefixed(fp, "yynerrs");
151	define_prefixed(fp, "yyerrflag");
152	define_prefixed(fp, "yylhs");
153	define_prefixed(fp, "yylen");
154	define_prefixed(fp, "yydefred");
155#if defined(YYBTYACC)
156	define_prefixed(fp, "yystos");
157#endif
158	define_prefixed(fp, "yydgoto");
159	define_prefixed(fp, "yysindex");
160	define_prefixed(fp, "yyrindex");
161	define_prefixed(fp, "yygindex");
162	define_prefixed(fp, "yytable");
163	define_prefixed(fp, "yycheck");
164	define_prefixed(fp, "yyname");
165	define_prefixed(fp, "yyrule");
166#if defined(YYBTYACC)
167	if (locations)
168	{
169	    define_prefixed(fp, "yyloc");
170	    define_prefixed(fp, "yylloc");
171	}
172	putc_code(fp, '\n');
173	putl_code(fp, "#if YYBTYACC\n");
174
175	define_prefixed(fp, "yycindex");
176	define_prefixed(fp, "yyctable");
177
178	putc_code(fp, '\n');
179	putl_code(fp, "#endif /* YYBTYACC */\n");
180	putc_code(fp, '\n');
181#endif
182    }
183    if (CountLine(fp))
184	++outline;
185    fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
186}
187
188static void
189output_newline(void)
190{
191    if (!rflag)
192	++outline;
193    putc('\n', output_file);
194}
195
196static void
197output_line(const char *value)
198{
199    fputs(value, output_file);
200    output_newline();
201}
202
203static void
204output_int(int value)
205{
206    fprintf(output_file, "%5d,", value);
207}
208
209static void
210start_int_table(const char *name, int value)
211{
212    int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
213
214    if (need < 6)
215	need = 6;
216    fprintf(output_file,
217	    "%sconst YYINT %s%s[] = {%*d,",
218	    StaticOrR, symbol_prefix, name, need, value);
219}
220
221static void
222start_str_table(const char *name)
223{
224    fprintf(output_file,
225	    "%sconst char *const %s%s[] = {",
226	    StaticOrR, symbol_prefix, name);
227    output_newline();
228}
229
230static void
231end_table(void)
232{
233    output_newline();
234    output_line("};");
235}
236
237static void
238output_YYINT_typedef(FILE * fp)
239{
240    /* generate the type used to index the various parser tables */
241    if (CountLine(fp))
242	++outline;
243    fprintf(fp, "typedef %s YYINT;\n", CONCAT1("", YYINT));
244}
245
246static void
247output_rule_data(void)
248{
249    int i;
250    int j;
251
252    output_YYINT_typedef(output_file);
253
254    start_int_table("lhs", symbol_value[start_symbol]);
255
256    j = 10;
257    for (i = 3; i < nrules; i++)
258    {
259	if (j >= 10)
260	{
261	    output_newline();
262	    j = 1;
263	}
264	else
265	    ++j;
266
267	output_int(symbol_value[rlhs[i]]);
268    }
269    end_table();
270
271    start_int_table("len", 2);
272
273    j = 10;
274    for (i = 3; i < nrules; i++)
275    {
276	if (j >= 10)
277	{
278	    output_newline();
279	    j = 1;
280	}
281	else
282	    j++;
283
284	output_int(rrhs[i + 1] - rrhs[i] - 1);
285    }
286    end_table();
287}
288
289static void
290output_yydefred(void)
291{
292    int i, j;
293
294    start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
295
296    j = 10;
297    for (i = 1; i < nstates; i++)
298    {
299	if (j < 10)
300	    ++j;
301	else
302	{
303	    output_newline();
304	    j = 1;
305	}
306
307	output_int((defred[i] ? defred[i] - 2 : 0));
308    }
309
310    end_table();
311}
312
313#if defined(YYBTYACC)
314static void
315output_accessing_symbols(void)
316{
317    int i, j;
318    int *translate;
319
320    if (nstates != 0)
321    {
322	translate = TMALLOC(int, nstates);
323	NO_SPACE(translate);
324
325	for (i = 0; i < nstates; ++i)
326	{
327	    int gsymb = accessing_symbol[i];
328
329	    translate[i] = symbol_pval[gsymb];
330	}
331
332	/* yystos[] may be unused, depending on compile-time defines */
333	start_int_table("stos", translate[0]);
334
335	j = 10;
336	for (i = 1; i < nstates; ++i)
337	{
338	    if (j < 10)
339		++j;
340	    else
341	    {
342		output_newline();
343		j = 1;
344	    }
345
346	    output_int(translate[i]);
347	}
348
349	end_table();
350	FREE(translate);
351    }
352}
353
354static Value_t
355find_conflict_base(int cbase)
356{
357    int i, j;
358
359    for (i = 0; i < cbase; i++)
360    {
361	for (j = 0; j + cbase < nconflicts; j++)
362	{
363	    if (conflicts[i + j] != conflicts[cbase + j])
364		break;
365	}
366	if (j + cbase >= nconflicts)
367	    break;
368    }
369    return (Value_t) i;
370}
371#endif
372
373static void
374token_actions(void)
375{
376    int i, j;
377    Value_t shiftcount, reducecount;
378#if defined(YYBTYACC)
379    Value_t conflictcount = 0;
380    Value_t csym = -1;
381    Value_t cbase = 0;
382#endif
383    int max, min;
384    Value_t *actionrow, *r, *s;
385    action *p;
386
387    actionrow = NEW2(PER_STATE * ntokens, Value_t);
388    for (i = 0; i < nstates; ++i)
389    {
390	if (parser[i])
391	{
392	    for (j = 0; j < PER_STATE * ntokens; ++j)
393		actionrow[j] = 0;
394
395	    shiftcount = 0;
396	    reducecount = 0;
397#if defined(YYBTYACC)
398	    if (backtrack)
399	    {
400		conflictcount = 0;
401		csym = -1;
402		cbase = nconflicts;
403	    }
404#endif
405	    for (p = parser[i]; p; p = p->next)
406	    {
407#if defined(YYBTYACC)
408		if (backtrack)
409		{
410		    if (csym != -1 && csym != p->symbol)
411		    {
412			conflictcount++;
413			conflicts[nconflicts++] = -1;
414			j = find_conflict_base(cbase);
415			actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
416			if (j == cbase)
417			{
418			    cbase = nconflicts;
419			}
420			else
421			{
422			    if (conflicts[cbase] == -1)
423				cbase++;
424			    nconflicts = cbase;
425			}
426			csym = -1;
427		    }
428		}
429#endif
430		if (p->suppressed == 0)
431		{
432		    if (p->action_code == SHIFT)
433		    {
434			++shiftcount;
435			actionrow[p->symbol] = p->number;
436		    }
437		    else if (p->action_code == REDUCE && p->number != defred[i])
438		    {
439			++reducecount;
440			actionrow[p->symbol + ntokens] = p->number;
441		    }
442		}
443#if defined(YYBTYACC)
444		else if (backtrack && p->suppressed == 1)
445		{
446		    csym = p->symbol;
447		    if (p->action_code == SHIFT)
448		    {
449			conflicts[nconflicts++] = p->number;
450		    }
451		    else if (p->action_code == REDUCE && p->number != defred[i])
452		    {
453			if (cbase == nconflicts)
454			{
455			    if (cbase)
456				cbase--;
457			    else
458				conflicts[nconflicts++] = -1;
459			}
460			conflicts[nconflicts++] = (Value_t) (p->number - 2);
461		    }
462		}
463#endif
464	    }
465#if defined(YYBTYACC)
466	    if (backtrack && csym != -1)
467	    {
468		conflictcount++;
469		conflicts[nconflicts++] = -1;
470		j = find_conflict_base(cbase);
471		actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
472		if (j == cbase)
473		{
474		    cbase = nconflicts;
475		}
476		else
477		{
478		    if (conflicts[cbase] == -1)
479			cbase++;
480		    nconflicts = cbase;
481		}
482	    }
483#endif
484
485	    tally[i] = shiftcount;
486	    tally[nstates + i] = reducecount;
487#if defined(YYBTYACC)
488	    if (backtrack)
489		tally[2 * nstates + i] = conflictcount;
490#endif
491	    width[i] = 0;
492	    width[nstates + i] = 0;
493#if defined(YYBTYACC)
494	    if (backtrack)
495		width[2 * nstates + i] = 0;
496#endif
497	    if (shiftcount > 0)
498	    {
499		froms[i] = r = NEW2(shiftcount, Value_t);
500		tos[i] = s = NEW2(shiftcount, Value_t);
501		min = MAXYYINT;
502		max = 0;
503		for (j = 0; j < ntokens; ++j)
504		{
505		    if (actionrow[j])
506		    {
507			if (min > symbol_value[j])
508			    min = symbol_value[j];
509			if (max < symbol_value[j])
510			    max = symbol_value[j];
511			*r++ = symbol_value[j];
512			*s++ = actionrow[j];
513		    }
514		}
515		width[i] = (Value_t) (max - min + 1);
516	    }
517	    if (reducecount > 0)
518	    {
519		froms[nstates + i] = r = NEW2(reducecount, Value_t);
520		tos[nstates + i] = s = NEW2(reducecount, Value_t);
521		min = MAXYYINT;
522		max = 0;
523		for (j = 0; j < ntokens; ++j)
524		{
525		    if (actionrow[ntokens + j])
526		    {
527			if (min > symbol_value[j])
528			    min = symbol_value[j];
529			if (max < symbol_value[j])
530			    max = symbol_value[j];
531			*r++ = symbol_value[j];
532			*s++ = (Value_t) (actionrow[ntokens + j] - 2);
533		    }
534		}
535		width[nstates + i] = (Value_t) (max - min + 1);
536	    }
537#if defined(YYBTYACC)
538	    if (backtrack && conflictcount > 0)
539	    {
540		froms[2 * nstates + i] = r = NEW2(conflictcount, Value_t);
541		tos[2 * nstates + i] = s = NEW2(conflictcount, Value_t);
542		min = MAXYYINT;
543		max = 0;
544		for (j = 0; j < ntokens; ++j)
545		{
546		    if (actionrow[2 * ntokens + j])
547		    {
548			if (min > symbol_value[j])
549			    min = symbol_value[j];
550			if (max < symbol_value[j])
551			    max = symbol_value[j];
552			*r++ = symbol_value[j];
553			*s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
554		    }
555		}
556		width[2 * nstates + i] = (Value_t) (max - min + 1);
557	    }
558#endif
559	}
560    }
561    FREE(actionrow);
562}
563
564static int
565default_goto(int symbol)
566{
567    int i;
568    int m;
569    int n;
570    int default_state;
571    int max;
572
573    m = goto_map[symbol];
574    n = goto_map[symbol + 1];
575
576    if (m == n)
577	return (0);
578
579    for (i = 0; i < nstates; i++)
580	state_count[i] = 0;
581
582    for (i = m; i < n; i++)
583	state_count[to_state[i]]++;
584
585    max = 0;
586    default_state = 0;
587    for (i = 0; i < nstates; i++)
588    {
589	if (state_count[i] > max)
590	{
591	    max = state_count[i];
592	    default_state = i;
593	}
594    }
595
596    return (default_state);
597}
598
599static void
600save_column(int symbol, int default_state)
601{
602    int i;
603    int m;
604    int n;
605    Value_t *sp;
606    Value_t *sp1;
607    Value_t *sp2;
608    Value_t count;
609    int symno;
610
611    m = goto_map[symbol];
612    n = goto_map[symbol + 1];
613
614    count = 0;
615    for (i = m; i < n; i++)
616    {
617	if (to_state[i] != default_state)
618	    ++count;
619    }
620    if (count == 0)
621	return;
622
623    symno = symbol_value[symbol] + PER_STATE * nstates;
624
625    froms[symno] = sp1 = sp = NEW2(count, Value_t);
626    tos[symno] = sp2 = NEW2(count, Value_t);
627
628    for (i = m; i < n; i++)
629    {
630	if (to_state[i] != default_state)
631	{
632	    *sp1++ = from_state[i];
633	    *sp2++ = to_state[i];
634	}
635    }
636
637    tally[symno] = count;
638    width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
639}
640
641static void
642goto_actions(void)
643{
644    int i, j, k;
645
646    state_count = NEW2(nstates, Value_t);
647
648    k = default_goto(start_symbol + 1);
649    start_int_table("dgoto", k);
650    save_column(start_symbol + 1, k);
651
652    j = 10;
653    for (i = start_symbol + 2; i < nsyms; i++)
654    {
655	if (j >= 10)
656	{
657	    output_newline();
658	    j = 1;
659	}
660	else
661	    ++j;
662
663	k = default_goto(i);
664	output_int(k);
665	save_column(i, k);
666    }
667
668    end_table();
669    FREE(state_count);
670}
671
672static void
673sort_actions(void)
674{
675    Value_t i;
676    int j;
677    int k;
678    int t;
679    int w;
680
681    order = NEW2(nvectors, Value_t);
682    nentries = 0;
683
684    for (i = 0; i < nvectors; i++)
685    {
686	if (tally[i] > 0)
687	{
688	    t = tally[i];
689	    w = width[i];
690	    j = nentries - 1;
691
692	    while (j >= 0 && (width[order[j]] < w))
693		j--;
694
695	    while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
696		j--;
697
698	    for (k = nentries - 1; k > j; k--)
699		order[k + 1] = order[k];
700
701	    order[j + 1] = i;
702	    nentries++;
703	}
704    }
705}
706
707/*  The function matching_vector determines if the vector specified by	*/
708/*  the input parameter matches a previously considered	vector.  The	*/
709/*  test at the start of the function checks if the vector represents	*/
710/*  a row of shifts over terminal symbols or a row of reductions, or a	*/
711/*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
712/*  check if a column of shifts over a nonterminal symbols matches a	*/
713/*  previously considered vector.  Because of the nature of LR parsing	*/
714/*  tables, no two columns can match.  Therefore, the only possible	*/
715/*  match would be between a row and a column.  Such matches are	*/
716/*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
717/*  column matches a previously considered vector.			*/
718/*									*/
719/*  Matching_vector is poorly designed.  The test could easily be made	*/
720/*  faster.  Also, it depends on the vectors being in a specific	*/
721/*  order.								*/
722#if defined(YYBTYACC)
723/*									*/
724/*  Not really any point in checking for matching conflicts -- it is    */
725/*  extremely unlikely to occur, and conflicts are (hopefully) rare.    */
726#endif
727
728static int
729matching_vector(int vector)
730{
731    int i;
732    int j;
733    int k;
734    int t;
735    int w;
736    int match;
737    int prev;
738
739    i = order[vector];
740    if (i >= 2 * nstates)
741	return (-1);
742
743    t = tally[i];
744    w = width[i];
745
746    for (prev = vector - 1; prev >= 0; prev--)
747    {
748	j = order[prev];
749	if (width[j] != w || tally[j] != t)
750	    return (-1);
751
752	match = 1;
753	for (k = 0; match && k < t; k++)
754	{
755	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
756		match = 0;
757	}
758
759	if (match)
760	    return (j);
761    }
762
763    return (-1);
764}
765
766static int
767pack_vector(int vector)
768{
769    int i, j, k, l;
770    int t;
771    int loc;
772    int ok;
773    Value_t *from;
774    Value_t *to;
775    int newmax;
776
777    i = order[vector];
778    t = tally[i];
779    assert(t);
780
781    from = froms[i];
782    to = tos[i];
783
784    j = lowzero - from[0];
785    for (k = 1; k < t; ++k)
786	if (lowzero - from[k] > j)
787	    j = lowzero - from[k];
788    for (;; ++j)
789    {
790	if (j == 0)
791	    continue;
792	ok = 1;
793	for (k = 0; ok && k < t; k++)
794	{
795	    loc = j + from[k];
796	    if (loc >= maxtable - 1)
797	    {
798		if (loc >= MAXTABLE - 1)
799		    fatal("maximum table size exceeded");
800
801		newmax = maxtable;
802		do
803		{
804		    newmax += 200;
805		}
806		while (newmax <= loc);
807
808		table = TREALLOC(Value_t, table, newmax);
809		NO_SPACE(table);
810
811		check = TREALLOC(Value_t, check, newmax);
812		NO_SPACE(check);
813
814		for (l = maxtable; l < newmax; ++l)
815		{
816		    table[l] = 0;
817		    check[l] = -1;
818		}
819		maxtable = newmax;
820	    }
821
822	    if (check[loc] != -1)
823		ok = 0;
824	}
825	for (k = 0; ok && k < vector; k++)
826	{
827	    if (pos[k] == j)
828		ok = 0;
829	}
830	if (ok)
831	{
832	    for (k = 0; k < t; k++)
833	    {
834		loc = j + from[k];
835		table[loc] = to[k];
836		check[loc] = from[k];
837		if (loc > high)
838		    high = loc;
839	    }
840
841	    while (check[lowzero] != -1)
842		++lowzero;
843
844	    return (j);
845	}
846    }
847}
848
849static void
850pack_table(void)
851{
852    int i;
853    Value_t place;
854    int state;
855
856    base = NEW2(nvectors, Value_t);
857    pos = NEW2(nentries, Value_t);
858
859    maxtable = 1000;
860    table = NEW2(maxtable, Value_t);
861    check = NEW2(maxtable, Value_t);
862
863    lowzero = 0;
864    high = 0;
865
866    for (i = 0; i < maxtable; i++)
867	check[i] = -1;
868
869    for (i = 0; i < nentries; i++)
870    {
871	state = matching_vector(i);
872
873	if (state < 0)
874	    place = (Value_t) pack_vector(i);
875	else
876	    place = base[state];
877
878	pos[i] = place;
879	base[order[i]] = place;
880    }
881
882    for (i = 0; i < nvectors; i++)
883    {
884	if (froms[i])
885	    FREE(froms[i]);
886	if (tos[i])
887	    FREE(tos[i]);
888    }
889
890    DO_FREE(froms);
891    DO_FREE(tos);
892    DO_FREE(tally);
893    DO_FREE(width);
894    DO_FREE(pos);
895}
896
897static void
898output_base(void)
899{
900    int i, j;
901
902    start_int_table("sindex", base[0]);
903
904    j = 10;
905    for (i = 1; i < nstates; i++)
906    {
907	if (j >= 10)
908	{
909	    output_newline();
910	    j = 1;
911	}
912	else
913	    ++j;
914
915	output_int(base[i]);
916    }
917
918    end_table();
919
920    start_int_table("rindex", base[nstates]);
921
922    j = 10;
923    for (i = nstates + 1; i < 2 * nstates; i++)
924    {
925	if (j >= 10)
926	{
927	    output_newline();
928	    j = 1;
929	}
930	else
931	    ++j;
932
933	output_int(base[i]);
934    }
935
936    end_table();
937
938#if defined(YYBTYACC)
939    output_line("#if YYBTYACC");
940    start_int_table("cindex", base[2 * nstates]);
941
942    j = 10;
943    for (i = 2 * nstates + 1; i < 3 * nstates; i++)
944    {
945	if (j >= 10)
946	{
947	    output_newline();
948	    j = 1;
949	}
950	else
951	    ++j;
952
953	output_int(base[i]);
954    }
955
956    end_table();
957    output_line("#endif");
958#endif
959
960    start_int_table("gindex", base[PER_STATE * nstates]);
961
962    j = 10;
963    for (i = PER_STATE * nstates + 1; i < nvectors - 1; i++)
964    {
965	if (j >= 10)
966	{
967	    output_newline();
968	    j = 1;
969	}
970	else
971	    ++j;
972
973	output_int(base[i]);
974    }
975
976    end_table();
977    FREE(base);
978}
979
980static void
981output_table(void)
982{
983    int i;
984    int j;
985
986    if (high >= MAXYYINT)
987    {
988	fprintf(stderr, "YYTABLESIZE: %ld\n", high);
989	fprintf(stderr, "Table is longer than %d elements.\n", MAXYYINT);
990	done(1);
991    }
992
993    ++outline;
994    fprintf(code_file, "#define YYTABLESIZE %ld\n", high);
995    start_int_table("table", table[0]);
996
997    j = 10;
998    for (i = 1; i <= high; i++)
999    {
1000	if (j >= 10)
1001	{
1002	    output_newline();
1003	    j = 1;
1004	}
1005	else
1006	    ++j;
1007
1008	output_int(table[i]);
1009    }
1010
1011    end_table();
1012    FREE(table);
1013}
1014
1015static void
1016output_check(void)
1017{
1018    int i;
1019    int j;
1020
1021    start_int_table("check", check[0]);
1022
1023    j = 10;
1024    for (i = 1; i <= high; i++)
1025    {
1026	if (j >= 10)
1027	{
1028	    output_newline();
1029	    j = 1;
1030	}
1031	else
1032	    ++j;
1033
1034	output_int(check[i]);
1035    }
1036
1037    end_table();
1038    FREE(check);
1039}
1040
1041#if defined(YYBTYACC)
1042static void
1043output_ctable(void)
1044{
1045    int i;
1046    int j;
1047    int limit = (conflicts != 0) ? nconflicts : 0;
1048
1049    if (limit < high)
1050	limit = (int)high;
1051
1052    output_line("#if YYBTYACC");
1053    start_int_table("ctable", conflicts ? conflicts[0] : -1);
1054
1055    j = 10;
1056    for (i = 1; i < limit; i++)
1057    {
1058	if (j >= 10)
1059	{
1060	    output_newline();
1061	    j = 1;
1062	}
1063	else
1064	    ++j;
1065
1066	output_int((conflicts != 0 && i < nconflicts) ? conflicts[i] : -1);
1067    }
1068
1069    if (conflicts)
1070	FREE(conflicts);
1071
1072    end_table();
1073    output_line("#endif");
1074}
1075#endif
1076
1077static void
1078output_actions(void)
1079{
1080    nvectors = PER_STATE * nstates + nvars;
1081
1082    froms = NEW2(nvectors, Value_t *);
1083    tos = NEW2(nvectors, Value_t *);
1084    tally = NEW2(nvectors, Value_t);
1085    width = NEW2(nvectors, Value_t);
1086
1087#if defined(YYBTYACC)
1088    if (backtrack && (SRtotal + RRtotal) != 0)
1089	conflicts = NEW2(4 * (SRtotal + RRtotal), Value_t);
1090#endif
1091
1092    token_actions();
1093    FREE(lookaheads);
1094    FREE(LA);
1095    FREE(LAruleno);
1096    FREE(accessing_symbol);
1097
1098    goto_actions();
1099    FREE(goto_base);
1100    FREE(from_state);
1101    FREE(to_state);
1102
1103    sort_actions();
1104    pack_table();
1105    output_base();
1106    output_table();
1107    output_check();
1108#if defined(YYBTYACC)
1109    output_ctable();
1110#endif
1111}
1112
1113static int
1114is_C_identifier(char *name)
1115{
1116    char *s;
1117    int c;
1118
1119    s = name;
1120    c = *s;
1121    if (c == '"')
1122    {
1123	c = *++s;
1124	if (!isalpha(c) && c != '_' && c != '$')
1125	    return (0);
1126	while ((c = *++s) != '"')
1127	{
1128	    if (!isalnum(c) && c != '_' && c != '$')
1129		return (0);
1130	}
1131	return (1);
1132    }
1133
1134    if (!isalpha(c) && c != '_' && c != '$')
1135	return (0);
1136    while ((c = *++s) != 0)
1137    {
1138	if (!isalnum(c) && c != '_' && c != '$')
1139	    return (0);
1140    }
1141    return (1);
1142}
1143
1144#if USE_HEADER_GUARDS
1145static void
1146start_defines_file(void)
1147{
1148    fprintf(defines_file, "#ifndef _%s_defines_h_\n", symbol_prefix);
1149    fprintf(defines_file, "#define _%s_defines_h_\n\n", symbol_prefix);
1150}
1151
1152static void
1153end_defines_file(void)
1154{
1155    fprintf(defines_file, "\n#endif /* _%s_defines_h_ */\n", symbol_prefix);
1156}
1157#else
1158#define start_defines_file()	/* nothing */
1159#define end_defines_file()	/* nothing */
1160#endif
1161
1162static void
1163output_defines(FILE * fp)
1164{
1165    int c, i;
1166    char *s;
1167
1168    for (i = 2; i < ntokens; ++i)
1169    {
1170	s = symbol_name[i];
1171	if (is_C_identifier(s) && (!sflag || *s != '"'))
1172	{
1173	    fprintf(fp, "#define ");
1174	    c = *s;
1175	    if (c == '"')
1176	    {
1177		while ((c = *++s) != '"')
1178		{
1179		    putc(c, fp);
1180		}
1181	    }
1182	    else
1183	    {
1184		do
1185		{
1186		    putc(c, fp);
1187		}
1188		while ((c = *++s) != 0);
1189	    }
1190	    if (fp == code_file)
1191		++outline;
1192	    fprintf(fp, " %d\n", symbol_value[i]);
1193	}
1194    }
1195
1196    if (fp == code_file)
1197	++outline;
1198    if (fp != defines_file || iflag)
1199	fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
1200
1201    if (fp == defines_file || (iflag && !dflag))
1202    {
1203	if (unionized)
1204	{
1205	    if (union_file != 0)
1206	    {
1207		rewind(union_file);
1208		while ((c = getc(union_file)) != EOF)
1209		    putc_code(fp, c);
1210	    }
1211	    fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
1212	}
1213    }
1214}
1215
1216static void
1217output_stored_text(FILE * fp)
1218{
1219    int c;
1220    FILE *in;
1221
1222    rewind(text_file);
1223    if (text_file == NULL)
1224	open_error("text_file");
1225    in = text_file;
1226    if ((c = getc(in)) == EOF)
1227	return;
1228    putc_code(fp, c);
1229    while ((c = getc(in)) != EOF)
1230    {
1231	putc_code(fp, c);
1232    }
1233    write_code_lineno(fp);
1234}
1235
1236static void
1237output_debug(void)
1238{
1239    int i, j, k, max, maxtok;
1240    const char **symnam;
1241    const char *s;
1242
1243    ++outline;
1244    fprintf(code_file, "#define YYFINAL %d\n", final_state);
1245
1246    putl_code(code_file, "#ifndef YYDEBUG\n");
1247    ++outline;
1248    fprintf(code_file, "#define YYDEBUG %d\n", tflag);
1249    putl_code(code_file, "#endif\n");
1250
1251    if (rflag)
1252    {
1253	fprintf(output_file, "#ifndef YYDEBUG\n");
1254	fprintf(output_file, "#define YYDEBUG %d\n", tflag);
1255	fprintf(output_file, "#endif\n");
1256    }
1257
1258    maxtok = 0;
1259    for (i = 0; i < ntokens; ++i)
1260	if (symbol_value[i] > maxtok)
1261	    maxtok = symbol_value[i];
1262
1263    /* symbol_value[$accept] = -1         */
1264    /* symbol_value[<goal>]  = 0          */
1265    /* remaining non-terminals start at 1 */
1266    max = maxtok;
1267    for (i = ntokens; i < nsyms; ++i)
1268	if (((maxtok + 1) + (symbol_value[i] + 1)) > max)
1269	    max = (maxtok + 1) + (symbol_value[i] + 1);
1270
1271    ++outline;
1272    fprintf(code_file, "#define YYMAXTOKEN %d\n", maxtok);
1273
1274    ++outline;
1275    fprintf(code_file, "#define YYUNDFTOKEN %d\n", max + 1);
1276
1277    ++outline;
1278    fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
1279	    "YYUNDFTOKEN : (a))\n");
1280
1281    symnam = TMALLOC(const char *, max + 2);
1282    NO_SPACE(symnam);
1283
1284    /* Note that it is not necessary to initialize the element          */
1285    /* symnam[max].                                                     */
1286#if defined(YYBTYACC)
1287    for (i = 0; i < max; ++i)
1288	symnam[i] = 0;
1289    for (i = nsyms - 1; i >= 0; --i)
1290	symnam[symbol_pval[i]] = symbol_name[i];
1291    symnam[max + 1] = "illegal-symbol";
1292#else
1293    for (i = 0; i <= max; ++i)
1294	symnam[i] = 0;
1295    for (i = ntokens - 1; i >= 2; --i)
1296	symnam[symbol_value[i]] = symbol_name[i];
1297    symnam[0] = "end-of-file";
1298    symnam[max + 1] = "illegal-symbol";
1299#endif
1300
1301    /*
1302     * bison's yytname[] array is roughly the same as byacc's yyname[] array.
1303     * The difference is that byacc does not predefine "$undefined".
1304     *
1305     * If the grammar declares "%token-table", define symbol "yytname" so
1306     * an application such as ntpd can build.
1307     */
1308    if (token_table)
1309    {
1310	output_line("#undef yytname");
1311	output_line("#define yytname yyname");
1312    }
1313    else
1314    {
1315	output_line("#if YYDEBUG");
1316    }
1317
1318    start_str_table("name");
1319    j = 80;
1320    for (i = 0; i <= max + 1; ++i)
1321    {
1322	if ((s = symnam[i]) != 0)
1323	{
1324	    if (s[0] == '"')
1325	    {
1326		k = 7;
1327		while (*++s != '"')
1328		{
1329		    ++k;
1330		    if (*s == '\\')
1331		    {
1332			k += 2;
1333			if (*++s == '\\')
1334			    ++k;
1335		    }
1336		}
1337		j += k;
1338		if (j > 80)
1339		{
1340		    output_newline();
1341		    j = k;
1342		}
1343		fprintf(output_file, "\"\\\"");
1344		s = symnam[i];
1345		while (*++s != '"')
1346		{
1347		    if (*s == '\\')
1348		    {
1349			fprintf(output_file, "\\\\");
1350			if (*++s == '\\')
1351			    fprintf(output_file, "\\\\");
1352			else
1353			    putc(*s, output_file);
1354		    }
1355		    else
1356			putc(*s, output_file);
1357		}
1358		fprintf(output_file, "\\\"\",");
1359	    }
1360	    else if (s[0] == '\'')
1361	    {
1362		if (s[1] == '"')
1363		{
1364		    j += 7;
1365		    if (j > 80)
1366		    {
1367			output_newline();
1368			j = 7;
1369		    }
1370		    fprintf(output_file, "\"'\\\"'\",");
1371		}
1372		else
1373		{
1374		    k = 5;
1375		    while (*++s != '\'')
1376		    {
1377			++k;
1378			if (*s == '\\')
1379			{
1380			    k += 2;
1381			    if (*++s == '\\')
1382				++k;
1383			}
1384		    }
1385		    j += k;
1386		    if (j > 80)
1387		    {
1388			output_newline();
1389			j = k;
1390		    }
1391		    fprintf(output_file, "\"'");
1392		    s = symnam[i];
1393		    while (*++s != '\'')
1394		    {
1395			if (*s == '\\')
1396			{
1397			    fprintf(output_file, "\\\\");
1398			    if (*++s == '\\')
1399				fprintf(output_file, "\\\\");
1400			    else
1401				putc(*s, output_file);
1402			}
1403			else
1404			    putc(*s, output_file);
1405		    }
1406		    fprintf(output_file, "'\",");
1407		}
1408	    }
1409	    else
1410	    {
1411		k = (int)strlen(s) + 3;
1412		j += k;
1413		if (j > 80)
1414		{
1415		    output_newline();
1416		    j = k;
1417		}
1418		putc('"', output_file);
1419		do
1420		{
1421		    putc(*s, output_file);
1422		}
1423		while (*++s);
1424		fprintf(output_file, "\",");
1425	    }
1426	}
1427	else
1428	{
1429	    j += 2;
1430	    if (j > 80)
1431	    {
1432		output_newline();
1433		j = 2;
1434	    }
1435	    fprintf(output_file, "0,");
1436	}
1437    }
1438    end_table();
1439    FREE(symnam);
1440
1441    if (token_table)
1442	output_line("#if YYDEBUG");
1443    start_str_table("rule");
1444    for (i = 2; i < nrules; ++i)
1445    {
1446	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1447	for (j = rrhs[i]; ritem[j] > 0; ++j)
1448	{
1449	    s = symbol_name[ritem[j]];
1450	    if (s[0] == '"')
1451	    {
1452		fprintf(output_file, " \\\"");
1453		while (*++s != '"')
1454		{
1455		    if (*s == '\\')
1456		    {
1457			if (s[1] == '\\')
1458			    fprintf(output_file, "\\\\\\\\");
1459			else
1460			    fprintf(output_file, "\\\\%c", s[1]);
1461			++s;
1462		    }
1463		    else
1464			putc(*s, output_file);
1465		}
1466		fprintf(output_file, "\\\"");
1467	    }
1468	    else if (s[0] == '\'')
1469	    {
1470		if (s[1] == '"')
1471		    fprintf(output_file, " '\\\"'");
1472		else if (s[1] == '\\')
1473		{
1474		    if (s[2] == '\\')
1475			fprintf(output_file, " '\\\\\\\\");
1476		    else
1477			fprintf(output_file, " '\\\\%c", s[2]);
1478		    s += 2;
1479		    while (*++s != '\'')
1480			putc(*s, output_file);
1481		    putc('\'', output_file);
1482		}
1483		else
1484		    fprintf(output_file, " '%c'", s[1]);
1485	    }
1486	    else
1487		fprintf(output_file, " %s", s);
1488	}
1489	fprintf(output_file, "\",");
1490	output_newline();
1491    }
1492
1493    end_table();
1494    output_line("#endif");
1495}
1496
1497#if defined(YYBTYACC)
1498static void
1499output_backtracking_parser(FILE * fp)
1500{
1501    putl_code(fp, "#undef YYBTYACC\n");
1502#if defined(YYBTYACC)
1503    if (backtrack)
1504    {
1505	putl_code(fp, "#define YYBTYACC 1\n");
1506	putl_code(fp,
1507		  "#define YYDEBUGSTR (yytrial ? YYPREFIX \"debug(trial)\" : YYPREFIX \"debug\")\n");
1508    }
1509    else
1510#endif
1511    {
1512	putl_code(fp, "#define YYBTYACC 0\n");
1513	putl_code(fp, "#define YYDEBUGSTR YYPREFIX \"debug\"\n");
1514    }
1515}
1516#endif
1517
1518static void
1519output_pure_parser(FILE * fp)
1520{
1521    putc_code(fp, '\n');
1522
1523    if (fp == code_file)
1524	++outline;
1525    fprintf(fp, "#define YYPURE %d\n", pure_parser);
1526    putc_code(fp, '\n');
1527}
1528
1529static void
1530output_stype(FILE * fp)
1531{
1532    if (!unionized && ntags == 0)
1533    {
1534	putc_code(fp, '\n');
1535	putl_code(fp, "#if "
1536		  "! defined(YYSTYPE) && "
1537		  "! defined(YYSTYPE_IS_DECLARED)\n");
1538	putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
1539	putl_code(fp, "typedef int YYSTYPE;\n");
1540	putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
1541	putl_code(fp, "#endif\n");
1542    }
1543}
1544
1545#if defined(YYBTYACC)
1546static void
1547output_ltype(FILE * fp)
1548{
1549    putc_code(fp, '\n');
1550    putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
1551    putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
1552    putl_code(fp, "typedef struct YYLTYPE\n");
1553    putl_code(fp, "{\n");
1554    putl_code(fp, "    int first_line;\n");
1555    putl_code(fp, "    int first_column;\n");
1556    putl_code(fp, "    int last_line;\n");
1557    putl_code(fp, "    int last_column;\n");
1558    putl_code(fp, "} YYLTYPE;\n");
1559    putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
1560    putl_code(fp, "#endif\n");
1561}
1562#endif
1563
1564static void
1565output_trailing_text(void)
1566{
1567    int c, last;
1568    FILE *in;
1569
1570    if (line == 0)
1571	return;
1572
1573    in = input_file;
1574    c = *cptr;
1575    if (c == '\n')
1576    {
1577	++lineno;
1578	if ((c = getc(in)) == EOF)
1579	    return;
1580	write_input_lineno();
1581	putc_code(code_file, c);
1582	last = c;
1583    }
1584    else
1585    {
1586	write_input_lineno();
1587	do
1588	{
1589	    putc_code(code_file, c);
1590	}
1591	while ((c = *++cptr) != '\n');
1592	putc_code(code_file, c);
1593	last = '\n';
1594    }
1595
1596    while ((c = getc(in)) != EOF)
1597    {
1598	putc_code(code_file, c);
1599	last = c;
1600    }
1601
1602    if (last != '\n')
1603    {
1604	putc_code(code_file, '\n');
1605    }
1606    write_code_lineno(code_file);
1607}
1608
1609static void
1610output_semantic_actions(void)
1611{
1612    int c, last;
1613
1614    rewind(action_file);
1615    if ((c = getc(action_file)) == EOF)
1616	return;
1617
1618    last = c;
1619    putc_code(code_file, c);
1620    while ((c = getc(action_file)) != EOF)
1621    {
1622	putc_code(code_file, c);
1623	last = c;
1624    }
1625
1626    if (last != '\n')
1627    {
1628	putc_code(code_file, '\n');
1629    }
1630
1631    write_code_lineno(code_file);
1632}
1633
1634static void
1635output_parse_decl(FILE * fp)
1636{
1637    putc_code(fp, '\n');
1638    putl_code(fp, "/* compatibility with bison */\n");
1639    putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1640    putl_code(fp, "/* compatibility with FreeBSD */\n");
1641    putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1642    putl_code(fp,
1643	      "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1644    putl_code(fp, "# else\n");
1645    putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1646    putl_code(fp, "# endif\n");
1647    putl_code(fp, "#else\n");
1648
1649    puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1650    puts_param_types(fp, parse_param, 0);
1651    putl_code(fp, ")\n");
1652
1653    putl_code(fp, "#endif\n");
1654}
1655
1656static void
1657output_lex_decl(FILE * fp)
1658{
1659    putc_code(fp, '\n');
1660    putl_code(fp, "/* Parameters sent to lex. */\n");
1661    putl_code(fp, "#ifdef YYLEX_PARAM\n");
1662    if (pure_parser)
1663    {
1664	putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1665#if defined(YYBTYACC)
1666	if (locations)
1667	{
1668	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1669		      " YYLTYPE *yylloc,"
1670		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1671	}
1672	else
1673#endif
1674	{
1675	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1676		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1677	}
1678	putl_code(fp, "# else\n");
1679#if defined(YYBTYACC)
1680	if (locations)
1681	{
1682	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1683		      " YYLTYPE *yylloc,"
1684		      " void * YYLEX_PARAM)\n");
1685	}
1686	else
1687#endif
1688	{
1689	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1690		      " void * YYLEX_PARAM)\n");
1691	}
1692	putl_code(fp, "# endif\n");
1693#if defined(YYBTYACC)
1694	if (locations)
1695	    putl_code(fp,
1696		      "# define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)\n");
1697	else
1698#endif
1699	    putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1700    }
1701    else
1702    {
1703	putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1704	putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1705    }
1706    putl_code(fp, "#else\n");
1707    if (pure_parser && lex_param)
1708    {
1709#if defined(YYBTYACC)
1710	if (locations)
1711	    puts_code(fp,
1712		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc, ");
1713	else
1714#endif
1715	    puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1716	puts_param_types(fp, lex_param, 0);
1717	putl_code(fp, ")\n");
1718
1719#if defined(YYBTYACC)
1720	if (locations)
1721	    puts_code(fp, "# define YYLEX yylex(&yylval, &yylloc, ");
1722	else
1723#endif
1724	    puts_code(fp, "# define YYLEX yylex(&yylval, ");
1725	puts_param_names(fp, lex_param, 0);
1726	putl_code(fp, ")\n");
1727    }
1728    else if (pure_parser)
1729    {
1730#if defined(YYBTYACC)
1731	if (locations)
1732	{
1733	    putl_code(fp,
1734		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc)\n");
1735	    putl_code(fp, "# define YYLEX yylex(&yylval, &yylloc)\n");
1736	}
1737	else
1738#endif
1739	{
1740	    putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1741	    putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1742	}
1743    }
1744    else if (lex_param)
1745    {
1746	puts_code(fp, "# define YYLEX_DECL() yylex(");
1747	puts_param_types(fp, lex_param, 0);
1748	putl_code(fp, ")\n");
1749
1750	puts_code(fp, "# define YYLEX yylex(");
1751	puts_param_names(fp, lex_param, 0);
1752	putl_code(fp, ")\n");
1753    }
1754    else
1755    {
1756	putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1757	putl_code(fp, "# define YYLEX yylex()\n");
1758    }
1759    putl_code(fp, "#endif\n");
1760}
1761
1762static void
1763output_error_decl(FILE * fp)
1764{
1765    putc_code(fp, '\n');
1766    putl_code(fp, "/* Parameters sent to yyerror. */\n");
1767    putl_code(fp, "#ifndef YYERROR_DECL\n");
1768    puts_code(fp, "#define YYERROR_DECL() yyerror(");
1769#if defined(YYBTYACC)
1770    if (locations)
1771	puts_code(fp, "YYLTYPE loc, ");
1772#endif
1773    puts_param_types(fp, parse_param, 1);
1774    putl_code(fp, "const char *s)\n");
1775    putl_code(fp, "#endif\n");
1776
1777    putl_code(fp, "#ifndef YYERROR_CALL\n");
1778
1779    puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1780#if defined(YYBTYACC)
1781    if (locations)
1782	puts_code(fp, "yylloc, ");
1783#endif
1784    puts_param_names(fp, parse_param, 1);
1785    putl_code(fp, "msg)\n");
1786
1787    putl_code(fp, "#endif\n");
1788}
1789
1790#if defined(YYBTYACC)
1791static void
1792output_yydestruct_decl(FILE * fp)
1793{
1794    putc_code(fp, '\n');
1795    putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
1796
1797    puts_code(fp,
1798	      "#define YYDESTRUCT_DECL() "
1799	      "yydestruct(const char *msg, int psymb, YYSTYPE *val");
1800#if defined(YYBTYACC)
1801    if (locations)
1802	puts_code(fp, ", YYLTYPE *loc");
1803#endif
1804    if (parse_param)
1805    {
1806	puts_code(fp, ", ");
1807	puts_param_types(fp, parse_param, 0);
1808    }
1809    putl_code(fp, ")\n");
1810
1811    putl_code(fp, "#endif\n");
1812
1813    putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
1814
1815    puts_code(fp, "#define YYDESTRUCT_CALL(msg, psymb, val");
1816#if defined(YYBTYACC)
1817    if (locations)
1818	puts_code(fp, ", loc");
1819#endif
1820    puts_code(fp, ") yydestruct(msg, psymb, val");
1821#if defined(YYBTYACC)
1822    if (locations)
1823	puts_code(fp, ", loc");
1824#endif
1825    if (parse_param)
1826    {
1827	puts_code(fp, ", ");
1828	puts_param_names(fp, parse_param, 0);
1829    }
1830    putl_code(fp, ")\n");
1831
1832    putl_code(fp, "#endif\n");
1833}
1834
1835static void
1836output_yydestruct_impl(void)
1837{
1838    int i;
1839    char *s, *destructor_code;
1840
1841    putc_code(code_file, '\n');
1842    putl_code(code_file, "/* Release memory associated with symbol. */\n");
1843    putl_code(code_file, "#if ! defined YYDESTRUCT_IS_DECLARED\n");
1844    putl_code(code_file, "static void\n");
1845    putl_code(code_file, "YYDESTRUCT_DECL()\n");
1846    putl_code(code_file, "{\n");
1847    putl_code(code_file, "    switch (psymb)\n");
1848    putl_code(code_file, "    {\n");
1849    for (i = 2; i < nsyms; ++i)
1850    {
1851	if ((destructor_code = symbol_destructor[i]) != NULL)
1852	{
1853	    ++outline;
1854	    fprintf(code_file, "\tcase %d:\n", symbol_pval[i]);
1855	    /* comprehend the number of lines in the destructor code */
1856	    for (s = destructor_code; (s = strchr(s, '\n')) != NULL; s++)
1857		++outline;
1858	    puts_code(code_file, destructor_code);
1859	    putc_code(code_file, '\n');
1860	    putl_code(code_file, "\tbreak;\n");
1861	    write_code_lineno(code_file);
1862	    FREE(destructor_code);
1863	}
1864    }
1865    putl_code(code_file, "    }\n");
1866    putl_code(code_file, "}\n");
1867    putl_code(code_file, "#define YYDESTRUCT_IS_DECLARED 1\n");
1868    putl_code(code_file, "#endif\n");
1869
1870    DO_FREE(symbol_destructor);
1871}
1872#endif
1873
1874static void
1875free_itemsets(void)
1876{
1877    core *cp, *next;
1878
1879    FREE(state_table);
1880    for (cp = first_state; cp; cp = next)
1881    {
1882	next = cp->next;
1883	FREE(cp);
1884    }
1885}
1886
1887static void
1888free_shifts(void)
1889{
1890    shifts *sp, *next;
1891
1892    FREE(shift_table);
1893    for (sp = first_shift; sp; sp = next)
1894    {
1895	next = sp->next;
1896	FREE(sp);
1897    }
1898}
1899
1900static void
1901free_reductions(void)
1902{
1903    reductions *rp, *next;
1904
1905    FREE(reduction_table);
1906    for (rp = first_reduction; rp; rp = next)
1907    {
1908	next = rp->next;
1909	FREE(rp);
1910    }
1911}
1912
1913static void
1914output_externs(FILE * fp, const char *const section[])
1915{
1916    int i;
1917    const char *s;
1918
1919    for (i = 0; (s = section[i]) != 0; ++i)
1920    {
1921	/* prefix non-blank lines that don't start with
1922	   C pre-processor directives with 'extern ' */
1923	if (*s && (*s != '#'))
1924	    fputs("extern\t", fp);
1925	if (fp == code_file)
1926	    ++outline;
1927	fprintf(fp, "%s\n", s);
1928    }
1929}
1930
1931void
1932output(void)
1933{
1934    FILE *fp;
1935
1936    free_itemsets();
1937    free_shifts();
1938    free_reductions();
1939
1940#if defined(YYBTYACC)
1941    output_backtracking_parser(output_file);
1942    if (rflag)
1943	output_backtracking_parser(code_file);
1944#endif
1945
1946    if (iflag)
1947    {
1948	write_code_lineno(code_file);
1949	++outline;
1950	fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1951	fp = externs_file;
1952    }
1953    else
1954	fp = code_file;
1955
1956    output_prefix(fp);
1957    output_pure_parser(fp);
1958    output_stored_text(fp);
1959    output_stype(fp);
1960#if defined(YYBTYACC)
1961    if (locations)
1962	output_ltype(fp);
1963#endif
1964    output_parse_decl(fp);
1965    output_lex_decl(fp);
1966    output_error_decl(fp);
1967#if defined(YYBTYACC)
1968    if (destructor)
1969	output_yydestruct_decl(fp);
1970#endif
1971    if (iflag || !rflag)
1972    {
1973	write_section(fp, xdecls);
1974    }
1975
1976    if (iflag)
1977    {
1978	output_externs(externs_file, global_vars);
1979	if (!pure_parser)
1980	    output_externs(externs_file, impure_vars);
1981    }
1982
1983    if (iflag)
1984    {
1985	if (dflag)
1986	{
1987	    ++outline;
1988	    fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1989	}
1990	else
1991	    output_defines(externs_file);
1992    }
1993    else
1994    {
1995	putc_code(code_file, '\n');
1996	output_defines(code_file);
1997    }
1998
1999    if (dflag)
2000    {
2001	start_defines_file();
2002	output_defines(defines_file);
2003	end_defines_file();
2004    }
2005
2006    output_rule_data();
2007    output_yydefred();
2008#if defined(YYBTYACC)
2009    output_accessing_symbols();
2010#endif
2011    output_actions();
2012    free_parser();
2013    output_debug();
2014    if (rflag)
2015    {
2016	write_section(code_file, xdecls);
2017	output_YYINT_typedef(code_file);
2018	write_section(code_file, tables);
2019    }
2020    write_section(code_file, global_vars);
2021    if (!pure_parser)
2022    {
2023	write_section(code_file, impure_vars);
2024    }
2025    write_section(code_file, hdr_defs);
2026    if (!pure_parser)
2027    {
2028	write_section(code_file, hdr_vars);
2029    }
2030    output_trailing_text();
2031#if defined(YYBTYACC)
2032    if (destructor)
2033	output_yydestruct_impl();
2034#endif
2035    write_section(code_file, body_1);
2036    if (pure_parser)
2037    {
2038	write_section(code_file, body_vars);
2039    }
2040    write_section(code_file, body_2);
2041    output_semantic_actions();
2042    write_section(code_file, trailer);
2043}
2044
2045#ifdef NO_LEAKS
2046void
2047output_leaks(void)
2048{
2049    DO_FREE(tally);
2050    DO_FREE(width);
2051    DO_FREE(order);
2052}
2053#endif
2054