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