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