1251143Sbapt/* $Id: output.c,v 1.45 2013/03/05 00:29:17 tom Exp $ */
2234949Sbapt
3234949Sbapt#include "defs.h"
4234949Sbapt
5234949Sbapt#define StaticOrR	(rflag ? "" : "static ")
6234949Sbapt#define CountLine(fp)   (!rflag || ((fp) == code_file))
7234949Sbapt
8234949Sbaptstatic int nvectors;
9234949Sbaptstatic int nentries;
10234949Sbaptstatic Value_t **froms;
11234949Sbaptstatic Value_t **tos;
12234949Sbaptstatic Value_t *tally;
13234949Sbaptstatic Value_t *width;
14234949Sbaptstatic Value_t *state_count;
15234949Sbaptstatic Value_t *order;
16234949Sbaptstatic Value_t *base;
17234949Sbaptstatic Value_t *pos;
18234949Sbaptstatic int maxtable;
19234949Sbaptstatic Value_t *table;
20234949Sbaptstatic Value_t *check;
21234949Sbaptstatic int lowzero;
22234949Sbaptstatic int high;
23234949Sbapt
24234949Sbaptstatic void
25234949Sbaptputc_code(FILE * fp, int c)
26234949Sbapt{
27234949Sbapt    if ((c == '\n') && (fp == code_file))
28234949Sbapt	++outline;
29234949Sbapt    putc(c, fp);
30234949Sbapt}
31234949Sbapt
32234949Sbaptstatic void
33234949Sbaptputl_code(FILE * fp, const char *s)
34234949Sbapt{
35234949Sbapt    if (fp == code_file)
36234949Sbapt	++outline;
37234949Sbapt    fputs(s, fp);
38234949Sbapt}
39234949Sbapt
40234949Sbaptstatic void
41234949Sbaptputs_code(FILE * fp, const char *s)
42234949Sbapt{
43234949Sbapt    fputs(s, fp);
44234949Sbapt}
45234949Sbapt
46234949Sbaptstatic void
47234949Sbaptwrite_code_lineno(FILE * fp)
48234949Sbapt{
49234949Sbapt    if (!lflag && (fp == code_file))
50234949Sbapt    {
51234949Sbapt	++outline;
52234949Sbapt	fprintf(fp, line_format, outline, code_file_name);
53234949Sbapt    }
54234949Sbapt}
55234949Sbapt
56234949Sbaptstatic void
57234949Sbaptwrite_input_lineno(void)
58234949Sbapt{
59234949Sbapt    if (!lflag)
60234949Sbapt    {
61234949Sbapt	++outline;
62234949Sbapt	fprintf(code_file, line_format, lineno, input_file_name);
63234949Sbapt    }
64234949Sbapt}
65234949Sbapt
66234949Sbaptstatic void
67234949Sbaptdefine_prefixed(FILE * fp, const char *name)
68234949Sbapt{
69234949Sbapt    int bump_line = CountLine(fp);
70234949Sbapt    if (bump_line)
71234949Sbapt	++outline;
72234949Sbapt    fprintf(fp, "\n");
73234949Sbapt
74234949Sbapt    if (bump_line)
75234949Sbapt	++outline;
76234949Sbapt    fprintf(fp, "#ifndef %s\n", name);
77234949Sbapt
78234949Sbapt    if (bump_line)
79234949Sbapt	++outline;
80234949Sbapt    fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
81234949Sbapt
82234949Sbapt    if (bump_line)
83234949Sbapt	++outline;
84234949Sbapt    fprintf(fp, "#endif /* %s */\n", name);
85234949Sbapt}
86234949Sbapt
87234949Sbaptstatic void
88234949Sbaptoutput_prefix(FILE * fp)
89234949Sbapt{
90234949Sbapt    if (symbol_prefix == NULL)
91234949Sbapt    {
92234949Sbapt	symbol_prefix = "yy";
93234949Sbapt    }
94234949Sbapt    else
95234949Sbapt    {
96234949Sbapt	define_prefixed(fp, "yyparse");
97234949Sbapt	define_prefixed(fp, "yylex");
98234949Sbapt	define_prefixed(fp, "yyerror");
99234949Sbapt	define_prefixed(fp, "yychar");
100234949Sbapt	define_prefixed(fp, "yyval");
101234949Sbapt	define_prefixed(fp, "yylval");
102234949Sbapt	define_prefixed(fp, "yydebug");
103234949Sbapt	define_prefixed(fp, "yynerrs");
104234949Sbapt	define_prefixed(fp, "yyerrflag");
105234949Sbapt	define_prefixed(fp, "yylhs");
106234949Sbapt	define_prefixed(fp, "yylen");
107234949Sbapt	define_prefixed(fp, "yydefred");
108234949Sbapt	define_prefixed(fp, "yydgoto");
109234949Sbapt	define_prefixed(fp, "yysindex");
110234949Sbapt	define_prefixed(fp, "yyrindex");
111234949Sbapt	define_prefixed(fp, "yygindex");
112234949Sbapt	define_prefixed(fp, "yytable");
113234949Sbapt	define_prefixed(fp, "yycheck");
114234949Sbapt	define_prefixed(fp, "yyname");
115234949Sbapt	define_prefixed(fp, "yyrule");
116234949Sbapt    }
117234949Sbapt    if (CountLine(fp))
118234949Sbapt	++outline;
119234949Sbapt    fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
120234949Sbapt}
121234949Sbapt
122234949Sbaptstatic void
123234949Sbaptoutput_newline(void)
124234949Sbapt{
125234949Sbapt    if (!rflag)
126234949Sbapt	++outline;
127234949Sbapt    putc('\n', output_file);
128234949Sbapt}
129234949Sbapt
130234949Sbaptstatic void
131234949Sbaptoutput_line(const char *value)
132234949Sbapt{
133234949Sbapt    fputs(value, output_file);
134234949Sbapt    output_newline();
135234949Sbapt}
136234949Sbapt
137234949Sbaptstatic void
138234949Sbaptoutput_int(int value)
139234949Sbapt{
140234949Sbapt    fprintf(output_file, "%5d,", value);
141234949Sbapt}
142234949Sbapt
143234949Sbaptstatic void
144234949Sbaptstart_int_table(const char *name, int value)
145234949Sbapt{
146234949Sbapt    int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
147234949Sbapt
148234949Sbapt    if (need < 6)
149234949Sbapt	need = 6;
150234949Sbapt    fprintf(output_file,
151234949Sbapt	    "%sconst short %s%s[] = {%*d,",
152234949Sbapt	    StaticOrR, symbol_prefix, name, need, value);
153234949Sbapt}
154234949Sbapt
155234949Sbaptstatic void
156234949Sbaptstart_str_table(const char *name)
157234949Sbapt{
158234949Sbapt    fprintf(output_file,
159234949Sbapt	    "%sconst char *%s%s[] = {",
160234949Sbapt	    StaticOrR, "yy", name);
161234949Sbapt    output_newline();
162234949Sbapt}
163234949Sbapt
164234949Sbaptstatic void
165234949Sbaptend_table(void)
166234949Sbapt{
167234949Sbapt    output_newline();
168234949Sbapt    output_line("};");
169234949Sbapt}
170234949Sbapt
171234949Sbaptstatic void
172234949Sbaptoutput_rule_data(void)
173234949Sbapt{
174234949Sbapt    int i;
175234949Sbapt    int j;
176234949Sbapt
177234949Sbapt    start_int_table("lhs", symbol_value[start_symbol]);
178234949Sbapt
179234949Sbapt    j = 10;
180234949Sbapt    for (i = 3; i < nrules; i++)
181234949Sbapt    {
182234949Sbapt	if (j >= 10)
183234949Sbapt	{
184234949Sbapt	    output_newline();
185234949Sbapt	    j = 1;
186234949Sbapt	}
187234949Sbapt	else
188234949Sbapt	    ++j;
189234949Sbapt
190234949Sbapt	output_int(symbol_value[rlhs[i]]);
191234949Sbapt    }
192234949Sbapt    end_table();
193234949Sbapt
194234949Sbapt    start_int_table("len", 2);
195234949Sbapt
196234949Sbapt    j = 10;
197234949Sbapt    for (i = 3; i < nrules; i++)
198234949Sbapt    {
199234949Sbapt	if (j >= 10)
200234949Sbapt	{
201234949Sbapt	    output_newline();
202234949Sbapt	    j = 1;
203234949Sbapt	}
204234949Sbapt	else
205234949Sbapt	    j++;
206234949Sbapt
207234949Sbapt	output_int(rrhs[i + 1] - rrhs[i] - 1);
208234949Sbapt    }
209234949Sbapt    end_table();
210234949Sbapt}
211234949Sbapt
212234949Sbaptstatic void
213234949Sbaptoutput_yydefred(void)
214234949Sbapt{
215234949Sbapt    int i, j;
216234949Sbapt
217234949Sbapt    start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
218234949Sbapt
219234949Sbapt    j = 10;
220234949Sbapt    for (i = 1; i < nstates; i++)
221234949Sbapt    {
222234949Sbapt	if (j < 10)
223234949Sbapt	    ++j;
224234949Sbapt	else
225234949Sbapt	{
226234949Sbapt	    output_newline();
227234949Sbapt	    j = 1;
228234949Sbapt	}
229234949Sbapt
230234949Sbapt	output_int((defred[i] ? defred[i] - 2 : 0));
231234949Sbapt    }
232234949Sbapt
233234949Sbapt    end_table();
234234949Sbapt}
235234949Sbapt
236234949Sbaptstatic void
237234949Sbapttoken_actions(void)
238234949Sbapt{
239234949Sbapt    int i, j;
240234949Sbapt    Value_t shiftcount, reducecount;
241234949Sbapt    int max, min;
242234949Sbapt    Value_t *actionrow, *r, *s;
243234949Sbapt    action *p;
244234949Sbapt
245234949Sbapt    actionrow = NEW2(2 * ntokens, Value_t);
246234949Sbapt    for (i = 0; i < nstates; ++i)
247234949Sbapt    {
248234949Sbapt	if (parser[i])
249234949Sbapt	{
250234949Sbapt	    for (j = 0; j < 2 * ntokens; ++j)
251234949Sbapt		actionrow[j] = 0;
252234949Sbapt
253234949Sbapt	    shiftcount = 0;
254234949Sbapt	    reducecount = 0;
255234949Sbapt	    for (p = parser[i]; p; p = p->next)
256234949Sbapt	    {
257234949Sbapt		if (p->suppressed == 0)
258234949Sbapt		{
259234949Sbapt		    if (p->action_code == SHIFT)
260234949Sbapt		    {
261234949Sbapt			++shiftcount;
262234949Sbapt			actionrow[p->symbol] = p->number;
263234949Sbapt		    }
264234949Sbapt		    else if (p->action_code == REDUCE && p->number != defred[i])
265234949Sbapt		    {
266234949Sbapt			++reducecount;
267234949Sbapt			actionrow[p->symbol + ntokens] = p->number;
268234949Sbapt		    }
269234949Sbapt		}
270234949Sbapt	    }
271234949Sbapt
272234949Sbapt	    tally[i] = shiftcount;
273234949Sbapt	    tally[nstates + i] = reducecount;
274234949Sbapt	    width[i] = 0;
275234949Sbapt	    width[nstates + i] = 0;
276234949Sbapt	    if (shiftcount > 0)
277234949Sbapt	    {
278234949Sbapt		froms[i] = r = NEW2(shiftcount, Value_t);
279234949Sbapt		tos[i] = s = NEW2(shiftcount, Value_t);
280234949Sbapt		min = MAXSHORT;
281234949Sbapt		max = 0;
282234949Sbapt		for (j = 0; j < ntokens; ++j)
283234949Sbapt		{
284234949Sbapt		    if (actionrow[j])
285234949Sbapt		    {
286234949Sbapt			if (min > symbol_value[j])
287234949Sbapt			    min = symbol_value[j];
288234949Sbapt			if (max < symbol_value[j])
289234949Sbapt			    max = symbol_value[j];
290234949Sbapt			*r++ = symbol_value[j];
291234949Sbapt			*s++ = actionrow[j];
292234949Sbapt		    }
293234949Sbapt		}
294234949Sbapt		width[i] = (Value_t) (max - min + 1);
295234949Sbapt	    }
296234949Sbapt	    if (reducecount > 0)
297234949Sbapt	    {
298234949Sbapt		froms[nstates + i] = r = NEW2(reducecount, Value_t);
299234949Sbapt		tos[nstates + i] = s = NEW2(reducecount, Value_t);
300234949Sbapt		min = MAXSHORT;
301234949Sbapt		max = 0;
302234949Sbapt		for (j = 0; j < ntokens; ++j)
303234949Sbapt		{
304234949Sbapt		    if (actionrow[ntokens + j])
305234949Sbapt		    {
306234949Sbapt			if (min > symbol_value[j])
307234949Sbapt			    min = symbol_value[j];
308234949Sbapt			if (max < symbol_value[j])
309234949Sbapt			    max = symbol_value[j];
310234949Sbapt			*r++ = symbol_value[j];
311234949Sbapt			*s++ = (Value_t) (actionrow[ntokens + j] - 2);
312234949Sbapt		    }
313234949Sbapt		}
314234949Sbapt		width[nstates + i] = (Value_t) (max - min + 1);
315234949Sbapt	    }
316234949Sbapt	}
317234949Sbapt    }
318234949Sbapt    FREE(actionrow);
319234949Sbapt}
320234949Sbapt
321234949Sbaptstatic int
322234949Sbaptdefault_goto(int symbol)
323234949Sbapt{
324234949Sbapt    int i;
325234949Sbapt    int m;
326234949Sbapt    int n;
327234949Sbapt    int default_state;
328234949Sbapt    int max;
329234949Sbapt
330234949Sbapt    m = goto_map[symbol];
331234949Sbapt    n = goto_map[symbol + 1];
332234949Sbapt
333234949Sbapt    if (m == n)
334234949Sbapt	return (0);
335234949Sbapt
336234949Sbapt    for (i = 0; i < nstates; i++)
337234949Sbapt	state_count[i] = 0;
338234949Sbapt
339234949Sbapt    for (i = m; i < n; i++)
340234949Sbapt	state_count[to_state[i]]++;
341234949Sbapt
342234949Sbapt    max = 0;
343234949Sbapt    default_state = 0;
344234949Sbapt    for (i = 0; i < nstates; i++)
345234949Sbapt    {
346234949Sbapt	if (state_count[i] > max)
347234949Sbapt	{
348234949Sbapt	    max = state_count[i];
349234949Sbapt	    default_state = i;
350234949Sbapt	}
351234949Sbapt    }
352234949Sbapt
353234949Sbapt    return (default_state);
354234949Sbapt}
355234949Sbapt
356234949Sbaptstatic void
357234949Sbaptsave_column(int symbol, int default_state)
358234949Sbapt{
359234949Sbapt    int i;
360234949Sbapt    int m;
361234949Sbapt    int n;
362234949Sbapt    Value_t *sp;
363234949Sbapt    Value_t *sp1;
364234949Sbapt    Value_t *sp2;
365234949Sbapt    Value_t count;
366234949Sbapt    int symno;
367234949Sbapt
368234949Sbapt    m = goto_map[symbol];
369234949Sbapt    n = goto_map[symbol + 1];
370234949Sbapt
371234949Sbapt    count = 0;
372234949Sbapt    for (i = m; i < n; i++)
373234949Sbapt    {
374234949Sbapt	if (to_state[i] != default_state)
375234949Sbapt	    ++count;
376234949Sbapt    }
377234949Sbapt    if (count == 0)
378234949Sbapt	return;
379234949Sbapt
380234949Sbapt    symno = symbol_value[symbol] + 2 * nstates;
381234949Sbapt
382234949Sbapt    froms[symno] = sp1 = sp = NEW2(count, Value_t);
383234949Sbapt    tos[symno] = sp2 = NEW2(count, Value_t);
384234949Sbapt
385234949Sbapt    for (i = m; i < n; i++)
386234949Sbapt    {
387234949Sbapt	if (to_state[i] != default_state)
388234949Sbapt	{
389234949Sbapt	    *sp1++ = from_state[i];
390234949Sbapt	    *sp2++ = to_state[i];
391234949Sbapt	}
392234949Sbapt    }
393234949Sbapt
394234949Sbapt    tally[symno] = count;
395234949Sbapt    width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
396234949Sbapt}
397234949Sbapt
398234949Sbaptstatic void
399234949Sbaptgoto_actions(void)
400234949Sbapt{
401234949Sbapt    int i, j, k;
402234949Sbapt
403234949Sbapt    state_count = NEW2(nstates, Value_t);
404234949Sbapt
405234949Sbapt    k = default_goto(start_symbol + 1);
406234949Sbapt    start_int_table("dgoto", k);
407234949Sbapt    save_column(start_symbol + 1, k);
408234949Sbapt
409234949Sbapt    j = 10;
410234949Sbapt    for (i = start_symbol + 2; i < nsyms; i++)
411234949Sbapt    {
412234949Sbapt	if (j >= 10)
413234949Sbapt	{
414234949Sbapt	    output_newline();
415234949Sbapt	    j = 1;
416234949Sbapt	}
417234949Sbapt	else
418234949Sbapt	    ++j;
419234949Sbapt
420234949Sbapt	k = default_goto(i);
421234949Sbapt	output_int(k);
422234949Sbapt	save_column(i, k);
423234949Sbapt    }
424234949Sbapt
425234949Sbapt    end_table();
426234949Sbapt    FREE(state_count);
427234949Sbapt}
428234949Sbapt
429234949Sbaptstatic void
430234949Sbaptsort_actions(void)
431234949Sbapt{
432234949Sbapt    Value_t i;
433234949Sbapt    int j;
434234949Sbapt    int k;
435234949Sbapt    int t;
436234949Sbapt    int w;
437234949Sbapt
438234949Sbapt    order = NEW2(nvectors, Value_t);
439234949Sbapt    nentries = 0;
440234949Sbapt
441234949Sbapt    for (i = 0; i < nvectors; i++)
442234949Sbapt    {
443234949Sbapt	if (tally[i] > 0)
444234949Sbapt	{
445234949Sbapt	    t = tally[i];
446234949Sbapt	    w = width[i];
447234949Sbapt	    j = nentries - 1;
448234949Sbapt
449234949Sbapt	    while (j >= 0 && (width[order[j]] < w))
450234949Sbapt		j--;
451234949Sbapt
452234949Sbapt	    while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
453234949Sbapt		j--;
454234949Sbapt
455234949Sbapt	    for (k = nentries - 1; k > j; k--)
456234949Sbapt		order[k + 1] = order[k];
457234949Sbapt
458234949Sbapt	    order[j + 1] = i;
459234949Sbapt	    nentries++;
460234949Sbapt	}
461234949Sbapt    }
462234949Sbapt}
463234949Sbapt
464234949Sbapt/*  The function matching_vector determines if the vector specified by	*/
465234949Sbapt/*  the input parameter matches a previously considered	vector.  The	*/
466234949Sbapt/*  test at the start of the function checks if the vector represents	*/
467234949Sbapt/*  a row of shifts over terminal symbols or a row of reductions, or a	*/
468234949Sbapt/*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
469234949Sbapt/*  check if a column of shifts over a nonterminal symbols matches a	*/
470234949Sbapt/*  previously considered vector.  Because of the nature of LR parsing	*/
471234949Sbapt/*  tables, no two columns can match.  Therefore, the only possible	*/
472234949Sbapt/*  match would be between a row and a column.  Such matches are	*/
473234949Sbapt/*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
474234949Sbapt/*  column matches a previously considered vector.			*/
475234949Sbapt/*									*/
476234949Sbapt/*  Matching_vector is poorly designed.  The test could easily be made	*/
477234949Sbapt/*  faster.  Also, it depends on the vectors being in a specific	*/
478234949Sbapt/*  order.								*/
479234949Sbapt
480234949Sbaptstatic int
481234949Sbaptmatching_vector(int vector)
482234949Sbapt{
483234949Sbapt    int i;
484234949Sbapt    int j;
485234949Sbapt    int k;
486234949Sbapt    int t;
487234949Sbapt    int w;
488234949Sbapt    int match;
489234949Sbapt    int prev;
490234949Sbapt
491234949Sbapt    i = order[vector];
492234949Sbapt    if (i >= 2 * nstates)
493234949Sbapt	return (-1);
494234949Sbapt
495234949Sbapt    t = tally[i];
496234949Sbapt    w = width[i];
497234949Sbapt
498234949Sbapt    for (prev = vector - 1; prev >= 0; prev--)
499234949Sbapt    {
500234949Sbapt	j = order[prev];
501234949Sbapt	if (width[j] != w || tally[j] != t)
502234949Sbapt	    return (-1);
503234949Sbapt
504234949Sbapt	match = 1;
505234949Sbapt	for (k = 0; match && k < t; k++)
506234949Sbapt	{
507234949Sbapt	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
508234949Sbapt		match = 0;
509234949Sbapt	}
510234949Sbapt
511234949Sbapt	if (match)
512234949Sbapt	    return (j);
513234949Sbapt    }
514234949Sbapt
515234949Sbapt    return (-1);
516234949Sbapt}
517234949Sbapt
518234949Sbaptstatic int
519234949Sbaptpack_vector(int vector)
520234949Sbapt{
521234949Sbapt    int i, j, k, l;
522234949Sbapt    int t;
523234949Sbapt    int loc;
524234949Sbapt    int ok;
525234949Sbapt    Value_t *from;
526234949Sbapt    Value_t *to;
527234949Sbapt    int newmax;
528234949Sbapt
529234949Sbapt    i = order[vector];
530234949Sbapt    t = tally[i];
531234949Sbapt    assert(t);
532234949Sbapt
533234949Sbapt    from = froms[i];
534234949Sbapt    to = tos[i];
535234949Sbapt
536234949Sbapt    j = lowzero - from[0];
537234949Sbapt    for (k = 1; k < t; ++k)
538234949Sbapt	if (lowzero - from[k] > j)
539234949Sbapt	    j = lowzero - from[k];
540234949Sbapt    for (;; ++j)
541234949Sbapt    {
542234949Sbapt	if (j == 0)
543234949Sbapt	    continue;
544234949Sbapt	ok = 1;
545234949Sbapt	for (k = 0; ok && k < t; k++)
546234949Sbapt	{
547234949Sbapt	    loc = j + from[k];
548234949Sbapt	    if (loc >= maxtable - 1)
549234949Sbapt	    {
550234949Sbapt		if (loc >= MAXTABLE - 1)
551234949Sbapt		    fatal("maximum table size exceeded");
552234949Sbapt
553234949Sbapt		newmax = maxtable;
554234949Sbapt		do
555234949Sbapt		{
556234949Sbapt		    newmax += 200;
557234949Sbapt		}
558234949Sbapt		while (newmax <= loc);
559234949Sbapt
560240517Sbapt		table = TREALLOC(Value_t, table, newmax);
561234949Sbapt		NO_SPACE(table);
562234949Sbapt
563240517Sbapt		check = TREALLOC(Value_t, check, newmax);
564234949Sbapt		NO_SPACE(check);
565234949Sbapt
566234949Sbapt		for (l = maxtable; l < newmax; ++l)
567234949Sbapt		{
568234949Sbapt		    table[l] = 0;
569234949Sbapt		    check[l] = -1;
570234949Sbapt		}
571234949Sbapt		maxtable = newmax;
572234949Sbapt	    }
573234949Sbapt
574234949Sbapt	    if (check[loc] != -1)
575234949Sbapt		ok = 0;
576234949Sbapt	}
577234949Sbapt	for (k = 0; ok && k < vector; k++)
578234949Sbapt	{
579234949Sbapt	    if (pos[k] == j)
580234949Sbapt		ok = 0;
581234949Sbapt	}
582234949Sbapt	if (ok)
583234949Sbapt	{
584234949Sbapt	    for (k = 0; k < t; k++)
585234949Sbapt	    {
586234949Sbapt		loc = j + from[k];
587234949Sbapt		table[loc] = to[k];
588234949Sbapt		check[loc] = from[k];
589234949Sbapt		if (loc > high)
590234949Sbapt		    high = loc;
591234949Sbapt	    }
592234949Sbapt
593234949Sbapt	    while (check[lowzero] != -1)
594234949Sbapt		++lowzero;
595234949Sbapt
596234949Sbapt	    return (j);
597234949Sbapt	}
598234949Sbapt    }
599234949Sbapt}
600234949Sbapt
601234949Sbaptstatic void
602234949Sbaptpack_table(void)
603234949Sbapt{
604234949Sbapt    int i;
605234949Sbapt    Value_t place;
606234949Sbapt    int state;
607234949Sbapt
608234949Sbapt    base = NEW2(nvectors, Value_t);
609234949Sbapt    pos = NEW2(nentries, Value_t);
610234949Sbapt
611234949Sbapt    maxtable = 1000;
612234949Sbapt    table = NEW2(maxtable, Value_t);
613234949Sbapt    check = NEW2(maxtable, Value_t);
614234949Sbapt
615234949Sbapt    lowzero = 0;
616234949Sbapt    high = 0;
617234949Sbapt
618234949Sbapt    for (i = 0; i < maxtable; i++)
619234949Sbapt	check[i] = -1;
620234949Sbapt
621234949Sbapt    for (i = 0; i < nentries; i++)
622234949Sbapt    {
623234949Sbapt	state = matching_vector(i);
624234949Sbapt
625234949Sbapt	if (state < 0)
626234949Sbapt	    place = (Value_t) pack_vector(i);
627234949Sbapt	else
628234949Sbapt	    place = base[state];
629234949Sbapt
630234949Sbapt	pos[i] = place;
631234949Sbapt	base[order[i]] = place;
632234949Sbapt    }
633234949Sbapt
634234949Sbapt    for (i = 0; i < nvectors; i++)
635234949Sbapt    {
636234949Sbapt	if (froms[i])
637234949Sbapt	    FREE(froms[i]);
638234949Sbapt	if (tos[i])
639234949Sbapt	    FREE(tos[i]);
640234949Sbapt    }
641234949Sbapt
642234949Sbapt    FREE(froms);
643234949Sbapt    FREE(tos);
644234949Sbapt    FREE(pos);
645234949Sbapt}
646234949Sbapt
647234949Sbaptstatic void
648234949Sbaptoutput_base(void)
649234949Sbapt{
650234949Sbapt    int i, j;
651234949Sbapt
652234949Sbapt    start_int_table("sindex", base[0]);
653234949Sbapt
654234949Sbapt    j = 10;
655234949Sbapt    for (i = 1; i < nstates; i++)
656234949Sbapt    {
657234949Sbapt	if (j >= 10)
658234949Sbapt	{
659234949Sbapt	    output_newline();
660234949Sbapt	    j = 1;
661234949Sbapt	}
662234949Sbapt	else
663234949Sbapt	    ++j;
664234949Sbapt
665234949Sbapt	output_int(base[i]);
666234949Sbapt    }
667234949Sbapt
668234949Sbapt    end_table();
669234949Sbapt
670234949Sbapt    start_int_table("rindex", base[nstates]);
671234949Sbapt
672234949Sbapt    j = 10;
673234949Sbapt    for (i = nstates + 1; i < 2 * nstates; i++)
674234949Sbapt    {
675234949Sbapt	if (j >= 10)
676234949Sbapt	{
677234949Sbapt	    output_newline();
678234949Sbapt	    j = 1;
679234949Sbapt	}
680234949Sbapt	else
681234949Sbapt	    ++j;
682234949Sbapt
683234949Sbapt	output_int(base[i]);
684234949Sbapt    }
685234949Sbapt
686234949Sbapt    end_table();
687234949Sbapt
688234949Sbapt    start_int_table("gindex", base[2 * nstates]);
689234949Sbapt
690234949Sbapt    j = 10;
691234949Sbapt    for (i = 2 * nstates + 1; i < nvectors - 1; i++)
692234949Sbapt    {
693234949Sbapt	if (j >= 10)
694234949Sbapt	{
695234949Sbapt	    output_newline();
696234949Sbapt	    j = 1;
697234949Sbapt	}
698234949Sbapt	else
699234949Sbapt	    ++j;
700234949Sbapt
701234949Sbapt	output_int(base[i]);
702234949Sbapt    }
703234949Sbapt
704234949Sbapt    end_table();
705234949Sbapt    FREE(base);
706234949Sbapt}
707234949Sbapt
708234949Sbaptstatic void
709234949Sbaptoutput_table(void)
710234949Sbapt{
711234949Sbapt    int i;
712234949Sbapt    int j;
713234949Sbapt
714234949Sbapt    ++outline;
715234949Sbapt    fprintf(code_file, "#define YYTABLESIZE %d\n", high);
716234949Sbapt    start_int_table("table", table[0]);
717234949Sbapt
718234949Sbapt    j = 10;
719234949Sbapt    for (i = 1; i <= high; i++)
720234949Sbapt    {
721234949Sbapt	if (j >= 10)
722234949Sbapt	{
723234949Sbapt	    output_newline();
724234949Sbapt	    j = 1;
725234949Sbapt	}
726234949Sbapt	else
727234949Sbapt	    ++j;
728234949Sbapt
729234949Sbapt	output_int(table[i]);
730234949Sbapt    }
731234949Sbapt
732234949Sbapt    end_table();
733234949Sbapt    FREE(table);
734234949Sbapt}
735234949Sbapt
736234949Sbaptstatic void
737234949Sbaptoutput_check(void)
738234949Sbapt{
739234949Sbapt    int i;
740234949Sbapt    int j;
741234949Sbapt
742234949Sbapt    start_int_table("check", check[0]);
743234949Sbapt
744234949Sbapt    j = 10;
745234949Sbapt    for (i = 1; i <= high; i++)
746234949Sbapt    {
747234949Sbapt	if (j >= 10)
748234949Sbapt	{
749234949Sbapt	    output_newline();
750234949Sbapt	    j = 1;
751234949Sbapt	}
752234949Sbapt	else
753234949Sbapt	    ++j;
754234949Sbapt
755234949Sbapt	output_int(check[i]);
756234949Sbapt    }
757234949Sbapt
758234949Sbapt    end_table();
759234949Sbapt    FREE(check);
760234949Sbapt}
761234949Sbapt
762234949Sbaptstatic void
763234949Sbaptoutput_actions(void)
764234949Sbapt{
765234949Sbapt    nvectors = 2 * nstates + nvars;
766234949Sbapt
767234949Sbapt    froms = NEW2(nvectors, Value_t *);
768234949Sbapt    tos = NEW2(nvectors, Value_t *);
769234949Sbapt    tally = NEW2(nvectors, Value_t);
770234949Sbapt    width = NEW2(nvectors, Value_t);
771234949Sbapt
772234949Sbapt    token_actions();
773234949Sbapt    FREE(lookaheads);
774234949Sbapt    FREE(LA);
775234949Sbapt    FREE(LAruleno);
776234949Sbapt    FREE(accessing_symbol);
777234949Sbapt
778234949Sbapt    goto_actions();
779234949Sbapt    FREE(goto_map + ntokens);
780234949Sbapt    FREE(from_state);
781234949Sbapt    FREE(to_state);
782234949Sbapt
783234949Sbapt    sort_actions();
784234949Sbapt    pack_table();
785234949Sbapt    output_base();
786234949Sbapt    output_table();
787234949Sbapt    output_check();
788234949Sbapt}
789234949Sbapt
790234949Sbaptstatic int
791234949Sbaptis_C_identifier(char *name)
792234949Sbapt{
793234949Sbapt    char *s;
794234949Sbapt    int c;
795234949Sbapt
796234949Sbapt    s = name;
797234949Sbapt    c = *s;
798234949Sbapt    if (c == '"')
799234949Sbapt    {
800234949Sbapt	c = *++s;
801234949Sbapt	if (!isalpha(c) && c != '_' && c != '$')
802234949Sbapt	    return (0);
803234949Sbapt	while ((c = *++s) != '"')
804234949Sbapt	{
805234949Sbapt	    if (!isalnum(c) && c != '_' && c != '$')
806234949Sbapt		return (0);
807234949Sbapt	}
808234949Sbapt	return (1);
809234949Sbapt    }
810234949Sbapt
811234949Sbapt    if (!isalpha(c) && c != '_' && c != '$')
812234949Sbapt	return (0);
813234949Sbapt    while ((c = *++s) != 0)
814234949Sbapt    {
815234949Sbapt	if (!isalnum(c) && c != '_' && c != '$')
816234949Sbapt	    return (0);
817234949Sbapt    }
818234949Sbapt    return (1);
819234949Sbapt}
820234949Sbapt
821234949Sbaptstatic void
822234949Sbaptoutput_defines(FILE * fp)
823234949Sbapt{
824234949Sbapt    int c, i;
825234949Sbapt    char *s;
826234949Sbapt
827234949Sbapt    for (i = 2; i < ntokens; ++i)
828234949Sbapt    {
829234949Sbapt	s = symbol_name[i];
830234949Sbapt	if (is_C_identifier(s) && (!sflag || *s != '"'))
831234949Sbapt	{
832234949Sbapt	    fprintf(fp, "#define ");
833234949Sbapt	    c = *s;
834234949Sbapt	    if (c == '"')
835234949Sbapt	    {
836234949Sbapt		while ((c = *++s) != '"')
837234949Sbapt		{
838234949Sbapt		    putc(c, fp);
839234949Sbapt		}
840234949Sbapt	    }
841234949Sbapt	    else
842234949Sbapt	    {
843234949Sbapt		do
844234949Sbapt		{
845234949Sbapt		    putc(c, fp);
846234949Sbapt		}
847234949Sbapt		while ((c = *++s) != 0);
848234949Sbapt	    }
849234949Sbapt	    if (fp == code_file)
850234949Sbapt		++outline;
851234949Sbapt	    fprintf(fp, " %d\n", symbol_value[i]);
852234949Sbapt	}
853234949Sbapt    }
854234949Sbapt
855234949Sbapt    if (fp == code_file)
856234949Sbapt	++outline;
857234949Sbapt    if (fp != defines_file || iflag)
858234949Sbapt	fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
859234949Sbapt
860234949Sbapt    if (fp == defines_file || (iflag && !dflag))
861234949Sbapt    {
862234949Sbapt	if (unionized)
863234949Sbapt	{
864251143Sbapt	    if (union_file != 0)
865251143Sbapt	    {
866251143Sbapt		rewind(union_file);
867251143Sbapt		while ((c = getc(union_file)) != EOF)
868251143Sbapt		    putc(c, fp);
869251143Sbapt	    }
870234949Sbapt	    fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
871234949Sbapt	}
872234949Sbapt    }
873234949Sbapt}
874234949Sbapt
875234949Sbaptstatic void
876234949Sbaptoutput_stored_text(FILE * fp)
877234949Sbapt{
878234949Sbapt    int c;
879234949Sbapt    FILE *in;
880234949Sbapt
881234949Sbapt    rewind(text_file);
882234949Sbapt    if (text_file == NULL)
883234949Sbapt	open_error("text_file");
884234949Sbapt    in = text_file;
885234949Sbapt    if ((c = getc(in)) == EOF)
886234949Sbapt	return;
887234949Sbapt    putc_code(fp, c);
888234949Sbapt    while ((c = getc(in)) != EOF)
889234949Sbapt    {
890234949Sbapt	putc_code(fp, c);
891234949Sbapt    }
892234949Sbapt    write_code_lineno(fp);
893234949Sbapt}
894234949Sbapt
895234949Sbaptstatic void
896234949Sbaptoutput_debug(void)
897234949Sbapt{
898234949Sbapt    int i, j, k, max;
899234949Sbapt    const char **symnam;
900234949Sbapt    const char *s;
901234949Sbapt
902234949Sbapt    ++outline;
903234949Sbapt    fprintf(code_file, "#define YYFINAL %d\n", final_state);
904234949Sbapt
905234949Sbapt    putl_code(code_file, "#ifndef YYDEBUG\n");
906234949Sbapt    ++outline;
907234949Sbapt    fprintf(code_file, "#define YYDEBUG %d\n", tflag);
908234949Sbapt    putl_code(code_file, "#endif\n");
909234949Sbapt
910234949Sbapt    if (rflag)
911234949Sbapt    {
912234949Sbapt	fprintf(output_file, "#ifndef YYDEBUG\n");
913234949Sbapt	fprintf(output_file, "#define YYDEBUG %d\n", tflag);
914234949Sbapt	fprintf(output_file, "#endif\n");
915234949Sbapt    }
916234949Sbapt
917234949Sbapt    max = 0;
918234949Sbapt    for (i = 2; i < ntokens; ++i)
919234949Sbapt	if (symbol_value[i] > max)
920234949Sbapt	    max = symbol_value[i];
921234949Sbapt
922234949Sbapt    ++outline;
923234949Sbapt    fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
924234949Sbapt
925240517Sbapt    symnam = TMALLOC(const char *, max + 1);
926234949Sbapt    NO_SPACE(symnam);
927234949Sbapt
928234949Sbapt    /* Note that it is  not necessary to initialize the element         */
929234949Sbapt    /* symnam[max].                                                     */
930234949Sbapt    for (i = 0; i < max; ++i)
931234949Sbapt	symnam[i] = 0;
932234949Sbapt    for (i = ntokens - 1; i >= 2; --i)
933234949Sbapt	symnam[symbol_value[i]] = symbol_name[i];
934234949Sbapt    symnam[0] = "end-of-file";
935234949Sbapt
936234949Sbapt    output_line("#if YYDEBUG");
937234949Sbapt
938234949Sbapt    start_str_table("name");
939234949Sbapt    j = 80;
940234949Sbapt    for (i = 0; i <= max; ++i)
941234949Sbapt    {
942234949Sbapt	if ((s = symnam[i]) != 0)
943234949Sbapt	{
944234949Sbapt	    if (s[0] == '"')
945234949Sbapt	    {
946234949Sbapt		k = 7;
947234949Sbapt		while (*++s != '"')
948234949Sbapt		{
949234949Sbapt		    ++k;
950234949Sbapt		    if (*s == '\\')
951234949Sbapt		    {
952234949Sbapt			k += 2;
953234949Sbapt			if (*++s == '\\')
954234949Sbapt			    ++k;
955234949Sbapt		    }
956234949Sbapt		}
957234949Sbapt		j += k;
958234949Sbapt		if (j > 80)
959234949Sbapt		{
960234949Sbapt		    output_newline();
961234949Sbapt		    j = k;
962234949Sbapt		}
963234949Sbapt		fprintf(output_file, "\"\\\"");
964234949Sbapt		s = symnam[i];
965234949Sbapt		while (*++s != '"')
966234949Sbapt		{
967234949Sbapt		    if (*s == '\\')
968234949Sbapt		    {
969234949Sbapt			fprintf(output_file, "\\\\");
970234949Sbapt			if (*++s == '\\')
971234949Sbapt			    fprintf(output_file, "\\\\");
972234949Sbapt			else
973234949Sbapt			    putc(*s, output_file);
974234949Sbapt		    }
975234949Sbapt		    else
976234949Sbapt			putc(*s, output_file);
977234949Sbapt		}
978234949Sbapt		fprintf(output_file, "\\\"\",");
979234949Sbapt	    }
980234949Sbapt	    else if (s[0] == '\'')
981234949Sbapt	    {
982234949Sbapt		if (s[1] == '"')
983234949Sbapt		{
984234949Sbapt		    j += 7;
985234949Sbapt		    if (j > 80)
986234949Sbapt		    {
987234949Sbapt			output_newline();
988234949Sbapt			j = 7;
989234949Sbapt		    }
990234949Sbapt		    fprintf(output_file, "\"'\\\"'\",");
991234949Sbapt		}
992234949Sbapt		else
993234949Sbapt		{
994234949Sbapt		    k = 5;
995234949Sbapt		    while (*++s != '\'')
996234949Sbapt		    {
997234949Sbapt			++k;
998234949Sbapt			if (*s == '\\')
999234949Sbapt			{
1000234949Sbapt			    k += 2;
1001234949Sbapt			    if (*++s == '\\')
1002234949Sbapt				++k;
1003234949Sbapt			}
1004234949Sbapt		    }
1005234949Sbapt		    j += k;
1006234949Sbapt		    if (j > 80)
1007234949Sbapt		    {
1008234949Sbapt			output_newline();
1009234949Sbapt			j = k;
1010234949Sbapt		    }
1011234949Sbapt		    fprintf(output_file, "\"'");
1012234949Sbapt		    s = symnam[i];
1013234949Sbapt		    while (*++s != '\'')
1014234949Sbapt		    {
1015234949Sbapt			if (*s == '\\')
1016234949Sbapt			{
1017234949Sbapt			    fprintf(output_file, "\\\\");
1018234949Sbapt			    if (*++s == '\\')
1019234949Sbapt				fprintf(output_file, "\\\\");
1020234949Sbapt			    else
1021234949Sbapt				putc(*s, output_file);
1022234949Sbapt			}
1023234949Sbapt			else
1024234949Sbapt			    putc(*s, output_file);
1025234949Sbapt		    }
1026234949Sbapt		    fprintf(output_file, "'\",");
1027234949Sbapt		}
1028234949Sbapt	    }
1029234949Sbapt	    else
1030234949Sbapt	    {
1031234949Sbapt		k = (int)strlen(s) + 3;
1032234949Sbapt		j += k;
1033234949Sbapt		if (j > 80)
1034234949Sbapt		{
1035234949Sbapt		    output_newline();
1036234949Sbapt		    j = k;
1037234949Sbapt		}
1038234949Sbapt		putc('"', output_file);
1039234949Sbapt		do
1040234949Sbapt		{
1041234949Sbapt		    putc(*s, output_file);
1042234949Sbapt		}
1043234949Sbapt		while (*++s);
1044234949Sbapt		fprintf(output_file, "\",");
1045234949Sbapt	    }
1046234949Sbapt	}
1047234949Sbapt	else
1048234949Sbapt	{
1049234949Sbapt	    j += 2;
1050234949Sbapt	    if (j > 80)
1051234949Sbapt	    {
1052234949Sbapt		output_newline();
1053234949Sbapt		j = 2;
1054234949Sbapt	    }
1055234949Sbapt	    fprintf(output_file, "0,");
1056234949Sbapt	}
1057234949Sbapt    }
1058234949Sbapt    end_table();
1059234949Sbapt    FREE(symnam);
1060234949Sbapt
1061234949Sbapt    start_str_table("rule");
1062234949Sbapt    for (i = 2; i < nrules; ++i)
1063234949Sbapt    {
1064234949Sbapt	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1065234949Sbapt	for (j = rrhs[i]; ritem[j] > 0; ++j)
1066234949Sbapt	{
1067234949Sbapt	    s = symbol_name[ritem[j]];
1068234949Sbapt	    if (s[0] == '"')
1069234949Sbapt	    {
1070234949Sbapt		fprintf(output_file, " \\\"");
1071234949Sbapt		while (*++s != '"')
1072234949Sbapt		{
1073234949Sbapt		    if (*s == '\\')
1074234949Sbapt		    {
1075234949Sbapt			if (s[1] == '\\')
1076234949Sbapt			    fprintf(output_file, "\\\\\\\\");
1077234949Sbapt			else
1078234949Sbapt			    fprintf(output_file, "\\\\%c", s[1]);
1079234949Sbapt			++s;
1080234949Sbapt		    }
1081234949Sbapt		    else
1082234949Sbapt			putc(*s, output_file);
1083234949Sbapt		}
1084234949Sbapt		fprintf(output_file, "\\\"");
1085234949Sbapt	    }
1086234949Sbapt	    else if (s[0] == '\'')
1087234949Sbapt	    {
1088234949Sbapt		if (s[1] == '"')
1089234949Sbapt		    fprintf(output_file, " '\\\"'");
1090234949Sbapt		else if (s[1] == '\\')
1091234949Sbapt		{
1092234949Sbapt		    if (s[2] == '\\')
1093234949Sbapt			fprintf(output_file, " '\\\\\\\\");
1094234949Sbapt		    else
1095234949Sbapt			fprintf(output_file, " '\\\\%c", s[2]);
1096234949Sbapt		    s += 2;
1097234949Sbapt		    while (*++s != '\'')
1098234949Sbapt			putc(*s, output_file);
1099234949Sbapt		    putc('\'', output_file);
1100234949Sbapt		}
1101234949Sbapt		else
1102234949Sbapt		    fprintf(output_file, " '%c'", s[1]);
1103234949Sbapt	    }
1104234949Sbapt	    else
1105234949Sbapt		fprintf(output_file, " %s", s);
1106234949Sbapt	}
1107234949Sbapt	fprintf(output_file, "\",");
1108234949Sbapt	output_newline();
1109234949Sbapt    }
1110234949Sbapt
1111234949Sbapt    end_table();
1112234949Sbapt    output_line("#endif");
1113234949Sbapt}
1114234949Sbapt
1115234949Sbaptstatic void
1116234949Sbaptoutput_pure_parser(FILE * fp)
1117234949Sbapt{
1118234949Sbapt    putc_code(fp, '\n');
1119234949Sbapt
1120234949Sbapt    if (fp == code_file)
1121234949Sbapt	outline += 1;
1122234949Sbapt    fprintf(fp, "#define YYPURE %d\n", pure_parser);
1123234949Sbapt    putc_code(fp, '\n');
1124234949Sbapt}
1125234949Sbapt
1126234949Sbaptstatic void
1127234949Sbaptoutput_stype(FILE * fp)
1128234949Sbapt{
1129234949Sbapt    if (!unionized && ntags == 0)
1130234949Sbapt    {
1131234949Sbapt	putc_code(fp, '\n');
1132234949Sbapt	putl_code(fp, "#ifndef YYSTYPE\n");
1133234949Sbapt	putl_code(fp, "typedef int YYSTYPE;\n");
1134234949Sbapt	putl_code(fp, "#endif\n");
1135234949Sbapt    }
1136234949Sbapt}
1137234949Sbapt
1138234949Sbaptstatic void
1139234949Sbaptoutput_trailing_text(void)
1140234949Sbapt{
1141234949Sbapt    int c, last;
1142234949Sbapt    FILE *in;
1143234949Sbapt
1144234949Sbapt    if (line == 0)
1145234949Sbapt	return;
1146234949Sbapt
1147234949Sbapt    in = input_file;
1148234949Sbapt    c = *cptr;
1149234949Sbapt    if (c == '\n')
1150234949Sbapt    {
1151234949Sbapt	++lineno;
1152234949Sbapt	if ((c = getc(in)) == EOF)
1153234949Sbapt	    return;
1154234949Sbapt	write_input_lineno();
1155234949Sbapt	putc_code(code_file, c);
1156234949Sbapt	last = c;
1157234949Sbapt    }
1158234949Sbapt    else
1159234949Sbapt    {
1160234949Sbapt	write_input_lineno();
1161234949Sbapt	do
1162234949Sbapt	{
1163234949Sbapt	    putc_code(code_file, c);
1164234949Sbapt	}
1165234949Sbapt	while ((c = *++cptr) != '\n');
1166234949Sbapt	putc_code(code_file, c);
1167234949Sbapt	last = '\n';
1168234949Sbapt    }
1169234949Sbapt
1170234949Sbapt    while ((c = getc(in)) != EOF)
1171234949Sbapt    {
1172234949Sbapt	putc_code(code_file, c);
1173234949Sbapt	last = c;
1174234949Sbapt    }
1175234949Sbapt
1176234949Sbapt    if (last != '\n')
1177234949Sbapt    {
1178234949Sbapt	putc_code(code_file, '\n');
1179234949Sbapt    }
1180234949Sbapt    write_code_lineno(code_file);
1181234949Sbapt}
1182234949Sbapt
1183234949Sbaptstatic void
1184234949Sbaptoutput_semantic_actions(void)
1185234949Sbapt{
1186234949Sbapt    int c, last;
1187234949Sbapt
1188234949Sbapt    rewind(action_file);
1189234949Sbapt    if ((c = getc(action_file)) == EOF)
1190234949Sbapt	return;
1191234949Sbapt
1192234949Sbapt    last = c;
1193234949Sbapt    putc_code(code_file, c);
1194234949Sbapt    while ((c = getc(action_file)) != EOF)
1195234949Sbapt    {
1196234949Sbapt	putc_code(code_file, c);
1197234949Sbapt	last = c;
1198234949Sbapt    }
1199234949Sbapt
1200234949Sbapt    if (last != '\n')
1201234949Sbapt    {
1202234949Sbapt	putc_code(code_file, '\n');
1203234949Sbapt    }
1204234949Sbapt
1205234949Sbapt    write_code_lineno(code_file);
1206234949Sbapt}
1207234949Sbapt
1208234949Sbaptstatic void
1209234949Sbaptoutput_parse_decl(FILE * fp)
1210234949Sbapt{
1211234949Sbapt    putl_code(fp, "\n");
1212234949Sbapt    putl_code(fp, "/* compatibility with bison */\n");
1213234949Sbapt    putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1214234949Sbapt    putl_code(fp, "/* compatibility with FreeBSD */\n");
1215234949Sbapt    putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1216234949Sbapt    putl_code(fp,
1217234949Sbapt	      "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1218234949Sbapt    putl_code(fp, "# else\n");
1219234949Sbapt    putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1220234949Sbapt    putl_code(fp, "# endif\n");
1221234949Sbapt    putl_code(fp, "#else\n");
1222234949Sbapt
1223234949Sbapt    puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1224234949Sbapt    if (!parse_param)
1225234949Sbapt	puts_code(fp, "void");
1226234949Sbapt    else
1227234949Sbapt    {
1228234949Sbapt	param *p;
1229234949Sbapt	for (p = parse_param; p; p = p->next)
1230234949Sbapt	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1231234949Sbapt		    p->next ? ", " : "");
1232234949Sbapt    }
1233234949Sbapt    putl_code(fp, ")\n");
1234234949Sbapt
1235234949Sbapt    putl_code(fp, "#endif\n");
1236234949Sbapt}
1237234949Sbapt
1238234949Sbaptstatic void
1239234949Sbaptoutput_lex_decl(FILE * fp)
1240234949Sbapt{
1241234949Sbapt    putl_code(fp, "\n");
1242234949Sbapt    putl_code(fp, "/* Parameters sent to lex. */\n");
1243234949Sbapt    putl_code(fp, "#ifdef YYLEX_PARAM\n");
1244234949Sbapt    if (pure_parser)
1245234949Sbapt    {
1246234949Sbapt	putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1247234949Sbapt	putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1248234949Sbapt		  " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1249234949Sbapt	putl_code(fp, "# else\n");
1250234949Sbapt	putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1251234949Sbapt		  " void * YYLEX_PARAM)\n");
1252234949Sbapt	putl_code(fp, "# endif\n");
1253234949Sbapt	putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1254234949Sbapt    }
1255234949Sbapt    else
1256234949Sbapt    {
1257234949Sbapt	putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1258234949Sbapt	putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1259234949Sbapt    }
1260234949Sbapt    putl_code(fp, "#else\n");
1261234949Sbapt    if (pure_parser && lex_param)
1262234949Sbapt    {
1263234949Sbapt	param *p;
1264234949Sbapt	puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1265234949Sbapt	for (p = lex_param; p; p = p->next)
1266234949Sbapt	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1267234949Sbapt		    p->next ? ", " : "");
1268234949Sbapt	putl_code(fp, ")\n");
1269234949Sbapt
1270234949Sbapt	puts_code(fp, "# define YYLEX yylex(&yylval, ");
1271234949Sbapt	for (p = lex_param; p; p = p->next)
1272234949Sbapt	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1273234949Sbapt	putl_code(fp, ")\n");
1274234949Sbapt    }
1275234949Sbapt    else if (pure_parser)
1276234949Sbapt    {
1277234949Sbapt	putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1278234949Sbapt	putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1279234949Sbapt    }
1280234949Sbapt    else if (lex_param)
1281234949Sbapt    {
1282234949Sbapt	param *p;
1283234949Sbapt	puts_code(fp, "# define YYLEX_DECL() yylex(");
1284234949Sbapt	for (p = lex_param; p; p = p->next)
1285234949Sbapt	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1286234949Sbapt		    p->next ? ", " : "");
1287234949Sbapt	putl_code(fp, ")\n");
1288234949Sbapt
1289234949Sbapt	puts_code(fp, "# define YYLEX yylex(");
1290234949Sbapt	for (p = lex_param; p; p = p->next)
1291234949Sbapt	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1292234949Sbapt	putl_code(fp, ")\n");
1293234949Sbapt    }
1294234949Sbapt    else
1295234949Sbapt    {
1296234949Sbapt	putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1297234949Sbapt	putl_code(fp, "# define YYLEX yylex()\n");
1298234949Sbapt    }
1299234949Sbapt    putl_code(fp, "#endif\n");
1300234949Sbapt}
1301234949Sbapt
1302234949Sbaptstatic void
1303234949Sbaptoutput_error_decl(FILE * fp)
1304234949Sbapt{
1305234949Sbapt    putl_code(fp, "\n");
1306234949Sbapt    putl_code(fp, "/* Parameters sent to yyerror. */\n");
1307234949Sbapt    if (parse_param)
1308234949Sbapt    {
1309234949Sbapt	param *p;
1310234949Sbapt
1311234949Sbapt	putl_code(fp, "#ifndef YYERROR_DECL\n");
1312234949Sbapt	fprintf(fp, "#define YYERROR_DECL() yyerror(");
1313234949Sbapt	for (p = parse_param; p; p = p->next)
1314234949Sbapt	    fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
1315234949Sbapt	putl_code(fp, "const char *s)\n");
1316234949Sbapt	putl_code(fp, "#endif\n");
1317234949Sbapt
1318234949Sbapt	putl_code(fp, "#ifndef YYERROR_CALL\n");
1319234949Sbapt	puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1320234949Sbapt
1321234949Sbapt	for (p = parse_param; p; p = p->next)
1322234949Sbapt	    fprintf(fp, "%s, ", p->name);
1323234949Sbapt
1324234949Sbapt	putl_code(fp, "msg)\n");
1325234949Sbapt	putl_code(fp, "#endif\n");
1326234949Sbapt    }
1327234949Sbapt    else
1328234949Sbapt    {
1329234949Sbapt	putl_code(fp, "#ifndef YYERROR_DECL\n");
1330234949Sbapt	putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n");
1331234949Sbapt	putl_code(fp, "#endif\n");
1332234949Sbapt	putl_code(fp, "#ifndef YYERROR_CALL\n");
1333234949Sbapt	putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n");
1334234949Sbapt	putl_code(fp, "#endif\n");
1335234949Sbapt    }
1336234949Sbapt}
1337234949Sbapt
1338234949Sbaptstatic void
1339234949Sbaptfree_itemsets(void)
1340234949Sbapt{
1341234949Sbapt    core *cp, *next;
1342234949Sbapt
1343234949Sbapt    FREE(state_table);
1344234949Sbapt    for (cp = first_state; cp; cp = next)
1345234949Sbapt    {
1346234949Sbapt	next = cp->next;
1347234949Sbapt	FREE(cp);
1348234949Sbapt    }
1349234949Sbapt}
1350234949Sbapt
1351234949Sbaptstatic void
1352234949Sbaptfree_shifts(void)
1353234949Sbapt{
1354234949Sbapt    shifts *sp, *next;
1355234949Sbapt
1356234949Sbapt    FREE(shift_table);
1357234949Sbapt    for (sp = first_shift; sp; sp = next)
1358234949Sbapt    {
1359234949Sbapt	next = sp->next;
1360234949Sbapt	FREE(sp);
1361234949Sbapt    }
1362234949Sbapt}
1363234949Sbapt
1364234949Sbaptstatic void
1365234949Sbaptfree_reductions(void)
1366234949Sbapt{
1367234949Sbapt    reductions *rp, *next;
1368234949Sbapt
1369234949Sbapt    FREE(reduction_table);
1370234949Sbapt    for (rp = first_reduction; rp; rp = next)
1371234949Sbapt    {
1372234949Sbapt	next = rp->next;
1373234949Sbapt	FREE(rp);
1374234949Sbapt    }
1375234949Sbapt}
1376234949Sbapt
1377234949Sbaptstatic void
1378234949Sbaptoutput_yyerror_call(const char *msg)
1379234949Sbapt{
1380234949Sbapt    FILE *fp = code_file;
1381234949Sbapt
1382234949Sbapt    puts_code(fp, "    yyerror(");
1383234949Sbapt    if (parse_param)
1384234949Sbapt    {
1385234949Sbapt	param *p;
1386234949Sbapt	for (p = parse_param; p; p = p->next)
1387234949Sbapt	    fprintf(fp, "%s, ", p->name);
1388234949Sbapt    }
1389234949Sbapt    puts_code(fp, "\"");
1390234949Sbapt    puts_code(fp, msg);
1391234949Sbapt    putl_code(fp, "\");\n");
1392234949Sbapt}
1393234949Sbapt
1394234949Sbaptstatic void
1395234949Sbaptoutput_externs(FILE * fp, const char *const section[])
1396234949Sbapt{
1397234949Sbapt    int c;
1398234949Sbapt    int i;
1399234949Sbapt    const char *s;
1400234949Sbapt
1401234949Sbapt    for (i = 0; (s = section[i]) != 0; ++i)
1402234949Sbapt    {
1403234949Sbapt	if (*s && *s != '#')
1404234949Sbapt	    fputs("extern\t", fp);
1405234949Sbapt	while ((c = *s) != 0)
1406234949Sbapt	{
1407234949Sbapt	    putc(c, fp);
1408234949Sbapt	    ++s;
1409234949Sbapt	}
1410234949Sbapt	if (fp == code_file)
1411234949Sbapt	    ++outline;
1412234949Sbapt	putc('\n', fp);
1413234949Sbapt    }
1414234949Sbapt}
1415234949Sbapt
1416234949Sbaptvoid
1417234949Sbaptoutput(void)
1418234949Sbapt{
1419234949Sbapt    FILE *fp;
1420234949Sbapt
1421234949Sbapt    free_itemsets();
1422234949Sbapt    free_shifts();
1423234949Sbapt    free_reductions();
1424234949Sbapt
1425234949Sbapt    if (iflag)
1426234949Sbapt    {
1427234949Sbapt	++outline;
1428234949Sbapt	fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1429234949Sbapt	fp = externs_file;
1430234949Sbapt    }
1431234949Sbapt    else
1432234949Sbapt	fp = code_file;
1433234949Sbapt
1434234949Sbapt    output_prefix(iflag ? externs_file : output_file);
1435234949Sbapt    output_pure_parser(fp);
1436234949Sbapt    output_stored_text(fp);
1437234949Sbapt    output_stype(fp);
1438234949Sbapt    output_parse_decl(fp);
1439234949Sbapt    output_lex_decl(fp);
1440234949Sbapt    output_error_decl(fp);
1441234949Sbapt    write_section(fp, xdecls);
1442234949Sbapt
1443234949Sbapt    if (iflag)
1444234949Sbapt    {
1445234949Sbapt	output_externs(externs_file, global_vars);
1446234949Sbapt	if (!pure_parser)
1447234949Sbapt	    output_externs(externs_file, impure_vars);
1448234949Sbapt    }
1449234949Sbapt
1450234949Sbapt    if (iflag)
1451234949Sbapt    {
1452251143Sbapt	if (dflag)
1453251143Sbapt	{
1454251143Sbapt	    ++outline;
1455251143Sbapt	    fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1456251143Sbapt	}
1457251143Sbapt	else
1458234949Sbapt	    output_defines(externs_file);
1459234949Sbapt    }
1460234949Sbapt    else
1461234949Sbapt    {
1462234949Sbapt	putc_code(code_file, '\n');
1463234949Sbapt	output_defines(code_file);
1464234949Sbapt    }
1465234949Sbapt
1466234949Sbapt    if (dflag)
1467234949Sbapt	output_defines(defines_file);
1468234949Sbapt
1469234949Sbapt    output_rule_data();
1470234949Sbapt    output_yydefred();
1471234949Sbapt    output_actions();
1472234949Sbapt    free_parser();
1473234949Sbapt    output_debug();
1474234949Sbapt    if (rflag)
1475234949Sbapt    {
1476234949Sbapt	output_prefix(code_file);
1477234949Sbapt	write_section(code_file, xdecls);
1478234949Sbapt	write_section(code_file, tables);
1479234949Sbapt    }
1480234949Sbapt    write_section(code_file, global_vars);
1481234949Sbapt    if (!pure_parser)
1482234949Sbapt    {
1483234949Sbapt	write_section(code_file, impure_vars);
1484234949Sbapt    }
1485234949Sbapt    write_section(code_file, hdr_defs);
1486234949Sbapt    if (!pure_parser)
1487234949Sbapt    {
1488234949Sbapt	write_section(code_file, hdr_vars);
1489234949Sbapt    }
1490234949Sbapt    output_trailing_text();
1491234949Sbapt    write_section(code_file, body_1);
1492234949Sbapt    if (pure_parser)
1493234949Sbapt    {
1494234949Sbapt	write_section(code_file, body_vars);
1495234949Sbapt    }
1496234949Sbapt    write_section(code_file, body_2);
1497234949Sbapt    output_yyerror_call("syntax error");
1498234949Sbapt    write_section(code_file, body_3);
1499234949Sbapt    output_semantic_actions();
1500234949Sbapt    write_section(code_file, trailer);
1501234949Sbapt    output_yyerror_call("yacc stack overflow");
1502234949Sbapt    write_section(code_file, trailer_2);
1503234949Sbapt}
1504234949Sbapt
1505234949Sbapt#ifdef NO_LEAKS
1506234949Sbaptvoid
1507234949Sbaptoutput_leaks(void)
1508234949Sbapt{
1509234949Sbapt    DO_FREE(tally);
1510234949Sbapt    DO_FREE(width);
1511234949Sbapt    DO_FREE(order);
1512234949Sbapt}
1513234949Sbapt#endif
1514