1272955Srodrigc/* $Id: output.c,v 1.74 2014/10/05 23:21:09 tom Exp $ */
2234949Sbapt
3234949Sbapt#include "defs.h"
4234949Sbapt
5234949Sbapt#define StaticOrR	(rflag ? "" : "static ")
6234949Sbapt#define CountLine(fp)   (!rflag || ((fp) == code_file))
7234949Sbapt
8268899Sbapt#if defined(YYBTYACC)
9268899Sbapt#define PER_STATE 3
10268899Sbapt#else
11268899Sbapt#define PER_STATE 2
12268899Sbapt#endif
13268899Sbapt
14234949Sbaptstatic int nvectors;
15234949Sbaptstatic int nentries;
16234949Sbaptstatic Value_t **froms;
17234949Sbaptstatic Value_t **tos;
18268899Sbapt#if defined(YYBTYACC)
19268899Sbaptstatic Value_t *conflicts = NULL;
20268899Sbaptstatic Value_t nconflicts = 0;
21268899Sbapt#endif
22234949Sbaptstatic Value_t *tally;
23234949Sbaptstatic Value_t *width;
24234949Sbaptstatic Value_t *state_count;
25234949Sbaptstatic Value_t *order;
26234949Sbaptstatic Value_t *base;
27234949Sbaptstatic Value_t *pos;
28234949Sbaptstatic int maxtable;
29234949Sbaptstatic Value_t *table;
30234949Sbaptstatic Value_t *check;
31234949Sbaptstatic int lowzero;
32268899Sbaptstatic long high;
33234949Sbapt
34234949Sbaptstatic void
35234949Sbaptputc_code(FILE * fp, int c)
36234949Sbapt{
37234949Sbapt    if ((c == '\n') && (fp == code_file))
38234949Sbapt	++outline;
39234949Sbapt    putc(c, fp);
40234949Sbapt}
41234949Sbapt
42234949Sbaptstatic void
43234949Sbaptputl_code(FILE * fp, const char *s)
44234949Sbapt{
45234949Sbapt    if (fp == code_file)
46234949Sbapt	++outline;
47234949Sbapt    fputs(s, fp);
48234949Sbapt}
49234949Sbapt
50234949Sbaptstatic void
51234949Sbaptputs_code(FILE * fp, const char *s)
52234949Sbapt{
53234949Sbapt    fputs(s, fp);
54234949Sbapt}
55234949Sbapt
56234949Sbaptstatic void
57272955Srodrigcputs_param_types(FILE * fp, param * list, int more)
58272955Srodrigc{
59272955Srodrigc    param *p;
60272955Srodrigc
61272955Srodrigc    if (list != 0)
62272955Srodrigc    {
63272955Srodrigc	for (p = list; p; p = p->next)
64272955Srodrigc	{
65272955Srodrigc	    size_t len_type = strlen(p->type);
66272955Srodrigc	    fprintf(fp, "%s%s%s%s%s", p->type,
67272955Srodrigc		    (((len_type != 0) && (p->type[len_type - 1] == '*'))
68272955Srodrigc		     ? ""
69272955Srodrigc		     : " "),
70272955Srodrigc		    p->name, p->type2,
71272955Srodrigc		    ((more || p->next) ? ", " : ""));
72272955Srodrigc	}
73272955Srodrigc    }
74272955Srodrigc    else
75272955Srodrigc    {
76272955Srodrigc	if (!more)
77272955Srodrigc	    fprintf(fp, "void");
78272955Srodrigc    }
79272955Srodrigc}
80272955Srodrigc
81272955Srodrigcstatic void
82272955Srodrigcputs_param_names(FILE * fp, param * list, int more)
83272955Srodrigc{
84272955Srodrigc    param *p;
85272955Srodrigc
86272955Srodrigc    for (p = list; p; p = p->next)
87272955Srodrigc    {
88272955Srodrigc	fprintf(fp, "%s%s", p->name,
89272955Srodrigc		((more || p->next) ? ", " : ""));
90272955Srodrigc    }
91272955Srodrigc}
92272955Srodrigc
93272955Srodrigcstatic void
94234949Sbaptwrite_code_lineno(FILE * fp)
95234949Sbapt{
96234949Sbapt    if (!lflag && (fp == code_file))
97234949Sbapt    {
98234949Sbapt	++outline;
99268899Sbapt	fprintf(fp, line_format, outline + 1, code_file_name);
100234949Sbapt    }
101234949Sbapt}
102234949Sbapt
103234949Sbaptstatic void
104234949Sbaptwrite_input_lineno(void)
105234949Sbapt{
106234949Sbapt    if (!lflag)
107234949Sbapt    {
108234949Sbapt	++outline;
109234949Sbapt	fprintf(code_file, line_format, lineno, input_file_name);
110234949Sbapt    }
111234949Sbapt}
112234949Sbapt
113234949Sbaptstatic void
114234949Sbaptdefine_prefixed(FILE * fp, const char *name)
115234949Sbapt{
116234949Sbapt    int bump_line = CountLine(fp);
117234949Sbapt    if (bump_line)
118234949Sbapt	++outline;
119234949Sbapt    fprintf(fp, "\n");
120234949Sbapt
121234949Sbapt    if (bump_line)
122234949Sbapt	++outline;
123234949Sbapt    fprintf(fp, "#ifndef %s\n", name);
124234949Sbapt
125234949Sbapt    if (bump_line)
126234949Sbapt	++outline;
127234949Sbapt    fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
128234949Sbapt
129234949Sbapt    if (bump_line)
130234949Sbapt	++outline;
131234949Sbapt    fprintf(fp, "#endif /* %s */\n", name);
132234949Sbapt}
133234949Sbapt
134234949Sbaptstatic void
135234949Sbaptoutput_prefix(FILE * fp)
136234949Sbapt{
137234949Sbapt    if (symbol_prefix == NULL)
138234949Sbapt    {
139234949Sbapt	symbol_prefix = "yy";
140234949Sbapt    }
141234949Sbapt    else
142234949Sbapt    {
143234949Sbapt	define_prefixed(fp, "yyparse");
144234949Sbapt	define_prefixed(fp, "yylex");
145234949Sbapt	define_prefixed(fp, "yyerror");
146234949Sbapt	define_prefixed(fp, "yychar");
147234949Sbapt	define_prefixed(fp, "yyval");
148234949Sbapt	define_prefixed(fp, "yylval");
149234949Sbapt	define_prefixed(fp, "yydebug");
150234949Sbapt	define_prefixed(fp, "yynerrs");
151234949Sbapt	define_prefixed(fp, "yyerrflag");
152234949Sbapt	define_prefixed(fp, "yylhs");
153234949Sbapt	define_prefixed(fp, "yylen");
154234949Sbapt	define_prefixed(fp, "yydefred");
155268899Sbapt#if defined(YYBTYACC)
156268899Sbapt	define_prefixed(fp, "yystos");
157268899Sbapt#endif
158234949Sbapt	define_prefixed(fp, "yydgoto");
159234949Sbapt	define_prefixed(fp, "yysindex");
160234949Sbapt	define_prefixed(fp, "yyrindex");
161234949Sbapt	define_prefixed(fp, "yygindex");
162234949Sbapt	define_prefixed(fp, "yytable");
163234949Sbapt	define_prefixed(fp, "yycheck");
164234949Sbapt	define_prefixed(fp, "yyname");
165234949Sbapt	define_prefixed(fp, "yyrule");
166268899Sbapt#if defined(YYBTYACC)
167268899Sbapt	if (locations)
168268899Sbapt	{
169268899Sbapt	    define_prefixed(fp, "yyloc");
170268899Sbapt	    define_prefixed(fp, "yylloc");
171268899Sbapt	}
172268899Sbapt	putc_code(fp, '\n');
173268899Sbapt	putl_code(fp, "#if YYBTYACC\n");
174268899Sbapt
175268899Sbapt	define_prefixed(fp, "yycindex");
176268899Sbapt	define_prefixed(fp, "yyctable");
177268899Sbapt
178268899Sbapt	putc_code(fp, '\n');
179268899Sbapt	putl_code(fp, "#endif /* YYBTYACC */\n");
180268899Sbapt	putc_code(fp, '\n');
181268899Sbapt#endif
182234949Sbapt    }
183234949Sbapt    if (CountLine(fp))
184234949Sbapt	++outline;
185234949Sbapt    fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
186234949Sbapt}
187234949Sbapt
188234949Sbaptstatic void
189234949Sbaptoutput_newline(void)
190234949Sbapt{
191234949Sbapt    if (!rflag)
192234949Sbapt	++outline;
193234949Sbapt    putc('\n', output_file);
194234949Sbapt}
195234949Sbapt
196234949Sbaptstatic void
197234949Sbaptoutput_line(const char *value)
198234949Sbapt{
199234949Sbapt    fputs(value, output_file);
200234949Sbapt    output_newline();
201234949Sbapt}
202234949Sbapt
203234949Sbaptstatic void
204234949Sbaptoutput_int(int value)
205234949Sbapt{
206234949Sbapt    fprintf(output_file, "%5d,", value);
207234949Sbapt}
208234949Sbapt
209234949Sbaptstatic void
210234949Sbaptstart_int_table(const char *name, int value)
211234949Sbapt{
212234949Sbapt    int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
213234949Sbapt
214234949Sbapt    if (need < 6)
215234949Sbapt	need = 6;
216234949Sbapt    fprintf(output_file,
217268899Sbapt	    "%sconst YYINT %s%s[] = {%*d,",
218234949Sbapt	    StaticOrR, symbol_prefix, name, need, value);
219234949Sbapt}
220234949Sbapt
221234949Sbaptstatic void
222234949Sbaptstart_str_table(const char *name)
223234949Sbapt{
224234949Sbapt    fprintf(output_file,
225268899Sbapt	    "%sconst char *const %s%s[] = {",
226268899Sbapt	    StaticOrR, symbol_prefix, name);
227234949Sbapt    output_newline();
228234949Sbapt}
229234949Sbapt
230234949Sbaptstatic void
231234949Sbaptend_table(void)
232234949Sbapt{
233234949Sbapt    output_newline();
234234949Sbapt    output_line("};");
235234949Sbapt}
236234949Sbapt
237234949Sbaptstatic void
238268899Sbaptoutput_YYINT_typedef(FILE * fp)
239268899Sbapt{
240268899Sbapt    /* generate the type used to index the various parser tables */
241268899Sbapt    if (CountLine(fp))
242268899Sbapt	++outline;
243268899Sbapt    fprintf(fp, "typedef %s YYINT;\n", CONCAT1("", YYINT));
244268899Sbapt}
245268899Sbapt
246268899Sbaptstatic void
247234949Sbaptoutput_rule_data(void)
248234949Sbapt{
249234949Sbapt    int i;
250234949Sbapt    int j;
251234949Sbapt
252268899Sbapt    output_YYINT_typedef(output_file);
253268899Sbapt
254234949Sbapt    start_int_table("lhs", symbol_value[start_symbol]);
255234949Sbapt
256234949Sbapt    j = 10;
257234949Sbapt    for (i = 3; i < nrules; i++)
258234949Sbapt    {
259234949Sbapt	if (j >= 10)
260234949Sbapt	{
261234949Sbapt	    output_newline();
262234949Sbapt	    j = 1;
263234949Sbapt	}
264234949Sbapt	else
265234949Sbapt	    ++j;
266234949Sbapt
267234949Sbapt	output_int(symbol_value[rlhs[i]]);
268234949Sbapt    }
269234949Sbapt    end_table();
270234949Sbapt
271234949Sbapt    start_int_table("len", 2);
272234949Sbapt
273234949Sbapt    j = 10;
274234949Sbapt    for (i = 3; i < nrules; i++)
275234949Sbapt    {
276234949Sbapt	if (j >= 10)
277234949Sbapt	{
278234949Sbapt	    output_newline();
279234949Sbapt	    j = 1;
280234949Sbapt	}
281234949Sbapt	else
282234949Sbapt	    j++;
283234949Sbapt
284234949Sbapt	output_int(rrhs[i + 1] - rrhs[i] - 1);
285234949Sbapt    }
286234949Sbapt    end_table();
287234949Sbapt}
288234949Sbapt
289234949Sbaptstatic void
290234949Sbaptoutput_yydefred(void)
291234949Sbapt{
292234949Sbapt    int i, j;
293234949Sbapt
294234949Sbapt    start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
295234949Sbapt
296234949Sbapt    j = 10;
297234949Sbapt    for (i = 1; i < nstates; i++)
298234949Sbapt    {
299234949Sbapt	if (j < 10)
300234949Sbapt	    ++j;
301234949Sbapt	else
302234949Sbapt	{
303234949Sbapt	    output_newline();
304234949Sbapt	    j = 1;
305234949Sbapt	}
306234949Sbapt
307234949Sbapt	output_int((defred[i] ? defred[i] - 2 : 0));
308234949Sbapt    }
309234949Sbapt
310234949Sbapt    end_table();
311234949Sbapt}
312234949Sbapt
313268899Sbapt#if defined(YYBTYACC)
314234949Sbaptstatic void
315268899Sbaptoutput_accessing_symbols(void)
316268899Sbapt{
317268899Sbapt    int i, j;
318268899Sbapt    int *translate;
319268899Sbapt
320268899Sbapt    if (nstates != 0)
321268899Sbapt    {
322268899Sbapt	translate = TMALLOC(int, nstates);
323268899Sbapt	NO_SPACE(translate);
324268899Sbapt
325268899Sbapt	for (i = 0; i < nstates; ++i)
326268899Sbapt	{
327268899Sbapt	    int gsymb = accessing_symbol[i];
328268899Sbapt
329268899Sbapt	    translate[i] = symbol_pval[gsymb];
330268899Sbapt	}
331268899Sbapt
332268899Sbapt	/* yystos[] may be unused, depending on compile-time defines */
333268899Sbapt	start_int_table("stos", translate[0]);
334268899Sbapt
335268899Sbapt	j = 10;
336268899Sbapt	for (i = 1; i < nstates; ++i)
337268899Sbapt	{
338268899Sbapt	    if (j < 10)
339268899Sbapt		++j;
340268899Sbapt	    else
341268899Sbapt	    {
342268899Sbapt		output_newline();
343268899Sbapt		j = 1;
344268899Sbapt	    }
345268899Sbapt
346268899Sbapt	    output_int(translate[i]);
347268899Sbapt	}
348268899Sbapt
349268899Sbapt	end_table();
350268899Sbapt	FREE(translate);
351268899Sbapt    }
352268899Sbapt}
353268899Sbapt
354268899Sbaptstatic Value_t
355268899Sbaptfind_conflict_base(int cbase)
356268899Sbapt{
357268899Sbapt    int i, j;
358268899Sbapt
359268899Sbapt    for (i = 0; i < cbase; i++)
360268899Sbapt    {
361268899Sbapt	for (j = 0; j + cbase < nconflicts; j++)
362268899Sbapt	{
363268899Sbapt	    if (conflicts[i + j] != conflicts[cbase + j])
364268899Sbapt		break;
365268899Sbapt	}
366268899Sbapt	if (j + cbase >= nconflicts)
367268899Sbapt	    break;
368268899Sbapt    }
369268899Sbapt    return (Value_t) i;
370268899Sbapt}
371268899Sbapt#endif
372268899Sbapt
373268899Sbaptstatic void
374234949Sbapttoken_actions(void)
375234949Sbapt{
376234949Sbapt    int i, j;
377234949Sbapt    Value_t shiftcount, reducecount;
378268899Sbapt#if defined(YYBTYACC)
379268899Sbapt    Value_t conflictcount = 0;
380268899Sbapt    Value_t csym = -1;
381268899Sbapt    Value_t cbase = 0;
382268899Sbapt#endif
383234949Sbapt    int max, min;
384234949Sbapt    Value_t *actionrow, *r, *s;
385234949Sbapt    action *p;
386234949Sbapt
387268899Sbapt    actionrow = NEW2(PER_STATE * ntokens, Value_t);
388234949Sbapt    for (i = 0; i < nstates; ++i)
389234949Sbapt    {
390234949Sbapt	if (parser[i])
391234949Sbapt	{
392268899Sbapt	    for (j = 0; j < PER_STATE * ntokens; ++j)
393234949Sbapt		actionrow[j] = 0;
394234949Sbapt
395234949Sbapt	    shiftcount = 0;
396234949Sbapt	    reducecount = 0;
397268899Sbapt#if defined(YYBTYACC)
398268899Sbapt	    if (backtrack)
399268899Sbapt	    {
400268899Sbapt		conflictcount = 0;
401268899Sbapt		csym = -1;
402268899Sbapt		cbase = nconflicts;
403268899Sbapt	    }
404268899Sbapt#endif
405234949Sbapt	    for (p = parser[i]; p; p = p->next)
406234949Sbapt	    {
407268899Sbapt#if defined(YYBTYACC)
408268899Sbapt		if (backtrack)
409268899Sbapt		{
410268899Sbapt		    if (csym != -1 && csym != p->symbol)
411268899Sbapt		    {
412268899Sbapt			conflictcount++;
413268899Sbapt			conflicts[nconflicts++] = -1;
414268899Sbapt			j = find_conflict_base(cbase);
415268899Sbapt			actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
416268899Sbapt			if (j == cbase)
417268899Sbapt			{
418268899Sbapt			    cbase = nconflicts;
419268899Sbapt			}
420268899Sbapt			else
421268899Sbapt			{
422268899Sbapt			    if (conflicts[cbase] == -1)
423268899Sbapt				cbase++;
424268899Sbapt			    nconflicts = cbase;
425268899Sbapt			}
426268899Sbapt			csym = -1;
427268899Sbapt		    }
428268899Sbapt		}
429268899Sbapt#endif
430234949Sbapt		if (p->suppressed == 0)
431234949Sbapt		{
432234949Sbapt		    if (p->action_code == SHIFT)
433234949Sbapt		    {
434234949Sbapt			++shiftcount;
435234949Sbapt			actionrow[p->symbol] = p->number;
436234949Sbapt		    }
437234949Sbapt		    else if (p->action_code == REDUCE && p->number != defred[i])
438234949Sbapt		    {
439234949Sbapt			++reducecount;
440234949Sbapt			actionrow[p->symbol + ntokens] = p->number;
441234949Sbapt		    }
442234949Sbapt		}
443268899Sbapt#if defined(YYBTYACC)
444268899Sbapt		else if (backtrack && p->suppressed == 1)
445268899Sbapt		{
446268899Sbapt		    csym = p->symbol;
447268899Sbapt		    if (p->action_code == SHIFT)
448268899Sbapt		    {
449268899Sbapt			conflicts[nconflicts++] = p->number;
450268899Sbapt		    }
451268899Sbapt		    else if (p->action_code == REDUCE && p->number != defred[i])
452268899Sbapt		    {
453268899Sbapt			if (cbase == nconflicts)
454268899Sbapt			{
455268899Sbapt			    if (cbase)
456268899Sbapt				cbase--;
457268899Sbapt			    else
458268899Sbapt				conflicts[nconflicts++] = -1;
459268899Sbapt			}
460268899Sbapt			conflicts[nconflicts++] = (Value_t) (p->number - 2);
461268899Sbapt		    }
462268899Sbapt		}
463268899Sbapt#endif
464234949Sbapt	    }
465268899Sbapt#if defined(YYBTYACC)
466268899Sbapt	    if (backtrack && csym != -1)
467268899Sbapt	    {
468268899Sbapt		conflictcount++;
469268899Sbapt		conflicts[nconflicts++] = -1;
470268899Sbapt		j = find_conflict_base(cbase);
471268899Sbapt		actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
472268899Sbapt		if (j == cbase)
473268899Sbapt		{
474268899Sbapt		    cbase = nconflicts;
475268899Sbapt		}
476268899Sbapt		else
477268899Sbapt		{
478268899Sbapt		    if (conflicts[cbase] == -1)
479268899Sbapt			cbase++;
480268899Sbapt		    nconflicts = cbase;
481268899Sbapt		}
482268899Sbapt	    }
483268899Sbapt#endif
484234949Sbapt
485234949Sbapt	    tally[i] = shiftcount;
486234949Sbapt	    tally[nstates + i] = reducecount;
487268899Sbapt#if defined(YYBTYACC)
488268899Sbapt	    if (backtrack)
489268899Sbapt		tally[2 * nstates + i] = conflictcount;
490268899Sbapt#endif
491234949Sbapt	    width[i] = 0;
492234949Sbapt	    width[nstates + i] = 0;
493268899Sbapt#if defined(YYBTYACC)
494268899Sbapt	    if (backtrack)
495268899Sbapt		width[2 * nstates + i] = 0;
496268899Sbapt#endif
497234949Sbapt	    if (shiftcount > 0)
498234949Sbapt	    {
499234949Sbapt		froms[i] = r = NEW2(shiftcount, Value_t);
500234949Sbapt		tos[i] = s = NEW2(shiftcount, Value_t);
501268899Sbapt		min = MAXYYINT;
502234949Sbapt		max = 0;
503234949Sbapt		for (j = 0; j < ntokens; ++j)
504234949Sbapt		{
505234949Sbapt		    if (actionrow[j])
506234949Sbapt		    {
507234949Sbapt			if (min > symbol_value[j])
508234949Sbapt			    min = symbol_value[j];
509234949Sbapt			if (max < symbol_value[j])
510234949Sbapt			    max = symbol_value[j];
511234949Sbapt			*r++ = symbol_value[j];
512234949Sbapt			*s++ = actionrow[j];
513234949Sbapt		    }
514234949Sbapt		}
515234949Sbapt		width[i] = (Value_t) (max - min + 1);
516234949Sbapt	    }
517234949Sbapt	    if (reducecount > 0)
518234949Sbapt	    {
519234949Sbapt		froms[nstates + i] = r = NEW2(reducecount, Value_t);
520234949Sbapt		tos[nstates + i] = s = NEW2(reducecount, Value_t);
521268899Sbapt		min = MAXYYINT;
522234949Sbapt		max = 0;
523234949Sbapt		for (j = 0; j < ntokens; ++j)
524234949Sbapt		{
525234949Sbapt		    if (actionrow[ntokens + j])
526234949Sbapt		    {
527234949Sbapt			if (min > symbol_value[j])
528234949Sbapt			    min = symbol_value[j];
529234949Sbapt			if (max < symbol_value[j])
530234949Sbapt			    max = symbol_value[j];
531234949Sbapt			*r++ = symbol_value[j];
532234949Sbapt			*s++ = (Value_t) (actionrow[ntokens + j] - 2);
533234949Sbapt		    }
534234949Sbapt		}
535234949Sbapt		width[nstates + i] = (Value_t) (max - min + 1);
536234949Sbapt	    }
537268899Sbapt#if defined(YYBTYACC)
538268899Sbapt	    if (backtrack && conflictcount > 0)
539268899Sbapt	    {
540268899Sbapt		froms[2 * nstates + i] = r = NEW2(conflictcount, Value_t);
541268899Sbapt		tos[2 * nstates + i] = s = NEW2(conflictcount, Value_t);
542268899Sbapt		min = MAXYYINT;
543268899Sbapt		max = 0;
544268899Sbapt		for (j = 0; j < ntokens; ++j)
545268899Sbapt		{
546268899Sbapt		    if (actionrow[2 * ntokens + j])
547268899Sbapt		    {
548268899Sbapt			if (min > symbol_value[j])
549268899Sbapt			    min = symbol_value[j];
550268899Sbapt			if (max < symbol_value[j])
551268899Sbapt			    max = symbol_value[j];
552268899Sbapt			*r++ = symbol_value[j];
553268899Sbapt			*s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
554268899Sbapt		    }
555268899Sbapt		}
556268899Sbapt		width[2 * nstates + i] = (Value_t) (max - min + 1);
557268899Sbapt	    }
558268899Sbapt#endif
559234949Sbapt	}
560234949Sbapt    }
561234949Sbapt    FREE(actionrow);
562234949Sbapt}
563234949Sbapt
564234949Sbaptstatic int
565234949Sbaptdefault_goto(int symbol)
566234949Sbapt{
567234949Sbapt    int i;
568234949Sbapt    int m;
569234949Sbapt    int n;
570234949Sbapt    int default_state;
571234949Sbapt    int max;
572234949Sbapt
573234949Sbapt    m = goto_map[symbol];
574234949Sbapt    n = goto_map[symbol + 1];
575234949Sbapt
576234949Sbapt    if (m == n)
577234949Sbapt	return (0);
578234949Sbapt
579234949Sbapt    for (i = 0; i < nstates; i++)
580234949Sbapt	state_count[i] = 0;
581234949Sbapt
582234949Sbapt    for (i = m; i < n; i++)
583234949Sbapt	state_count[to_state[i]]++;
584234949Sbapt
585234949Sbapt    max = 0;
586234949Sbapt    default_state = 0;
587234949Sbapt    for (i = 0; i < nstates; i++)
588234949Sbapt    {
589234949Sbapt	if (state_count[i] > max)
590234949Sbapt	{
591234949Sbapt	    max = state_count[i];
592234949Sbapt	    default_state = i;
593234949Sbapt	}
594234949Sbapt    }
595234949Sbapt
596234949Sbapt    return (default_state);
597234949Sbapt}
598234949Sbapt
599234949Sbaptstatic void
600234949Sbaptsave_column(int symbol, int default_state)
601234949Sbapt{
602234949Sbapt    int i;
603234949Sbapt    int m;
604234949Sbapt    int n;
605234949Sbapt    Value_t *sp;
606234949Sbapt    Value_t *sp1;
607234949Sbapt    Value_t *sp2;
608234949Sbapt    Value_t count;
609234949Sbapt    int symno;
610234949Sbapt
611234949Sbapt    m = goto_map[symbol];
612234949Sbapt    n = goto_map[symbol + 1];
613234949Sbapt
614234949Sbapt    count = 0;
615234949Sbapt    for (i = m; i < n; i++)
616234949Sbapt    {
617234949Sbapt	if (to_state[i] != default_state)
618234949Sbapt	    ++count;
619234949Sbapt    }
620234949Sbapt    if (count == 0)
621234949Sbapt	return;
622234949Sbapt
623268899Sbapt    symno = symbol_value[symbol] + PER_STATE * nstates;
624234949Sbapt
625234949Sbapt    froms[symno] = sp1 = sp = NEW2(count, Value_t);
626234949Sbapt    tos[symno] = sp2 = NEW2(count, Value_t);
627234949Sbapt
628234949Sbapt    for (i = m; i < n; i++)
629234949Sbapt    {
630234949Sbapt	if (to_state[i] != default_state)
631234949Sbapt	{
632234949Sbapt	    *sp1++ = from_state[i];
633234949Sbapt	    *sp2++ = to_state[i];
634234949Sbapt	}
635234949Sbapt    }
636234949Sbapt
637234949Sbapt    tally[symno] = count;
638234949Sbapt    width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
639234949Sbapt}
640234949Sbapt
641234949Sbaptstatic void
642234949Sbaptgoto_actions(void)
643234949Sbapt{
644234949Sbapt    int i, j, k;
645234949Sbapt
646234949Sbapt    state_count = NEW2(nstates, Value_t);
647234949Sbapt
648234949Sbapt    k = default_goto(start_symbol + 1);
649234949Sbapt    start_int_table("dgoto", k);
650234949Sbapt    save_column(start_symbol + 1, k);
651234949Sbapt
652234949Sbapt    j = 10;
653234949Sbapt    for (i = start_symbol + 2; i < nsyms; i++)
654234949Sbapt    {
655234949Sbapt	if (j >= 10)
656234949Sbapt	{
657234949Sbapt	    output_newline();
658234949Sbapt	    j = 1;
659234949Sbapt	}
660234949Sbapt	else
661234949Sbapt	    ++j;
662234949Sbapt
663234949Sbapt	k = default_goto(i);
664234949Sbapt	output_int(k);
665234949Sbapt	save_column(i, k);
666234949Sbapt    }
667234949Sbapt
668234949Sbapt    end_table();
669234949Sbapt    FREE(state_count);
670234949Sbapt}
671234949Sbapt
672234949Sbaptstatic void
673234949Sbaptsort_actions(void)
674234949Sbapt{
675234949Sbapt    Value_t i;
676234949Sbapt    int j;
677234949Sbapt    int k;
678234949Sbapt    int t;
679234949Sbapt    int w;
680234949Sbapt
681234949Sbapt    order = NEW2(nvectors, Value_t);
682234949Sbapt    nentries = 0;
683234949Sbapt
684234949Sbapt    for (i = 0; i < nvectors; i++)
685234949Sbapt    {
686234949Sbapt	if (tally[i] > 0)
687234949Sbapt	{
688234949Sbapt	    t = tally[i];
689234949Sbapt	    w = width[i];
690234949Sbapt	    j = nentries - 1;
691234949Sbapt
692234949Sbapt	    while (j >= 0 && (width[order[j]] < w))
693234949Sbapt		j--;
694234949Sbapt
695234949Sbapt	    while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
696234949Sbapt		j--;
697234949Sbapt
698234949Sbapt	    for (k = nentries - 1; k > j; k--)
699234949Sbapt		order[k + 1] = order[k];
700234949Sbapt
701234949Sbapt	    order[j + 1] = i;
702234949Sbapt	    nentries++;
703234949Sbapt	}
704234949Sbapt    }
705234949Sbapt}
706234949Sbapt
707234949Sbapt/*  The function matching_vector determines if the vector specified by	*/
708234949Sbapt/*  the input parameter matches a previously considered	vector.  The	*/
709234949Sbapt/*  test at the start of the function checks if the vector represents	*/
710234949Sbapt/*  a row of shifts over terminal symbols or a row of reductions, or a	*/
711234949Sbapt/*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
712234949Sbapt/*  check if a column of shifts over a nonterminal symbols matches a	*/
713234949Sbapt/*  previously considered vector.  Because of the nature of LR parsing	*/
714234949Sbapt/*  tables, no two columns can match.  Therefore, the only possible	*/
715234949Sbapt/*  match would be between a row and a column.  Such matches are	*/
716234949Sbapt/*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
717234949Sbapt/*  column matches a previously considered vector.			*/
718234949Sbapt/*									*/
719234949Sbapt/*  Matching_vector is poorly designed.  The test could easily be made	*/
720234949Sbapt/*  faster.  Also, it depends on the vectors being in a specific	*/
721234949Sbapt/*  order.								*/
722268899Sbapt#if defined(YYBTYACC)
723268899Sbapt/*									*/
724268899Sbapt/*  Not really any point in checking for matching conflicts -- it is    */
725268899Sbapt/*  extremely unlikely to occur, and conflicts are (hopefully) rare.    */
726268899Sbapt#endif
727234949Sbapt
728234949Sbaptstatic int
729234949Sbaptmatching_vector(int vector)
730234949Sbapt{
731234949Sbapt    int i;
732234949Sbapt    int j;
733234949Sbapt    int k;
734234949Sbapt    int t;
735234949Sbapt    int w;
736234949Sbapt    int match;
737234949Sbapt    int prev;
738234949Sbapt
739234949Sbapt    i = order[vector];
740234949Sbapt    if (i >= 2 * nstates)
741234949Sbapt	return (-1);
742234949Sbapt
743234949Sbapt    t = tally[i];
744234949Sbapt    w = width[i];
745234949Sbapt
746234949Sbapt    for (prev = vector - 1; prev >= 0; prev--)
747234949Sbapt    {
748234949Sbapt	j = order[prev];
749234949Sbapt	if (width[j] != w || tally[j] != t)
750234949Sbapt	    return (-1);
751234949Sbapt
752234949Sbapt	match = 1;
753234949Sbapt	for (k = 0; match && k < t; k++)
754234949Sbapt	{
755234949Sbapt	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
756234949Sbapt		match = 0;
757234949Sbapt	}
758234949Sbapt
759234949Sbapt	if (match)
760234949Sbapt	    return (j);
761234949Sbapt    }
762234949Sbapt
763234949Sbapt    return (-1);
764234949Sbapt}
765234949Sbapt
766234949Sbaptstatic int
767234949Sbaptpack_vector(int vector)
768234949Sbapt{
769234949Sbapt    int i, j, k, l;
770234949Sbapt    int t;
771234949Sbapt    int loc;
772234949Sbapt    int ok;
773234949Sbapt    Value_t *from;
774234949Sbapt    Value_t *to;
775234949Sbapt    int newmax;
776234949Sbapt
777234949Sbapt    i = order[vector];
778234949Sbapt    t = tally[i];
779234949Sbapt    assert(t);
780234949Sbapt
781234949Sbapt    from = froms[i];
782234949Sbapt    to = tos[i];
783234949Sbapt
784234949Sbapt    j = lowzero - from[0];
785234949Sbapt    for (k = 1; k < t; ++k)
786234949Sbapt	if (lowzero - from[k] > j)
787234949Sbapt	    j = lowzero - from[k];
788234949Sbapt    for (;; ++j)
789234949Sbapt    {
790234949Sbapt	if (j == 0)
791234949Sbapt	    continue;
792234949Sbapt	ok = 1;
793234949Sbapt	for (k = 0; ok && k < t; k++)
794234949Sbapt	{
795234949Sbapt	    loc = j + from[k];
796234949Sbapt	    if (loc >= maxtable - 1)
797234949Sbapt	    {
798234949Sbapt		if (loc >= MAXTABLE - 1)
799234949Sbapt		    fatal("maximum table size exceeded");
800234949Sbapt
801234949Sbapt		newmax = maxtable;
802234949Sbapt		do
803234949Sbapt		{
804234949Sbapt		    newmax += 200;
805234949Sbapt		}
806234949Sbapt		while (newmax <= loc);
807234949Sbapt
808240517Sbapt		table = TREALLOC(Value_t, table, newmax);
809234949Sbapt		NO_SPACE(table);
810234949Sbapt
811240517Sbapt		check = TREALLOC(Value_t, check, newmax);
812234949Sbapt		NO_SPACE(check);
813234949Sbapt
814234949Sbapt		for (l = maxtable; l < newmax; ++l)
815234949Sbapt		{
816234949Sbapt		    table[l] = 0;
817234949Sbapt		    check[l] = -1;
818234949Sbapt		}
819234949Sbapt		maxtable = newmax;
820234949Sbapt	    }
821234949Sbapt
822234949Sbapt	    if (check[loc] != -1)
823234949Sbapt		ok = 0;
824234949Sbapt	}
825234949Sbapt	for (k = 0; ok && k < vector; k++)
826234949Sbapt	{
827234949Sbapt	    if (pos[k] == j)
828234949Sbapt		ok = 0;
829234949Sbapt	}
830234949Sbapt	if (ok)
831234949Sbapt	{
832234949Sbapt	    for (k = 0; k < t; k++)
833234949Sbapt	    {
834234949Sbapt		loc = j + from[k];
835234949Sbapt		table[loc] = to[k];
836234949Sbapt		check[loc] = from[k];
837234949Sbapt		if (loc > high)
838234949Sbapt		    high = loc;
839234949Sbapt	    }
840234949Sbapt
841234949Sbapt	    while (check[lowzero] != -1)
842234949Sbapt		++lowzero;
843234949Sbapt
844234949Sbapt	    return (j);
845234949Sbapt	}
846234949Sbapt    }
847234949Sbapt}
848234949Sbapt
849234949Sbaptstatic void
850234949Sbaptpack_table(void)
851234949Sbapt{
852234949Sbapt    int i;
853234949Sbapt    Value_t place;
854234949Sbapt    int state;
855234949Sbapt
856234949Sbapt    base = NEW2(nvectors, Value_t);
857234949Sbapt    pos = NEW2(nentries, Value_t);
858234949Sbapt
859234949Sbapt    maxtable = 1000;
860234949Sbapt    table = NEW2(maxtable, Value_t);
861234949Sbapt    check = NEW2(maxtable, Value_t);
862234949Sbapt
863234949Sbapt    lowzero = 0;
864234949Sbapt    high = 0;
865234949Sbapt
866234949Sbapt    for (i = 0; i < maxtable; i++)
867234949Sbapt	check[i] = -1;
868234949Sbapt
869234949Sbapt    for (i = 0; i < nentries; i++)
870234949Sbapt    {
871234949Sbapt	state = matching_vector(i);
872234949Sbapt
873234949Sbapt	if (state < 0)
874234949Sbapt	    place = (Value_t) pack_vector(i);
875234949Sbapt	else
876234949Sbapt	    place = base[state];
877234949Sbapt
878234949Sbapt	pos[i] = place;
879234949Sbapt	base[order[i]] = place;
880234949Sbapt    }
881234949Sbapt
882234949Sbapt    for (i = 0; i < nvectors; i++)
883234949Sbapt    {
884234949Sbapt	if (froms[i])
885234949Sbapt	    FREE(froms[i]);
886234949Sbapt	if (tos[i])
887234949Sbapt	    FREE(tos[i]);
888234949Sbapt    }
889234949Sbapt
890268899Sbapt    DO_FREE(froms);
891268899Sbapt    DO_FREE(tos);
892268899Sbapt    DO_FREE(tally);
893268899Sbapt    DO_FREE(width);
894268899Sbapt    DO_FREE(pos);
895234949Sbapt}
896234949Sbapt
897234949Sbaptstatic void
898234949Sbaptoutput_base(void)
899234949Sbapt{
900234949Sbapt    int i, j;
901234949Sbapt
902234949Sbapt    start_int_table("sindex", base[0]);
903234949Sbapt
904234949Sbapt    j = 10;
905234949Sbapt    for (i = 1; i < nstates; i++)
906234949Sbapt    {
907234949Sbapt	if (j >= 10)
908234949Sbapt	{
909234949Sbapt	    output_newline();
910234949Sbapt	    j = 1;
911234949Sbapt	}
912234949Sbapt	else
913234949Sbapt	    ++j;
914234949Sbapt
915234949Sbapt	output_int(base[i]);
916234949Sbapt    }
917234949Sbapt
918234949Sbapt    end_table();
919234949Sbapt
920234949Sbapt    start_int_table("rindex", base[nstates]);
921234949Sbapt
922234949Sbapt    j = 10;
923234949Sbapt    for (i = nstates + 1; i < 2 * nstates; i++)
924234949Sbapt    {
925234949Sbapt	if (j >= 10)
926234949Sbapt	{
927234949Sbapt	    output_newline();
928234949Sbapt	    j = 1;
929234949Sbapt	}
930234949Sbapt	else
931234949Sbapt	    ++j;
932234949Sbapt
933234949Sbapt	output_int(base[i]);
934234949Sbapt    }
935234949Sbapt
936234949Sbapt    end_table();
937234949Sbapt
938268899Sbapt#if defined(YYBTYACC)
939268899Sbapt    output_line("#if YYBTYACC");
940268899Sbapt    start_int_table("cindex", base[2 * nstates]);
941234949Sbapt
942234949Sbapt    j = 10;
943268899Sbapt    for (i = 2 * nstates + 1; i < 3 * nstates; i++)
944234949Sbapt    {
945234949Sbapt	if (j >= 10)
946234949Sbapt	{
947234949Sbapt	    output_newline();
948234949Sbapt	    j = 1;
949234949Sbapt	}
950234949Sbapt	else
951234949Sbapt	    ++j;
952234949Sbapt
953234949Sbapt	output_int(base[i]);
954234949Sbapt    }
955234949Sbapt
956234949Sbapt    end_table();
957268899Sbapt    output_line("#endif");
958268899Sbapt#endif
959268899Sbapt
960268899Sbapt    start_int_table("gindex", base[PER_STATE * nstates]);
961268899Sbapt
962268899Sbapt    j = 10;
963268899Sbapt    for (i = PER_STATE * nstates + 1; i < nvectors - 1; i++)
964268899Sbapt    {
965268899Sbapt	if (j >= 10)
966268899Sbapt	{
967268899Sbapt	    output_newline();
968268899Sbapt	    j = 1;
969268899Sbapt	}
970268899Sbapt	else
971268899Sbapt	    ++j;
972268899Sbapt
973268899Sbapt	output_int(base[i]);
974268899Sbapt    }
975268899Sbapt
976268899Sbapt    end_table();
977234949Sbapt    FREE(base);
978234949Sbapt}
979234949Sbapt
980234949Sbaptstatic void
981234949Sbaptoutput_table(void)
982234949Sbapt{
983234949Sbapt    int i;
984234949Sbapt    int j;
985234949Sbapt
986268899Sbapt    if (high >= MAXYYINT)
987268899Sbapt    {
988268899Sbapt	fprintf(stderr, "YYTABLESIZE: %ld\n", high);
989268899Sbapt	fprintf(stderr, "Table is longer than %d elements.\n", MAXYYINT);
990268899Sbapt	done(1);
991268899Sbapt    }
992268899Sbapt
993234949Sbapt    ++outline;
994268899Sbapt    fprintf(code_file, "#define YYTABLESIZE %ld\n", high);
995234949Sbapt    start_int_table("table", table[0]);
996234949Sbapt
997234949Sbapt    j = 10;
998234949Sbapt    for (i = 1; i <= high; i++)
999234949Sbapt    {
1000234949Sbapt	if (j >= 10)
1001234949Sbapt	{
1002234949Sbapt	    output_newline();
1003234949Sbapt	    j = 1;
1004234949Sbapt	}
1005234949Sbapt	else
1006234949Sbapt	    ++j;
1007234949Sbapt
1008234949Sbapt	output_int(table[i]);
1009234949Sbapt    }
1010234949Sbapt
1011234949Sbapt    end_table();
1012234949Sbapt    FREE(table);
1013234949Sbapt}
1014234949Sbapt
1015234949Sbaptstatic void
1016234949Sbaptoutput_check(void)
1017234949Sbapt{
1018234949Sbapt    int i;
1019234949Sbapt    int j;
1020234949Sbapt
1021234949Sbapt    start_int_table("check", check[0]);
1022234949Sbapt
1023234949Sbapt    j = 10;
1024234949Sbapt    for (i = 1; i <= high; i++)
1025234949Sbapt    {
1026234949Sbapt	if (j >= 10)
1027234949Sbapt	{
1028234949Sbapt	    output_newline();
1029234949Sbapt	    j = 1;
1030234949Sbapt	}
1031234949Sbapt	else
1032234949Sbapt	    ++j;
1033234949Sbapt
1034234949Sbapt	output_int(check[i]);
1035234949Sbapt    }
1036234949Sbapt
1037234949Sbapt    end_table();
1038234949Sbapt    FREE(check);
1039234949Sbapt}
1040234949Sbapt
1041268899Sbapt#if defined(YYBTYACC)
1042234949Sbaptstatic void
1043268899Sbaptoutput_ctable(void)
1044268899Sbapt{
1045268899Sbapt    int i;
1046268899Sbapt    int j;
1047272955Srodrigc    int limit = (conflicts != 0) ? nconflicts : 0;
1048268899Sbapt
1049272955Srodrigc    if (limit < high)
1050272955Srodrigc	limit = (int)high;
1051272955Srodrigc
1052272955Srodrigc    output_line("#if YYBTYACC");
1053272955Srodrigc    start_int_table("ctable", conflicts ? conflicts[0] : -1);
1054272955Srodrigc
1055272955Srodrigc    j = 10;
1056272955Srodrigc    for (i = 1; i < limit; i++)
1057268899Sbapt    {
1058272955Srodrigc	if (j >= 10)
1059268899Sbapt	{
1060272955Srodrigc	    output_newline();
1061272955Srodrigc	    j = 1;
1062268899Sbapt	}
1063272955Srodrigc	else
1064272955Srodrigc	    ++j;
1065268899Sbapt
1066272955Srodrigc	output_int((conflicts != 0 && i < nconflicts) ? conflicts[i] : -1);
1067272955Srodrigc    }
1068272955Srodrigc
1069272955Srodrigc    if (conflicts)
1070268899Sbapt	FREE(conflicts);
1071272955Srodrigc
1072272955Srodrigc    end_table();
1073272955Srodrigc    output_line("#endif");
1074268899Sbapt}
1075268899Sbapt#endif
1076268899Sbapt
1077268899Sbaptstatic void
1078234949Sbaptoutput_actions(void)
1079234949Sbapt{
1080268899Sbapt    nvectors = PER_STATE * nstates + nvars;
1081234949Sbapt
1082234949Sbapt    froms = NEW2(nvectors, Value_t *);
1083234949Sbapt    tos = NEW2(nvectors, Value_t *);
1084234949Sbapt    tally = NEW2(nvectors, Value_t);
1085234949Sbapt    width = NEW2(nvectors, Value_t);
1086234949Sbapt
1087268899Sbapt#if defined(YYBTYACC)
1088268899Sbapt    if (backtrack && (SRtotal + RRtotal) != 0)
1089268899Sbapt	conflicts = NEW2(4 * (SRtotal + RRtotal), Value_t);
1090268899Sbapt#endif
1091268899Sbapt
1092234949Sbapt    token_actions();
1093234949Sbapt    FREE(lookaheads);
1094234949Sbapt    FREE(LA);
1095234949Sbapt    FREE(LAruleno);
1096234949Sbapt    FREE(accessing_symbol);
1097234949Sbapt
1098234949Sbapt    goto_actions();
1099272955Srodrigc    FREE(goto_base);
1100234949Sbapt    FREE(from_state);
1101234949Sbapt    FREE(to_state);
1102234949Sbapt
1103234949Sbapt    sort_actions();
1104234949Sbapt    pack_table();
1105234949Sbapt    output_base();
1106234949Sbapt    output_table();
1107234949Sbapt    output_check();
1108268899Sbapt#if defined(YYBTYACC)
1109268899Sbapt    output_ctable();
1110268899Sbapt#endif
1111234949Sbapt}
1112234949Sbapt
1113234949Sbaptstatic int
1114234949Sbaptis_C_identifier(char *name)
1115234949Sbapt{
1116234949Sbapt    char *s;
1117234949Sbapt    int c;
1118234949Sbapt
1119234949Sbapt    s = name;
1120234949Sbapt    c = *s;
1121234949Sbapt    if (c == '"')
1122234949Sbapt    {
1123234949Sbapt	c = *++s;
1124234949Sbapt	if (!isalpha(c) && c != '_' && c != '$')
1125234949Sbapt	    return (0);
1126234949Sbapt	while ((c = *++s) != '"')
1127234949Sbapt	{
1128234949Sbapt	    if (!isalnum(c) && c != '_' && c != '$')
1129234949Sbapt		return (0);
1130234949Sbapt	}
1131234949Sbapt	return (1);
1132234949Sbapt    }
1133234949Sbapt
1134234949Sbapt    if (!isalpha(c) && c != '_' && c != '$')
1135234949Sbapt	return (0);
1136234949Sbapt    while ((c = *++s) != 0)
1137234949Sbapt    {
1138234949Sbapt	if (!isalnum(c) && c != '_' && c != '$')
1139234949Sbapt	    return (0);
1140234949Sbapt    }
1141234949Sbapt    return (1);
1142234949Sbapt}
1143234949Sbapt
1144268899Sbapt#if USE_HEADER_GUARDS
1145234949Sbaptstatic void
1146268899Sbaptstart_defines_file(void)
1147268899Sbapt{
1148268899Sbapt    fprintf(defines_file, "#ifndef _%s_defines_h_\n", symbol_prefix);
1149268899Sbapt    fprintf(defines_file, "#define _%s_defines_h_\n\n", symbol_prefix);
1150268899Sbapt}
1151268899Sbapt
1152268899Sbaptstatic void
1153268899Sbaptend_defines_file(void)
1154268899Sbapt{
1155268899Sbapt    fprintf(defines_file, "\n#endif /* _%s_defines_h_ */\n", symbol_prefix);
1156268899Sbapt}
1157268899Sbapt#else
1158268899Sbapt#define start_defines_file()	/* nothing */
1159268899Sbapt#define end_defines_file()	/* nothing */
1160268899Sbapt#endif
1161268899Sbapt
1162268899Sbaptstatic void
1163234949Sbaptoutput_defines(FILE * fp)
1164234949Sbapt{
1165234949Sbapt    int c, i;
1166234949Sbapt    char *s;
1167234949Sbapt
1168234949Sbapt    for (i = 2; i < ntokens; ++i)
1169234949Sbapt    {
1170234949Sbapt	s = symbol_name[i];
1171234949Sbapt	if (is_C_identifier(s) && (!sflag || *s != '"'))
1172234949Sbapt	{
1173234949Sbapt	    fprintf(fp, "#define ");
1174234949Sbapt	    c = *s;
1175234949Sbapt	    if (c == '"')
1176234949Sbapt	    {
1177234949Sbapt		while ((c = *++s) != '"')
1178234949Sbapt		{
1179234949Sbapt		    putc(c, fp);
1180234949Sbapt		}
1181234949Sbapt	    }
1182234949Sbapt	    else
1183234949Sbapt	    {
1184234949Sbapt		do
1185234949Sbapt		{
1186234949Sbapt		    putc(c, fp);
1187234949Sbapt		}
1188234949Sbapt		while ((c = *++s) != 0);
1189234949Sbapt	    }
1190234949Sbapt	    if (fp == code_file)
1191234949Sbapt		++outline;
1192234949Sbapt	    fprintf(fp, " %d\n", symbol_value[i]);
1193234949Sbapt	}
1194234949Sbapt    }
1195234949Sbapt
1196234949Sbapt    if (fp == code_file)
1197234949Sbapt	++outline;
1198234949Sbapt    if (fp != defines_file || iflag)
1199234949Sbapt	fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
1200234949Sbapt
1201234949Sbapt    if (fp == defines_file || (iflag && !dflag))
1202234949Sbapt    {
1203234949Sbapt	if (unionized)
1204234949Sbapt	{
1205251143Sbapt	    if (union_file != 0)
1206251143Sbapt	    {
1207251143Sbapt		rewind(union_file);
1208251143Sbapt		while ((c = getc(union_file)) != EOF)
1209268899Sbapt		    putc_code(fp, c);
1210251143Sbapt	    }
1211234949Sbapt	    fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
1212234949Sbapt	}
1213234949Sbapt    }
1214234949Sbapt}
1215234949Sbapt
1216234949Sbaptstatic void
1217234949Sbaptoutput_stored_text(FILE * fp)
1218234949Sbapt{
1219234949Sbapt    int c;
1220234949Sbapt    FILE *in;
1221234949Sbapt
1222234949Sbapt    rewind(text_file);
1223234949Sbapt    if (text_file == NULL)
1224234949Sbapt	open_error("text_file");
1225234949Sbapt    in = text_file;
1226234949Sbapt    if ((c = getc(in)) == EOF)
1227234949Sbapt	return;
1228234949Sbapt    putc_code(fp, c);
1229234949Sbapt    while ((c = getc(in)) != EOF)
1230234949Sbapt    {
1231234949Sbapt	putc_code(fp, c);
1232234949Sbapt    }
1233234949Sbapt    write_code_lineno(fp);
1234234949Sbapt}
1235234949Sbapt
1236234949Sbaptstatic void
1237234949Sbaptoutput_debug(void)
1238234949Sbapt{
1239268899Sbapt    int i, j, k, max, maxtok;
1240234949Sbapt    const char **symnam;
1241234949Sbapt    const char *s;
1242234949Sbapt
1243234949Sbapt    ++outline;
1244234949Sbapt    fprintf(code_file, "#define YYFINAL %d\n", final_state);
1245234949Sbapt
1246234949Sbapt    putl_code(code_file, "#ifndef YYDEBUG\n");
1247234949Sbapt    ++outline;
1248234949Sbapt    fprintf(code_file, "#define YYDEBUG %d\n", tflag);
1249234949Sbapt    putl_code(code_file, "#endif\n");
1250234949Sbapt
1251234949Sbapt    if (rflag)
1252234949Sbapt    {
1253234949Sbapt	fprintf(output_file, "#ifndef YYDEBUG\n");
1254234949Sbapt	fprintf(output_file, "#define YYDEBUG %d\n", tflag);
1255234949Sbapt	fprintf(output_file, "#endif\n");
1256234949Sbapt    }
1257234949Sbapt
1258268899Sbapt    maxtok = 0;
1259268899Sbapt    for (i = 0; i < ntokens; ++i)
1260268899Sbapt	if (symbol_value[i] > maxtok)
1261268899Sbapt	    maxtok = symbol_value[i];
1262234949Sbapt
1263268899Sbapt    /* symbol_value[$accept] = -1         */
1264268899Sbapt    /* symbol_value[<goal>]  = 0          */
1265268899Sbapt    /* remaining non-terminals start at 1 */
1266268899Sbapt    max = maxtok;
1267268899Sbapt    for (i = ntokens; i < nsyms; ++i)
1268268899Sbapt	if (((maxtok + 1) + (symbol_value[i] + 1)) > max)
1269268899Sbapt	    max = (maxtok + 1) + (symbol_value[i] + 1);
1270268899Sbapt
1271234949Sbapt    ++outline;
1272268899Sbapt    fprintf(code_file, "#define YYMAXTOKEN %d\n", maxtok);
1273234949Sbapt
1274268899Sbapt    ++outline;
1275268899Sbapt    fprintf(code_file, "#define YYUNDFTOKEN %d\n", max + 1);
1276268899Sbapt
1277268899Sbapt    ++outline;
1278268899Sbapt    fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
1279268899Sbapt	    "YYUNDFTOKEN : (a))\n");
1280268899Sbapt
1281268899Sbapt    symnam = TMALLOC(const char *, max + 2);
1282234949Sbapt    NO_SPACE(symnam);
1283234949Sbapt
1284268899Sbapt    /* Note that it is not necessary to initialize the element          */
1285234949Sbapt    /* symnam[max].                                                     */
1286268899Sbapt#if defined(YYBTYACC)
1287234949Sbapt    for (i = 0; i < max; ++i)
1288234949Sbapt	symnam[i] = 0;
1289268899Sbapt    for (i = nsyms - 1; i >= 0; --i)
1290268899Sbapt	symnam[symbol_pval[i]] = symbol_name[i];
1291268899Sbapt    symnam[max + 1] = "illegal-symbol";
1292268899Sbapt#else
1293268899Sbapt    for (i = 0; i <= max; ++i)
1294268899Sbapt	symnam[i] = 0;
1295234949Sbapt    for (i = ntokens - 1; i >= 2; --i)
1296234949Sbapt	symnam[symbol_value[i]] = symbol_name[i];
1297234949Sbapt    symnam[0] = "end-of-file";
1298268899Sbapt    symnam[max + 1] = "illegal-symbol";
1299268899Sbapt#endif
1300234949Sbapt
1301268899Sbapt    /*
1302268899Sbapt     * bison's yytname[] array is roughly the same as byacc's yyname[] array.
1303268899Sbapt     * The difference is that byacc does not predefine "$undefined".
1304268899Sbapt     *
1305268899Sbapt     * If the grammar declares "%token-table", define symbol "yytname" so
1306268899Sbapt     * an application such as ntpd can build.
1307268899Sbapt     */
1308268899Sbapt    if (token_table)
1309268899Sbapt    {
1310268899Sbapt	output_line("#undef yytname");
1311268899Sbapt	output_line("#define yytname yyname");
1312268899Sbapt    }
1313268899Sbapt    else
1314268899Sbapt    {
1315268899Sbapt	output_line("#if YYDEBUG");
1316268899Sbapt    }
1317234949Sbapt
1318234949Sbapt    start_str_table("name");
1319234949Sbapt    j = 80;
1320268899Sbapt    for (i = 0; i <= max + 1; ++i)
1321234949Sbapt    {
1322234949Sbapt	if ((s = symnam[i]) != 0)
1323234949Sbapt	{
1324234949Sbapt	    if (s[0] == '"')
1325234949Sbapt	    {
1326234949Sbapt		k = 7;
1327234949Sbapt		while (*++s != '"')
1328234949Sbapt		{
1329234949Sbapt		    ++k;
1330234949Sbapt		    if (*s == '\\')
1331234949Sbapt		    {
1332234949Sbapt			k += 2;
1333234949Sbapt			if (*++s == '\\')
1334234949Sbapt			    ++k;
1335234949Sbapt		    }
1336234949Sbapt		}
1337234949Sbapt		j += k;
1338234949Sbapt		if (j > 80)
1339234949Sbapt		{
1340234949Sbapt		    output_newline();
1341234949Sbapt		    j = k;
1342234949Sbapt		}
1343234949Sbapt		fprintf(output_file, "\"\\\"");
1344234949Sbapt		s = symnam[i];
1345234949Sbapt		while (*++s != '"')
1346234949Sbapt		{
1347234949Sbapt		    if (*s == '\\')
1348234949Sbapt		    {
1349234949Sbapt			fprintf(output_file, "\\\\");
1350234949Sbapt			if (*++s == '\\')
1351234949Sbapt			    fprintf(output_file, "\\\\");
1352234949Sbapt			else
1353234949Sbapt			    putc(*s, output_file);
1354234949Sbapt		    }
1355234949Sbapt		    else
1356234949Sbapt			putc(*s, output_file);
1357234949Sbapt		}
1358234949Sbapt		fprintf(output_file, "\\\"\",");
1359234949Sbapt	    }
1360234949Sbapt	    else if (s[0] == '\'')
1361234949Sbapt	    {
1362234949Sbapt		if (s[1] == '"')
1363234949Sbapt		{
1364234949Sbapt		    j += 7;
1365234949Sbapt		    if (j > 80)
1366234949Sbapt		    {
1367234949Sbapt			output_newline();
1368234949Sbapt			j = 7;
1369234949Sbapt		    }
1370234949Sbapt		    fprintf(output_file, "\"'\\\"'\",");
1371234949Sbapt		}
1372234949Sbapt		else
1373234949Sbapt		{
1374234949Sbapt		    k = 5;
1375234949Sbapt		    while (*++s != '\'')
1376234949Sbapt		    {
1377234949Sbapt			++k;
1378234949Sbapt			if (*s == '\\')
1379234949Sbapt			{
1380234949Sbapt			    k += 2;
1381234949Sbapt			    if (*++s == '\\')
1382234949Sbapt				++k;
1383234949Sbapt			}
1384234949Sbapt		    }
1385234949Sbapt		    j += k;
1386234949Sbapt		    if (j > 80)
1387234949Sbapt		    {
1388234949Sbapt			output_newline();
1389234949Sbapt			j = k;
1390234949Sbapt		    }
1391234949Sbapt		    fprintf(output_file, "\"'");
1392234949Sbapt		    s = symnam[i];
1393234949Sbapt		    while (*++s != '\'')
1394234949Sbapt		    {
1395234949Sbapt			if (*s == '\\')
1396234949Sbapt			{
1397234949Sbapt			    fprintf(output_file, "\\\\");
1398234949Sbapt			    if (*++s == '\\')
1399234949Sbapt				fprintf(output_file, "\\\\");
1400234949Sbapt			    else
1401234949Sbapt				putc(*s, output_file);
1402234949Sbapt			}
1403234949Sbapt			else
1404234949Sbapt			    putc(*s, output_file);
1405234949Sbapt		    }
1406234949Sbapt		    fprintf(output_file, "'\",");
1407234949Sbapt		}
1408234949Sbapt	    }
1409234949Sbapt	    else
1410234949Sbapt	    {
1411234949Sbapt		k = (int)strlen(s) + 3;
1412234949Sbapt		j += k;
1413234949Sbapt		if (j > 80)
1414234949Sbapt		{
1415234949Sbapt		    output_newline();
1416234949Sbapt		    j = k;
1417234949Sbapt		}
1418234949Sbapt		putc('"', output_file);
1419234949Sbapt		do
1420234949Sbapt		{
1421234949Sbapt		    putc(*s, output_file);
1422234949Sbapt		}
1423234949Sbapt		while (*++s);
1424234949Sbapt		fprintf(output_file, "\",");
1425234949Sbapt	    }
1426234949Sbapt	}
1427234949Sbapt	else
1428234949Sbapt	{
1429234949Sbapt	    j += 2;
1430234949Sbapt	    if (j > 80)
1431234949Sbapt	    {
1432234949Sbapt		output_newline();
1433234949Sbapt		j = 2;
1434234949Sbapt	    }
1435234949Sbapt	    fprintf(output_file, "0,");
1436234949Sbapt	}
1437234949Sbapt    }
1438234949Sbapt    end_table();
1439234949Sbapt    FREE(symnam);
1440234949Sbapt
1441268899Sbapt    if (token_table)
1442268899Sbapt	output_line("#if YYDEBUG");
1443234949Sbapt    start_str_table("rule");
1444234949Sbapt    for (i = 2; i < nrules; ++i)
1445234949Sbapt    {
1446234949Sbapt	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1447234949Sbapt	for (j = rrhs[i]; ritem[j] > 0; ++j)
1448234949Sbapt	{
1449234949Sbapt	    s = symbol_name[ritem[j]];
1450234949Sbapt	    if (s[0] == '"')
1451234949Sbapt	    {
1452234949Sbapt		fprintf(output_file, " \\\"");
1453234949Sbapt		while (*++s != '"')
1454234949Sbapt		{
1455234949Sbapt		    if (*s == '\\')
1456234949Sbapt		    {
1457234949Sbapt			if (s[1] == '\\')
1458234949Sbapt			    fprintf(output_file, "\\\\\\\\");
1459234949Sbapt			else
1460234949Sbapt			    fprintf(output_file, "\\\\%c", s[1]);
1461234949Sbapt			++s;
1462234949Sbapt		    }
1463234949Sbapt		    else
1464234949Sbapt			putc(*s, output_file);
1465234949Sbapt		}
1466234949Sbapt		fprintf(output_file, "\\\"");
1467234949Sbapt	    }
1468234949Sbapt	    else if (s[0] == '\'')
1469234949Sbapt	    {
1470234949Sbapt		if (s[1] == '"')
1471234949Sbapt		    fprintf(output_file, " '\\\"'");
1472234949Sbapt		else if (s[1] == '\\')
1473234949Sbapt		{
1474234949Sbapt		    if (s[2] == '\\')
1475234949Sbapt			fprintf(output_file, " '\\\\\\\\");
1476234949Sbapt		    else
1477234949Sbapt			fprintf(output_file, " '\\\\%c", s[2]);
1478234949Sbapt		    s += 2;
1479234949Sbapt		    while (*++s != '\'')
1480234949Sbapt			putc(*s, output_file);
1481234949Sbapt		    putc('\'', output_file);
1482234949Sbapt		}
1483234949Sbapt		else
1484234949Sbapt		    fprintf(output_file, " '%c'", s[1]);
1485234949Sbapt	    }
1486234949Sbapt	    else
1487234949Sbapt		fprintf(output_file, " %s", s);
1488234949Sbapt	}
1489234949Sbapt	fprintf(output_file, "\",");
1490234949Sbapt	output_newline();
1491234949Sbapt    }
1492234949Sbapt
1493234949Sbapt    end_table();
1494234949Sbapt    output_line("#endif");
1495234949Sbapt}
1496234949Sbapt
1497268899Sbapt#if defined(YYBTYACC)
1498234949Sbaptstatic void
1499268899Sbaptoutput_backtracking_parser(FILE * fp)
1500268899Sbapt{
1501268899Sbapt    putl_code(fp, "#undef YYBTYACC\n");
1502268899Sbapt#if defined(YYBTYACC)
1503268899Sbapt    if (backtrack)
1504268899Sbapt    {
1505268899Sbapt	putl_code(fp, "#define YYBTYACC 1\n");
1506268899Sbapt	putl_code(fp,
1507268899Sbapt		  "#define YYDEBUGSTR (yytrial ? YYPREFIX \"debug(trial)\" : YYPREFIX \"debug\")\n");
1508268899Sbapt    }
1509268899Sbapt    else
1510268899Sbapt#endif
1511268899Sbapt    {
1512268899Sbapt	putl_code(fp, "#define YYBTYACC 0\n");
1513268899Sbapt	putl_code(fp, "#define YYDEBUGSTR YYPREFIX \"debug\"\n");
1514268899Sbapt    }
1515268899Sbapt}
1516268899Sbapt#endif
1517268899Sbapt
1518268899Sbaptstatic void
1519234949Sbaptoutput_pure_parser(FILE * fp)
1520234949Sbapt{
1521234949Sbapt    putc_code(fp, '\n');
1522234949Sbapt
1523234949Sbapt    if (fp == code_file)
1524268899Sbapt	++outline;
1525234949Sbapt    fprintf(fp, "#define YYPURE %d\n", pure_parser);
1526234949Sbapt    putc_code(fp, '\n');
1527234949Sbapt}
1528234949Sbapt
1529234949Sbaptstatic void
1530234949Sbaptoutput_stype(FILE * fp)
1531234949Sbapt{
1532234949Sbapt    if (!unionized && ntags == 0)
1533234949Sbapt    {
1534234949Sbapt	putc_code(fp, '\n');
1535268899Sbapt	putl_code(fp, "#if "
1536268899Sbapt		  "! defined(YYSTYPE) && "
1537268899Sbapt		  "! defined(YYSTYPE_IS_DECLARED)\n");
1538268899Sbapt	putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
1539234949Sbapt	putl_code(fp, "typedef int YYSTYPE;\n");
1540268899Sbapt	putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
1541234949Sbapt	putl_code(fp, "#endif\n");
1542234949Sbapt    }
1543234949Sbapt}
1544234949Sbapt
1545268899Sbapt#if defined(YYBTYACC)
1546234949Sbaptstatic void
1547268899Sbaptoutput_ltype(FILE * fp)
1548268899Sbapt{
1549268899Sbapt    putc_code(fp, '\n');
1550268899Sbapt    putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
1551268899Sbapt    putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
1552268899Sbapt    putl_code(fp, "typedef struct YYLTYPE\n");
1553268899Sbapt    putl_code(fp, "{\n");
1554268899Sbapt    putl_code(fp, "    int first_line;\n");
1555268899Sbapt    putl_code(fp, "    int first_column;\n");
1556268899Sbapt    putl_code(fp, "    int last_line;\n");
1557268899Sbapt    putl_code(fp, "    int last_column;\n");
1558268899Sbapt    putl_code(fp, "} YYLTYPE;\n");
1559268899Sbapt    putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
1560268899Sbapt    putl_code(fp, "#endif\n");
1561268899Sbapt}
1562268899Sbapt#endif
1563268899Sbapt
1564268899Sbaptstatic void
1565234949Sbaptoutput_trailing_text(void)
1566234949Sbapt{
1567234949Sbapt    int c, last;
1568234949Sbapt    FILE *in;
1569234949Sbapt
1570234949Sbapt    if (line == 0)
1571234949Sbapt	return;
1572234949Sbapt
1573234949Sbapt    in = input_file;
1574234949Sbapt    c = *cptr;
1575234949Sbapt    if (c == '\n')
1576234949Sbapt    {
1577234949Sbapt	++lineno;
1578234949Sbapt	if ((c = getc(in)) == EOF)
1579234949Sbapt	    return;
1580234949Sbapt	write_input_lineno();
1581234949Sbapt	putc_code(code_file, c);
1582234949Sbapt	last = c;
1583234949Sbapt    }
1584234949Sbapt    else
1585234949Sbapt    {
1586234949Sbapt	write_input_lineno();
1587234949Sbapt	do
1588234949Sbapt	{
1589234949Sbapt	    putc_code(code_file, c);
1590234949Sbapt	}
1591234949Sbapt	while ((c = *++cptr) != '\n');
1592234949Sbapt	putc_code(code_file, c);
1593234949Sbapt	last = '\n';
1594234949Sbapt    }
1595234949Sbapt
1596234949Sbapt    while ((c = getc(in)) != EOF)
1597234949Sbapt    {
1598234949Sbapt	putc_code(code_file, c);
1599234949Sbapt	last = c;
1600234949Sbapt    }
1601234949Sbapt
1602234949Sbapt    if (last != '\n')
1603234949Sbapt    {
1604234949Sbapt	putc_code(code_file, '\n');
1605234949Sbapt    }
1606234949Sbapt    write_code_lineno(code_file);
1607234949Sbapt}
1608234949Sbapt
1609234949Sbaptstatic void
1610234949Sbaptoutput_semantic_actions(void)
1611234949Sbapt{
1612234949Sbapt    int c, last;
1613234949Sbapt
1614234949Sbapt    rewind(action_file);
1615234949Sbapt    if ((c = getc(action_file)) == EOF)
1616234949Sbapt	return;
1617234949Sbapt
1618234949Sbapt    last = c;
1619234949Sbapt    putc_code(code_file, c);
1620234949Sbapt    while ((c = getc(action_file)) != EOF)
1621234949Sbapt    {
1622234949Sbapt	putc_code(code_file, c);
1623234949Sbapt	last = c;
1624234949Sbapt    }
1625234949Sbapt
1626234949Sbapt    if (last != '\n')
1627234949Sbapt    {
1628234949Sbapt	putc_code(code_file, '\n');
1629234949Sbapt    }
1630234949Sbapt
1631234949Sbapt    write_code_lineno(code_file);
1632234949Sbapt}
1633234949Sbapt
1634234949Sbaptstatic void
1635234949Sbaptoutput_parse_decl(FILE * fp)
1636234949Sbapt{
1637268899Sbapt    putc_code(fp, '\n');
1638234949Sbapt    putl_code(fp, "/* compatibility with bison */\n");
1639234949Sbapt    putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1640234949Sbapt    putl_code(fp, "/* compatibility with FreeBSD */\n");
1641234949Sbapt    putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1642234949Sbapt    putl_code(fp,
1643234949Sbapt	      "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1644234949Sbapt    putl_code(fp, "# else\n");
1645234949Sbapt    putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1646234949Sbapt    putl_code(fp, "# endif\n");
1647234949Sbapt    putl_code(fp, "#else\n");
1648234949Sbapt
1649234949Sbapt    puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1650272955Srodrigc    puts_param_types(fp, parse_param, 0);
1651234949Sbapt    putl_code(fp, ")\n");
1652234949Sbapt
1653234949Sbapt    putl_code(fp, "#endif\n");
1654234949Sbapt}
1655234949Sbapt
1656234949Sbaptstatic void
1657234949Sbaptoutput_lex_decl(FILE * fp)
1658234949Sbapt{
1659268899Sbapt    putc_code(fp, '\n');
1660234949Sbapt    putl_code(fp, "/* Parameters sent to lex. */\n");
1661234949Sbapt    putl_code(fp, "#ifdef YYLEX_PARAM\n");
1662234949Sbapt    if (pure_parser)
1663234949Sbapt    {
1664234949Sbapt	putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1665268899Sbapt#if defined(YYBTYACC)
1666268899Sbapt	if (locations)
1667268899Sbapt	{
1668272955Srodrigc	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1669272955Srodrigc		      " YYLTYPE *yylloc,"
1670268899Sbapt		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1671268899Sbapt	}
1672268899Sbapt	else
1673268899Sbapt#endif
1674268899Sbapt	{
1675268899Sbapt	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1676268899Sbapt		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1677268899Sbapt	}
1678234949Sbapt	putl_code(fp, "# else\n");
1679268899Sbapt#if defined(YYBTYACC)
1680268899Sbapt	if (locations)
1681268899Sbapt	{
1682272955Srodrigc	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1683272955Srodrigc		      " YYLTYPE *yylloc,"
1684268899Sbapt		      " void * YYLEX_PARAM)\n");
1685268899Sbapt	}
1686268899Sbapt	else
1687268899Sbapt#endif
1688268899Sbapt	{
1689268899Sbapt	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1690268899Sbapt		      " void * YYLEX_PARAM)\n");
1691268899Sbapt	}
1692234949Sbapt	putl_code(fp, "# endif\n");
1693268899Sbapt#if defined(YYBTYACC)
1694268899Sbapt	if (locations)
1695268899Sbapt	    putl_code(fp,
1696268899Sbapt		      "# define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)\n");
1697268899Sbapt	else
1698268899Sbapt#endif
1699268899Sbapt	    putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1700234949Sbapt    }
1701234949Sbapt    else
1702234949Sbapt    {
1703234949Sbapt	putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1704234949Sbapt	putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1705234949Sbapt    }
1706234949Sbapt    putl_code(fp, "#else\n");
1707234949Sbapt    if (pure_parser && lex_param)
1708234949Sbapt    {
1709268899Sbapt#if defined(YYBTYACC)
1710268899Sbapt	if (locations)
1711268899Sbapt	    puts_code(fp,
1712268899Sbapt		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc, ");
1713268899Sbapt	else
1714268899Sbapt#endif
1715268899Sbapt	    puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1716272955Srodrigc	puts_param_types(fp, lex_param, 0);
1717234949Sbapt	putl_code(fp, ")\n");
1718234949Sbapt
1719268899Sbapt#if defined(YYBTYACC)
1720268899Sbapt	if (locations)
1721268899Sbapt	    puts_code(fp, "# define YYLEX yylex(&yylval, &yylloc, ");
1722268899Sbapt	else
1723268899Sbapt#endif
1724268899Sbapt	    puts_code(fp, "# define YYLEX yylex(&yylval, ");
1725272955Srodrigc	puts_param_names(fp, lex_param, 0);
1726234949Sbapt	putl_code(fp, ")\n");
1727234949Sbapt    }
1728234949Sbapt    else if (pure_parser)
1729234949Sbapt    {
1730268899Sbapt#if defined(YYBTYACC)
1731268899Sbapt	if (locations)
1732268899Sbapt	{
1733268899Sbapt	    putl_code(fp,
1734268899Sbapt		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc)\n");
1735268899Sbapt	    putl_code(fp, "# define YYLEX yylex(&yylval, &yylloc)\n");
1736268899Sbapt	}
1737268899Sbapt	else
1738268899Sbapt#endif
1739268899Sbapt	{
1740268899Sbapt	    putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1741268899Sbapt	    putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1742268899Sbapt	}
1743234949Sbapt    }
1744234949Sbapt    else if (lex_param)
1745234949Sbapt    {
1746234949Sbapt	puts_code(fp, "# define YYLEX_DECL() yylex(");
1747272955Srodrigc	puts_param_types(fp, lex_param, 0);
1748234949Sbapt	putl_code(fp, ")\n");
1749234949Sbapt
1750234949Sbapt	puts_code(fp, "# define YYLEX yylex(");
1751272955Srodrigc	puts_param_names(fp, lex_param, 0);
1752234949Sbapt	putl_code(fp, ")\n");
1753234949Sbapt    }
1754234949Sbapt    else
1755234949Sbapt    {
1756234949Sbapt	putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1757234949Sbapt	putl_code(fp, "# define YYLEX yylex()\n");
1758234949Sbapt    }
1759234949Sbapt    putl_code(fp, "#endif\n");
1760234949Sbapt}
1761234949Sbapt
1762234949Sbaptstatic void
1763234949Sbaptoutput_error_decl(FILE * fp)
1764234949Sbapt{
1765268899Sbapt    putc_code(fp, '\n');
1766234949Sbapt    putl_code(fp, "/* Parameters sent to yyerror. */\n");
1767268899Sbapt    putl_code(fp, "#ifndef YYERROR_DECL\n");
1768268899Sbapt    puts_code(fp, "#define YYERROR_DECL() yyerror(");
1769268899Sbapt#if defined(YYBTYACC)
1770268899Sbapt    if (locations)
1771268899Sbapt	puts_code(fp, "YYLTYPE loc, ");
1772268899Sbapt#endif
1773272955Srodrigc    puts_param_types(fp, parse_param, 1);
1774268899Sbapt    putl_code(fp, "const char *s)\n");
1775268899Sbapt    putl_code(fp, "#endif\n");
1776234949Sbapt
1777268899Sbapt    putl_code(fp, "#ifndef YYERROR_CALL\n");
1778272955Srodrigc
1779268899Sbapt    puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1780268899Sbapt#if defined(YYBTYACC)
1781268899Sbapt    if (locations)
1782268899Sbapt	puts_code(fp, "yylloc, ");
1783268899Sbapt#endif
1784272955Srodrigc    puts_param_names(fp, parse_param, 1);
1785272955Srodrigc    putl_code(fp, "msg)\n");
1786234949Sbapt
1787268899Sbapt    putl_code(fp, "#endif\n");
1788268899Sbapt}
1789234949Sbapt
1790268899Sbapt#if defined(YYBTYACC)
1791268899Sbaptstatic void
1792268899Sbaptoutput_yydestruct_decl(FILE * fp)
1793268899Sbapt{
1794268899Sbapt    putc_code(fp, '\n');
1795268899Sbapt    putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
1796272955Srodrigc
1797272955Srodrigc    puts_code(fp,
1798272955Srodrigc	      "#define YYDESTRUCT_DECL() "
1799272955Srodrigc	      "yydestruct(const char *msg, int psymb, YYSTYPE *val");
1800268899Sbapt#if defined(YYBTYACC)
1801268899Sbapt    if (locations)
1802272955Srodrigc	puts_code(fp, ", YYLTYPE *loc");
1803268899Sbapt#endif
1804272955Srodrigc    if (parse_param)
1805272955Srodrigc    {
1806272955Srodrigc	puts_code(fp, ", ");
1807272955Srodrigc	puts_param_types(fp, parse_param, 0);
1808272955Srodrigc    }
1809272955Srodrigc    putl_code(fp, ")\n");
1810272955Srodrigc
1811268899Sbapt    putl_code(fp, "#endif\n");
1812272955Srodrigc
1813268899Sbapt    putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
1814272955Srodrigc
1815272955Srodrigc    puts_code(fp, "#define YYDESTRUCT_CALL(msg, psymb, val");
1816268899Sbapt#if defined(YYBTYACC)
1817268899Sbapt    if (locations)
1818272955Srodrigc	puts_code(fp, ", loc");
1819268899Sbapt#endif
1820272955Srodrigc    puts_code(fp, ") yydestruct(msg, psymb, val");
1821272955Srodrigc#if defined(YYBTYACC)
1822272955Srodrigc    if (locations)
1823272955Srodrigc	puts_code(fp, ", loc");
1824272955Srodrigc#endif
1825272955Srodrigc    if (parse_param)
1826272955Srodrigc    {
1827272955Srodrigc	puts_code(fp, ", ");
1828272955Srodrigc	puts_param_names(fp, parse_param, 0);
1829272955Srodrigc    }
1830272955Srodrigc    putl_code(fp, ")\n");
1831272955Srodrigc
1832268899Sbapt    putl_code(fp, "#endif\n");
1833268899Sbapt}
1834268899Sbapt
1835268899Sbaptstatic void
1836268899Sbaptoutput_yydestruct_impl(void)
1837268899Sbapt{
1838268899Sbapt    int i;
1839268899Sbapt    char *s, *destructor_code;
1840268899Sbapt
1841268899Sbapt    putc_code(code_file, '\n');
1842268899Sbapt    putl_code(code_file, "/* Release memory associated with symbol. */\n");
1843268899Sbapt    putl_code(code_file, "#if ! defined YYDESTRUCT_IS_DECLARED\n");
1844268899Sbapt    putl_code(code_file, "static void\n");
1845268899Sbapt    putl_code(code_file, "YYDESTRUCT_DECL()\n");
1846268899Sbapt    putl_code(code_file, "{\n");
1847268899Sbapt    putl_code(code_file, "    switch (psymb)\n");
1848268899Sbapt    putl_code(code_file, "    {\n");
1849268899Sbapt    for (i = 2; i < nsyms; ++i)
1850234949Sbapt    {
1851268899Sbapt	if ((destructor_code = symbol_destructor[i]) != NULL)
1852268899Sbapt	{
1853268899Sbapt	    ++outline;
1854268899Sbapt	    fprintf(code_file, "\tcase %d:\n", symbol_pval[i]);
1855268899Sbapt	    /* comprehend the number of lines in the destructor code */
1856268899Sbapt	    for (s = destructor_code; (s = strchr(s, '\n')) != NULL; s++)
1857268899Sbapt		++outline;
1858268899Sbapt	    puts_code(code_file, destructor_code);
1859268899Sbapt	    putc_code(code_file, '\n');
1860268899Sbapt	    putl_code(code_file, "\tbreak;\n");
1861268899Sbapt	    write_code_lineno(code_file);
1862268899Sbapt	    FREE(destructor_code);
1863268899Sbapt	}
1864234949Sbapt    }
1865268899Sbapt    putl_code(code_file, "    }\n");
1866268899Sbapt    putl_code(code_file, "}\n");
1867268899Sbapt    putl_code(code_file, "#define YYDESTRUCT_IS_DECLARED 1\n");
1868268899Sbapt    putl_code(code_file, "#endif\n");
1869268899Sbapt
1870268899Sbapt    DO_FREE(symbol_destructor);
1871234949Sbapt}
1872268899Sbapt#endif
1873234949Sbapt
1874234949Sbaptstatic void
1875234949Sbaptfree_itemsets(void)
1876234949Sbapt{
1877234949Sbapt    core *cp, *next;
1878234949Sbapt
1879234949Sbapt    FREE(state_table);
1880234949Sbapt    for (cp = first_state; cp; cp = next)
1881234949Sbapt    {
1882234949Sbapt	next = cp->next;
1883234949Sbapt	FREE(cp);
1884234949Sbapt    }
1885234949Sbapt}
1886234949Sbapt
1887234949Sbaptstatic void
1888234949Sbaptfree_shifts(void)
1889234949Sbapt{
1890234949Sbapt    shifts *sp, *next;
1891234949Sbapt
1892234949Sbapt    FREE(shift_table);
1893234949Sbapt    for (sp = first_shift; sp; sp = next)
1894234949Sbapt    {
1895234949Sbapt	next = sp->next;
1896234949Sbapt	FREE(sp);
1897234949Sbapt    }
1898234949Sbapt}
1899234949Sbapt
1900234949Sbaptstatic void
1901234949Sbaptfree_reductions(void)
1902234949Sbapt{
1903234949Sbapt    reductions *rp, *next;
1904234949Sbapt
1905234949Sbapt    FREE(reduction_table);
1906234949Sbapt    for (rp = first_reduction; rp; rp = next)
1907234949Sbapt    {
1908234949Sbapt	next = rp->next;
1909234949Sbapt	FREE(rp);
1910234949Sbapt    }
1911234949Sbapt}
1912234949Sbapt
1913234949Sbaptstatic void
1914234949Sbaptoutput_externs(FILE * fp, const char *const section[])
1915234949Sbapt{
1916234949Sbapt    int i;
1917234949Sbapt    const char *s;
1918234949Sbapt
1919234949Sbapt    for (i = 0; (s = section[i]) != 0; ++i)
1920234949Sbapt    {
1921268899Sbapt	/* prefix non-blank lines that don't start with
1922268899Sbapt	   C pre-processor directives with 'extern ' */
1923268899Sbapt	if (*s && (*s != '#'))
1924234949Sbapt	    fputs("extern\t", fp);
1925234949Sbapt	if (fp == code_file)
1926234949Sbapt	    ++outline;
1927268899Sbapt	fprintf(fp, "%s\n", s);
1928234949Sbapt    }
1929234949Sbapt}
1930234949Sbapt
1931234949Sbaptvoid
1932234949Sbaptoutput(void)
1933234949Sbapt{
1934234949Sbapt    FILE *fp;
1935234949Sbapt
1936234949Sbapt    free_itemsets();
1937234949Sbapt    free_shifts();
1938234949Sbapt    free_reductions();
1939234949Sbapt
1940268899Sbapt#if defined(YYBTYACC)
1941268899Sbapt    output_backtracking_parser(output_file);
1942268899Sbapt    if (rflag)
1943268899Sbapt	output_backtracking_parser(code_file);
1944268899Sbapt#endif
1945268899Sbapt
1946234949Sbapt    if (iflag)
1947234949Sbapt    {
1948268899Sbapt	write_code_lineno(code_file);
1949234949Sbapt	++outline;
1950234949Sbapt	fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1951234949Sbapt	fp = externs_file;
1952234949Sbapt    }
1953234949Sbapt    else
1954234949Sbapt	fp = code_file;
1955234949Sbapt
1956268899Sbapt    output_prefix(fp);
1957234949Sbapt    output_pure_parser(fp);
1958234949Sbapt    output_stored_text(fp);
1959234949Sbapt    output_stype(fp);
1960268899Sbapt#if defined(YYBTYACC)
1961268899Sbapt    if (locations)
1962268899Sbapt	output_ltype(fp);
1963268899Sbapt#endif
1964234949Sbapt    output_parse_decl(fp);
1965234949Sbapt    output_lex_decl(fp);
1966234949Sbapt    output_error_decl(fp);
1967268899Sbapt#if defined(YYBTYACC)
1968268899Sbapt    if (destructor)
1969268899Sbapt	output_yydestruct_decl(fp);
1970268899Sbapt#endif
1971268899Sbapt    if (iflag || !rflag)
1972268899Sbapt    {
1973268899Sbapt	write_section(fp, xdecls);
1974268899Sbapt    }
1975234949Sbapt
1976234949Sbapt    if (iflag)
1977234949Sbapt    {
1978234949Sbapt	output_externs(externs_file, global_vars);
1979234949Sbapt	if (!pure_parser)
1980234949Sbapt	    output_externs(externs_file, impure_vars);
1981234949Sbapt    }
1982234949Sbapt
1983234949Sbapt    if (iflag)
1984234949Sbapt    {
1985251143Sbapt	if (dflag)
1986251143Sbapt	{
1987251143Sbapt	    ++outline;
1988251143Sbapt	    fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1989251143Sbapt	}
1990251143Sbapt	else
1991234949Sbapt	    output_defines(externs_file);
1992234949Sbapt    }
1993234949Sbapt    else
1994234949Sbapt    {
1995234949Sbapt	putc_code(code_file, '\n');
1996234949Sbapt	output_defines(code_file);
1997234949Sbapt    }
1998234949Sbapt
1999234949Sbapt    if (dflag)
2000268899Sbapt    {
2001268899Sbapt	start_defines_file();
2002234949Sbapt	output_defines(defines_file);
2003268899Sbapt	end_defines_file();
2004268899Sbapt    }
2005234949Sbapt
2006234949Sbapt    output_rule_data();
2007234949Sbapt    output_yydefred();
2008268899Sbapt#if defined(YYBTYACC)
2009268899Sbapt    output_accessing_symbols();
2010268899Sbapt#endif
2011234949Sbapt    output_actions();
2012234949Sbapt    free_parser();
2013234949Sbapt    output_debug();
2014234949Sbapt    if (rflag)
2015234949Sbapt    {
2016234949Sbapt	write_section(code_file, xdecls);
2017268899Sbapt	output_YYINT_typedef(code_file);
2018234949Sbapt	write_section(code_file, tables);
2019234949Sbapt    }
2020234949Sbapt    write_section(code_file, global_vars);
2021234949Sbapt    if (!pure_parser)
2022234949Sbapt    {
2023234949Sbapt	write_section(code_file, impure_vars);
2024234949Sbapt    }
2025234949Sbapt    write_section(code_file, hdr_defs);
2026234949Sbapt    if (!pure_parser)
2027234949Sbapt    {
2028234949Sbapt	write_section(code_file, hdr_vars);
2029234949Sbapt    }
2030234949Sbapt    output_trailing_text();
2031268899Sbapt#if defined(YYBTYACC)
2032268899Sbapt    if (destructor)
2033268899Sbapt	output_yydestruct_impl();
2034268899Sbapt#endif
2035234949Sbapt    write_section(code_file, body_1);
2036234949Sbapt    if (pure_parser)
2037234949Sbapt    {
2038234949Sbapt	write_section(code_file, body_vars);
2039234949Sbapt    }
2040234949Sbapt    write_section(code_file, body_2);
2041234949Sbapt    output_semantic_actions();
2042234949Sbapt    write_section(code_file, trailer);
2043234949Sbapt}
2044234949Sbapt
2045234949Sbapt#ifdef NO_LEAKS
2046234949Sbaptvoid
2047234949Sbaptoutput_leaks(void)
2048234949Sbapt{
2049234949Sbapt    DO_FREE(tally);
2050234949Sbapt    DO_FREE(width);
2051234949Sbapt    DO_FREE(order);
2052234949Sbapt}
2053234949Sbapt#endif
2054