fatbase

portable OpenBSD tools
git clone git://git.2f30.org/fatbase
Log | Files | Refs

output.c (24165B)


      1 /*	$OpenBSD: output.c,v 1.23 2014/03/13 01:18:22 tedu Exp $	*/
      2 /*	$NetBSD: output.c,v 1.4 1996/03/19 03:21:41 jtc Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 1989 The Regents of the University of California.
      6  * All rights reserved.
      7  *
      8  * This code is derived from software contributed to Berkeley by
      9  * Robert Paul Corbett.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #include "defs.h"
     37 
     38 static int nvectors;
     39 static int nentries;
     40 static short **froms;
     41 static short **tos;
     42 static short *tally;
     43 static short *width;
     44 static short *state_count;
     45 static short *order;
     46 static short *base;
     47 static short *pos;
     48 static int maxtable;
     49 static short *table;
     50 static short *check;
     51 static int lowzero;
     52 static int high;
     53 
     54 void output_prefix(void);
     55 void output_rule_data(void);
     56 void output_yydefred(void);
     57 void output_actions(void);
     58 void token_actions(void);
     59 void goto_actions(void);
     60 int default_goto(int);
     61 void save_column(int, int);
     62 void sort_actions(void);
     63 void pack_table(void);
     64 int matching_vector(int);
     65 int pack_vector(int);
     66 void output_base(void);
     67 void output_table(void);
     68 void output_check(void);
     69 int is_C_identifier(char *);
     70 void output_defines(void);
     71 void output_stored_text(void);
     72 void output_debug(void);
     73 void output_stype(void);
     74 void output_trailing_text(void);
     75 void output_semantic_actions(void);
     76 void free_itemsets(void);
     77 void free_shifts(void);
     78 void free_reductions(void);
     79 
     80 void
     81 output(void)
     82 {
     83 	free_itemsets();
     84 	free_shifts();
     85 	free_reductions();
     86 	output_prefix();
     87 	output_stored_text();
     88 	output_defines();
     89 	output_rule_data();
     90 	output_yydefred();
     91 	output_actions();
     92 	free_parser();
     93 	output_debug();
     94 	output_stype();
     95 	if (rflag)
     96 		write_section(tables);
     97 	write_section(header);
     98 	output_trailing_text();
     99 	write_section(body);
    100 	output_semantic_actions();
    101 	write_section(trailer);
    102 }
    103 
    104 
    105 void
    106 output_prefix(void)
    107 {
    108 	if (symbol_prefix == NULL)
    109 		symbol_prefix = "yy";
    110 	else {
    111 		++outline;
    112 		fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
    113 		++outline;
    114 		fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
    115 		++outline;
    116 		fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
    117 		++outline;
    118 		fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
    119 		++outline;
    120 		fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
    121 		++outline;
    122 		fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
    123 		++outline;
    124 		fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
    125 		++outline;
    126 		fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
    127 		++outline;
    128 		fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
    129 		++outline;
    130 		fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
    131 		++outline;
    132 		fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix);
    133 		++outline;
    134 		fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
    135 		++outline;
    136 		fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
    137 		++outline;
    138 		fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
    139 		++outline;
    140 		fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix);
    141 		++outline;
    142 		fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
    143 		++outline;
    144 		fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
    145 		++outline;
    146 		fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
    147 		++outline;
    148 		fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
    149 		++outline;
    150 		fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
    151 		++outline;
    152 		fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
    153 		++outline;
    154 		fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
    155 		++outline;
    156 		fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
    157 		++outline;
    158 		fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
    159 		++outline;
    160 		fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
    161 		++outline;
    162 		fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
    163 	}
    164 	++outline;
    165 	fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
    166 }
    167 
    168 
    169 void
    170 output_rule_data(void)
    171 {
    172 	int i;
    173 	int j;
    174 
    175 	fprintf(output_file,
    176 	    "const short %slhs[] =\n"
    177 	    "\t{%42d,", symbol_prefix, symbol_value[start_symbol]);
    178 
    179 	j = 10;
    180 	for (i = 3; i < nrules; i++) {
    181 		if (j >= 10) {
    182 			if (!rflag)
    183 				++outline;
    184 			putc('\n', output_file);
    185 			j = 1;
    186 		} else
    187 			++j;
    188 		fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
    189 	}
    190 	if (!rflag)
    191 		outline += 2;
    192 	fprintf(output_file, "\n};\n");
    193 
    194 	fprintf(output_file,
    195 	    "const short %slen[] =\n"
    196 	    "\t{%42d,", symbol_prefix, 2);
    197 
    198 	j = 10;
    199 	for (i = 3; i < nrules; i++) {
    200 		if (j >= 10) {
    201 			if (!rflag)
    202 				++outline;
    203 			putc('\n', output_file);
    204 			j = 1;
    205 		} else
    206 			j++;
    207 		fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
    208 	}
    209 	if (!rflag)
    210 		outline += 2;
    211 	fprintf(output_file, "\n};\n");
    212 }
    213 
    214 
    215 void
    216 output_yydefred(void)
    217 {
    218 	int i, j;
    219 
    220 	fprintf(output_file,
    221 	    "const short %sdefred[] =\n"
    222 	    "\t{%39d,",
    223 	    symbol_prefix, (defred[0] ? defred[0] - 2 : 0));
    224 
    225 	j = 10;
    226 	for (i = 1; i < nstates; i++) {
    227 		if (j < 10)
    228 			++j;
    229 		else {
    230 			if (!rflag)
    231 				++outline;
    232 			putc('\n', output_file);
    233 			j = 1;
    234 		}
    235 		fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
    236 	}
    237 
    238 	if (!rflag)
    239 		outline += 2;
    240 	fprintf(output_file, "\n};\n");
    241 }
    242 
    243 
    244 void
    245 output_actions(void)
    246 {
    247 	nvectors = 2 * nstates + nvars;
    248 
    249 	froms = NEW2(nvectors, short *);
    250 	tos = NEW2(nvectors, short *);
    251 	tally = NEW2(nvectors, short);
    252 	width = NEW2(nvectors, short);
    253 
    254 	token_actions();
    255 	free(lookaheads);
    256 	free(LA);
    257 	free(LAruleno);
    258 	free(accessing_symbol);
    259 
    260 	goto_actions();
    261 	free(goto_map + ntokens);
    262 	free(from_state);
    263 	free(to_state);
    264 
    265 	sort_actions();
    266 	pack_table();
    267 	output_base();
    268 	output_table();
    269 	output_check();
    270 }
    271 
    272 
    273 void
    274 token_actions(void)
    275 {
    276 	int i, j;
    277 	int shiftcount, reducecount;
    278 	int max, min;
    279 	short *actionrow, *r, *s;
    280 	action *p;
    281 
    282 	actionrow = NEW2(2*ntokens, short);
    283 	for (i = 0; i < nstates; ++i) {
    284 	if (parser[i]) {
    285 		for (j = 0; j < 2 * ntokens; ++j)
    286 			actionrow[j] = 0;
    287 			shiftcount = 0;
    288 			reducecount = 0;
    289 			for (p = parser[i]; p; p = p->next) {
    290 				if (p->suppressed == 0) {
    291 					if (p->action_code == SHIFT) {
    292 						++shiftcount;
    293 						actionrow[p->symbol] = p->number;
    294 					} else if (p->action_code == REDUCE &&
    295 					    p->number != defred[i]) {
    296 						++reducecount;
    297 						actionrow[p->symbol + ntokens] = p->number;
    298 					}
    299 				}
    300 			}
    301 
    302 			tally[i] = shiftcount;
    303 			tally[nstates+i] = reducecount;
    304 			width[i] = 0;
    305 			width[nstates+i] = 0;
    306 			if (shiftcount > 0) {
    307 				froms[i] = r = NEW2(shiftcount, short);
    308 				tos[i] = s = NEW2(shiftcount, short);
    309 				min = MAXSHORT;
    310 				max = 0;
    311 				for (j = 0; j < ntokens; ++j) {
    312 					if (actionrow[j]) {
    313 						if (min > symbol_value[j])
    314 							min = symbol_value[j];
    315 						if (max < symbol_value[j])
    316 							max = symbol_value[j];
    317 						*r++ = symbol_value[j];
    318 						*s++ = actionrow[j];
    319 					}
    320 				}
    321 				width[i] = max - min + 1;
    322 			}
    323 			if (reducecount > 0) {
    324 				froms[nstates+i] = r = NEW2(reducecount, short);
    325 				tos[nstates+i] = s = NEW2(reducecount, short);
    326 				min = MAXSHORT;
    327 				max = 0;
    328 				for (j = 0; j < ntokens; ++j) {
    329 					if (actionrow[ntokens+j]) {
    330 						if (min > symbol_value[j])
    331 							min = symbol_value[j];
    332 						if (max < symbol_value[j])
    333 							max = symbol_value[j];
    334 						*r++ = symbol_value[j];
    335 						*s++ = actionrow[ntokens+j] - 2;
    336 					}
    337 				}
    338 				width[nstates+i] = max - min + 1;
    339 			}
    340 		}
    341 	}
    342 	free(actionrow);
    343 }
    344 
    345 void
    346 goto_actions(void)
    347 {
    348 	int i, j, k;
    349 
    350 	state_count = NEW2(nstates, short);
    351 
    352 	k = default_goto(start_symbol + 1);
    353 	fprintf(output_file, "const short %sdgoto[] =\n"
    354 	    "\t{%40d,", symbol_prefix, k);
    355 	save_column(start_symbol + 1, k);
    356 
    357 	j = 10;
    358 	for (i = start_symbol + 2; i < nsyms; i++) {
    359 		if (j >= 10) {
    360 			if (!rflag)
    361 				++outline;
    362 			putc('\n', output_file);
    363 			j = 1;
    364 		} else
    365 			++j;
    366 
    367 		k = default_goto(i);
    368 		fprintf(output_file, "%5d,", k);
    369 		save_column(i, k);
    370 	}
    371 
    372 	if (!rflag)
    373 		outline += 2;
    374 	fprintf(output_file, "\n};\n");
    375 	free(state_count);
    376 }
    377 
    378 int
    379 default_goto(int symbol)
    380 {
    381 	int i;
    382 	int m;
    383 	int n;
    384 	int default_state;
    385 	int max;
    386 
    387 	m = goto_map[symbol];
    388 	n = goto_map[symbol + 1];
    389 
    390 	if (m == n)
    391 		return (0);
    392 
    393 	memset(state_count, 0, nstates * sizeof(short));
    394 
    395 	for (i = m; i < n; i++)
    396 		state_count[to_state[i]]++;
    397 
    398 	max = 0;
    399 	default_state = 0;
    400 	for (i = 0; i < nstates; i++) {
    401 		if (state_count[i] > max) {
    402 			max = state_count[i];
    403 			default_state = i;
    404 		}
    405 	}
    406 
    407 	return (default_state);
    408 }
    409 
    410 
    411 
    412 void
    413 save_column(int symbol, int default_state)
    414 {
    415 	int i;
    416 	int m;
    417 	int n;
    418 	short *sp;
    419 	short *sp1;
    420 	short *sp2;
    421 	int count;
    422 	int symno;
    423 
    424 	m = goto_map[symbol];
    425 	n = goto_map[symbol + 1];
    426 
    427 	count = 0;
    428 	for (i = m; i < n; i++) {
    429 		if (to_state[i] != default_state)
    430 			++count;
    431 	}
    432 	if (count == 0)
    433 		return;
    434 
    435 	symno = symbol_value[symbol] + 2*nstates;
    436 
    437 	froms[symno] = sp1 = sp = NEW2(count, short);
    438 	tos[symno] = sp2 = NEW2(count, short);
    439 
    440 	for (i = m; i < n; i++) {
    441 		if (to_state[i] != default_state) {
    442 			*sp1++ = from_state[i];
    443 			*sp2++ = to_state[i];
    444 		}
    445 	}
    446 
    447 	tally[symno] = count;
    448 	width[symno] = sp1[-1] - sp[0] + 1;
    449 }
    450 
    451 void
    452 sort_actions(void)
    453 {
    454 	int i;
    455 	int j;
    456 	int k;
    457 	int t;
    458 	int w;
    459 
    460 	order = NEW2(nvectors, short);
    461 	nentries = 0;
    462 
    463 	for (i = 0; i < nvectors; i++) {
    464 		if (tally[i] > 0) {
    465 			t = tally[i];
    466 			w = width[i];
    467 			j = nentries - 1;
    468 
    469 			while (j >= 0 && (width[order[j]] < w))
    470 				j--;
    471 
    472 			while (j >= 0 && (width[order[j]] == w) &&
    473 			    (tally[order[j]] < t))
    474 				j--;
    475 
    476 			for (k = nentries - 1; k > j; k--)
    477 				order[k + 1] = order[k];
    478 
    479 			order[j + 1] = i;
    480 			nentries++;
    481 		}
    482 	}
    483 }
    484 
    485 
    486 void
    487 pack_table(void)
    488 {
    489 	int i;
    490 	int place;
    491 	int state;
    492 
    493 	base = NEW2(nvectors, short);
    494 	pos = NEW2(nentries, short);
    495 
    496 	maxtable = 1000;
    497 	table = NEW2(maxtable, short);
    498 	check = NEW2(maxtable, short);
    499 
    500 	lowzero = 0;
    501 	high = 0;
    502 
    503 	for (i = 0; i < maxtable; i++)
    504 		check[i] = -1;
    505 
    506 	for (i = 0; i < nentries; i++) {
    507 		state = matching_vector(i);
    508 
    509 		if (state < 0)
    510 			place = pack_vector(i);
    511 		else
    512 			place = base[state];
    513 
    514 		pos[i] = place;
    515 		base[order[i]] = place;
    516 	}
    517 
    518 	for (i = 0; i < nvectors; i++) {
    519 		if (froms[i])
    520 			free(froms[i]);
    521 		if (tos[i])
    522 			free(tos[i]);
    523 	}
    524 
    525 	free(froms);
    526 	free(tos);
    527 	free(pos);
    528 }
    529 
    530 
    531 /*  The function matching_vector determines if the vector specified by	*/
    532 /*  the input parameter matches a previously considered	vector.  The	*/
    533 /*  test at the start of the function checks if the vector represents	*/
    534 /*  a row of shifts over terminal symbols or a row of reductions, or a	*/
    535 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
    536 /*  check if a column of shifts over a nonterminal symbols matches a	*/
    537 /*  previously considered vector.  Because of the nature of LR parsing	*/
    538 /*  tables, no two columns can match.  Therefore, the only possible	*/
    539 /*  match would be between a row and a column.  Such matches are	*/
    540 /*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
    541 /*  column matches a previously considered vector.			*/
    542 /*									*/
    543 /*  Matching_vector is poorly designed.  The test could easily be made	*/
    544 /*  faster.  Also, it depends on the vectors being in a specific	*/
    545 /*  order.								*/
    546 
    547 int
    548 matching_vector(int vector)
    549 {
    550 	int i, j, k, t, w, match, prev;
    551 
    552 	i = order[vector];
    553 	if (i >= 2*nstates)
    554 		return (-1);
    555 
    556 	t = tally[i];
    557 	w = width[i];
    558 
    559 	for (prev = vector - 1; prev >= 0; prev--) {
    560 		j = order[prev];
    561 		if (width[j] != w || tally[j] != t)
    562 			return (-1);
    563 
    564 		match = 1;
    565 		for (k = 0; match && k < t; k++) {
    566 			if (tos[j][k] != tos[i][k] ||
    567 			    froms[j][k] != froms[i][k])
    568 				match = 0;
    569 		}
    570 
    571 		if (match)
    572 			return (j);
    573 	}
    574 
    575 	return (-1);
    576 }
    577 
    578 
    579 
    580 int
    581 pack_vector(int vector)
    582 {
    583 	int i, j, k, l;
    584 	int t, loc, ok;
    585 	short *from, *to;
    586 	int newmax;
    587 
    588 	i = order[vector];
    589 	t = tally[i];
    590 	assert(t);
    591 
    592 	from = froms[i];
    593 	to = tos[i];
    594 
    595 	j = lowzero - from[0];
    596 	for (k = 1; k < t; ++k)
    597 		if (lowzero - from[k] > j)
    598 			j = lowzero - from[k];
    599 	for (;; ++j) {
    600 		if (j == 0)
    601 			continue;
    602 		ok = 1;
    603 		for (k = 0; ok && k < t; k++) {
    604 			loc = j + from[k];
    605 			if (loc >= maxtable) {
    606 				if (loc >= MAXTABLE)
    607 					fatal("maximum table size exceeded");
    608 
    609 				newmax = maxtable;
    610 				do {
    611 					newmax += 200;
    612 				} while (newmax <= loc);
    613 				table = realloc(table, newmax * sizeof(short));
    614 				if (table == NULL)
    615 					no_space();
    616 				check = realloc(check, newmax * sizeof(short));
    617 				if (check == NULL)
    618 					no_space();
    619 				for (l  = maxtable; l < newmax; ++l) {
    620 					table[l] = 0;
    621 					check[l] = -1;
    622 				}
    623 				maxtable = newmax;
    624 			}
    625 
    626 			if (check[loc] != -1)
    627 				ok = 0;
    628 		}
    629 		for (k = 0; ok && k < vector; k++) {
    630 			if (pos[k] == j)
    631 				ok = 0;
    632 		}
    633 		if (ok) {
    634 			for (k = 0; k < t; k++) {
    635 				loc = j + from[k];
    636 				table[loc] = to[k];
    637 				check[loc] = from[k];
    638 				if (loc > high)
    639 					high = loc;
    640 			}
    641 
    642 			while (check[lowzero] != -1)
    643 				++lowzero;
    644 
    645 			return (j);
    646 		}
    647 	}
    648 }
    649 
    650 
    651 
    652 void
    653 output_base(void)
    654 {
    655 	int i, j;
    656 
    657 	fprintf(output_file, "const short %ssindex[] =\n"
    658 	    "\t{%39d,", symbol_prefix, base[0]);
    659 
    660 	j = 10;
    661 	for (i = 1; i < nstates; i++) {
    662 		if (j >= 10) {
    663 			if (!rflag)
    664 				++outline;
    665 			putc('\n', output_file);
    666 			j = 1;
    667 		} else
    668 			++j;
    669 		fprintf(output_file, "%5d,", base[i]);
    670 	}
    671 
    672 	if (!rflag)
    673 		outline += 2;
    674 	fprintf(output_file, "};\n"
    675 	    "const short %srindex[] =\n"
    676 	    "\t{%39d,", symbol_prefix, base[nstates]);
    677 
    678 	j = 10;
    679 	for (i = nstates + 1; i < 2*nstates; i++) {
    680 		if (j >= 10) {
    681 			if (!rflag)
    682 				++outline;
    683 			putc('\n', output_file);
    684 			j = 1;
    685 		} else
    686 			++j;
    687 		fprintf(output_file, "%5d,", base[i]);
    688 	}
    689 
    690 	if (!rflag)
    691 		outline += 2;
    692 	fprintf(output_file, "};\n"
    693 	    "const short %sgindex[] =\n"
    694 	    "\t{%39d,", symbol_prefix, base[2*nstates]);
    695 
    696 	j = 10;
    697 	for (i = 2*nstates + 1; i < nvectors - 1; i++) {
    698 		if (j >= 10) {
    699 			if (!rflag)
    700 				++outline;
    701 			putc('\n', output_file);
    702 			j = 1;
    703 		} else
    704 			++j;
    705 		fprintf(output_file, "%5d,", base[i]);
    706 	}
    707 
    708 	if (!rflag)
    709 		outline += 2;
    710 	fprintf(output_file, "\n};\n");
    711 	free(base);
    712 }
    713 
    714 
    715 void
    716 output_table(void)
    717 {
    718 	int i, j;
    719 
    720 	++outline;
    721 	fprintf(code_file, "#define YYTABLESIZE %d\n", high);
    722 	fprintf(output_file, "const short %stable[] =\n"
    723 	    "\t{%40d,", symbol_prefix, table[0]);
    724 
    725 	j = 10;
    726 	for (i = 1; i <= high; i++) {
    727 		if (j >= 10) {
    728 			if (!rflag)
    729 				++outline;
    730 			putc('\n', output_file);
    731 			j = 1;
    732 		} else
    733 			++j;
    734 		fprintf(output_file, "%5d,", table[i]);
    735 	}
    736 
    737 	if (!rflag)
    738 		outline += 2;
    739 	fprintf(output_file, "\n};\n");
    740 	free(table);
    741 }
    742 
    743 
    744 void
    745 output_check(void)
    746 {
    747 	int i, j;
    748 
    749 	fprintf(output_file, "const short %scheck[] =\n"
    750 	    "\t{%40d,", symbol_prefix, check[0]);
    751 
    752 	j = 10;
    753 	for (i = 1; i <= high; i++) {
    754 		if (j >= 10) {
    755 			if (!rflag)
    756 				++outline;
    757 			putc('\n', output_file);
    758 			j = 1;
    759 		} else
    760 			++j;
    761 		fprintf(output_file, "%5d,", check[i]);
    762 	}
    763 
    764 	if (!rflag)
    765 		outline += 2;
    766 	fprintf(output_file, "\n};\n");
    767 	free(check);
    768 }
    769 
    770 
    771 int
    772 is_C_identifier(char *name)
    773 {
    774 	char *s;
    775 	int c;
    776 
    777 	s = name;
    778 	c = (unsigned char)*s;
    779 	if (c == '"') {
    780 		c = (unsigned char)*++s;
    781 		if (!isalpha(c) && c != '_' && c != '$')
    782 			return (0);
    783 		while ((c = (unsigned char)*++s) != '"') {
    784 			if (!isalnum(c) && c != '_' && c != '$')
    785 				return (0);
    786 		}
    787 		return (1);
    788 	}
    789 
    790 	if (!isalpha(c) && c != '_' && c != '$')
    791 		return (0);
    792 	while ((c = (unsigned char)*++s)) {
    793 		if (!isalnum(c) && c != '_' && c != '$')
    794 			return (0);
    795 	}
    796 	return (1);
    797 }
    798 
    799 
    800 void
    801 output_defines(void)
    802 {
    803 	int c, i;
    804 	char *s;
    805 
    806 	for (i = 2; i < ntokens; ++i) {
    807 		s = symbol_name[i];
    808 		if (is_C_identifier(s)) {
    809 			fprintf(code_file, "#define ");
    810 			if (dflag)
    811 				fprintf(defines_file, "#define ");
    812 			c = (unsigned char)*s;
    813 			if (c == '"') {
    814 				while ((c = (unsigned char)*++s) != '"') {
    815 					putc(c, code_file);
    816 					if (dflag)
    817 						putc(c, defines_file);
    818 				}
    819 			} else {
    820 				do {
    821 					putc(c, code_file);
    822 					if (dflag)
    823 						putc(c, defines_file);
    824 				} while ((c = (unsigned char)*++s));
    825 			}
    826 			++outline;
    827 			fprintf(code_file, " %d\n", symbol_value[i]);
    828 			if (dflag)
    829 				fprintf(defines_file, " %d\n", symbol_value[i]);
    830 		}
    831 	}
    832 
    833 	++outline;
    834 	fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
    835 
    836 	if (dflag && unionized) {
    837 		fclose(union_file);
    838 		union_file = fopen(union_file_name, "r");
    839 		if (union_file == NULL)
    840 			open_error(union_file_name);
    841 		while ((c = getc(union_file)) != EOF)
    842 			putc(c, defines_file);
    843 		fprintf(defines_file, " YYSTYPE;\n");
    844 		fprintf(defines_file, "#endif /* YYSTYPE_DEFINED */\n");
    845 		fprintf(defines_file, "extern YYSTYPE %slval;\n",
    846 		    symbol_prefix);
    847 	}
    848 }
    849 
    850 
    851 void
    852 output_stored_text(void)
    853 {
    854 	int c;
    855 	FILE *in, *out;
    856 
    857 	fclose(text_file);
    858 	text_file = fopen(text_file_name, "r");
    859 	if (text_file == NULL)
    860 		open_error(text_file_name);
    861 	in = text_file;
    862 	if ((c = getc(in)) == EOF)
    863 		return;
    864 	out = code_file;
    865 	if (c ==  '\n')
    866 		++outline;
    867 	putc(c, out);
    868 	while ((c = getc(in)) != EOF) {
    869 		if (c == '\n')
    870 			++outline;
    871 		putc(c, out);
    872 	}
    873 	if (!lflag)
    874 		fprintf(out, line_format, ++outline + 1, code_file_name);
    875 }
    876 
    877 
    878 void
    879 output_debug(void)
    880 {
    881 	int i, j, k, max;
    882 	char **symnam, *s;
    883 
    884 	++outline;
    885 	fprintf(code_file, "#define YYFINAL %d\n", final_state);
    886 	outline += 3;
    887 	fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
    888 		tflag);
    889 	if (rflag)
    890 		fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
    891 		    tflag);
    892 
    893 	max = 0;
    894 	for (i = 2; i < ntokens; ++i)
    895 		if (symbol_value[i] > max)
    896 			max = symbol_value[i];
    897 	++outline;
    898 	fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
    899 
    900 	symnam = calloc(max+1, sizeof(char *));
    901 	if (symnam == NULL)
    902 		no_space();
    903 
    904 	for (i = ntokens - 1; i >= 2; --i)
    905 		symnam[symbol_value[i]] = symbol_name[i];
    906 	symnam[0] = "end-of-file";
    907 
    908 	if (!rflag)
    909 		++outline;
    910 	fprintf(output_file,
    911 	    "#if YYDEBUG\n"
    912 	    "const char * const %sname[] =\n"
    913 	    "\t{", symbol_prefix);
    914 	j = 80;
    915 	for (i = 0; i <= max; ++i) {
    916 		if ((s = symnam[i]) != '\0') {
    917 			if (s[0] == '"') {
    918 				k = 7;
    919 				while (*++s != '"') {
    920 					++k;
    921 					if (*s == '\\') {
    922 						k += 2;
    923 						if (*++s == '\\')
    924 							++k;
    925 					}
    926 				}
    927 				j += k;
    928 				if (j > 80) {
    929 					if (!rflag)
    930 						++outline;
    931 					putc('\n', output_file);
    932 					j = k;
    933 				}
    934 				fprintf(output_file, "\"\\\"");
    935 				s = symnam[i];
    936 				while (*++s != '"') {
    937 					if (*s == '\\') {
    938 						fprintf(output_file, "\\\\");
    939 						if (*++s == '\\')
    940 							fprintf(output_file, "\\\\");
    941 						else
    942 							putc(*s, output_file);
    943 					} else
    944 						putc(*s, output_file);
    945 				}
    946 				fprintf(output_file, "\\\"\",");
    947 			} else if (s[0] == '\'') {
    948 				if (s[1] == '"') {
    949 					j += 7;
    950 					if (j > 80) {
    951 						if (!rflag)
    952 							++outline;
    953 						putc('\n', output_file);
    954 						j = 7;
    955 					}
    956 					fprintf(output_file, "\"'\\\"'\",");
    957 				} else {
    958 					k = 5;
    959 					while (*++s != '\'') {
    960 						++k;
    961 						if (*s == '\\') {
    962 							k += 2;
    963 							if (*++s == '\\')
    964 								++k;
    965 						}
    966 					}
    967 					j += k;
    968 					if (j > 80) {
    969 						if (!rflag)
    970 							++outline;
    971 						putc('\n', output_file);
    972 						j = k;
    973 					}
    974 					fprintf(output_file, "\"'");
    975 					s = symnam[i];
    976 					while (*++s != '\'') {
    977 						if (*s == '\\') {
    978 							fprintf(output_file, "\\\\");
    979 							if (*++s == '\\')
    980 								fprintf(output_file, "\\\\");
    981 							else
    982 								putc(*s, output_file);
    983 						} else
    984 							putc(*s, output_file);
    985 					}
    986 					fprintf(output_file, "'\",");
    987 				}
    988 			} else {
    989 				k = strlen(s) + 3;
    990 				j += k;
    991 				if (j > 80) {
    992 					if (!rflag)
    993 						++outline;
    994 					putc('\n', output_file);
    995 					j = k;
    996 				}
    997 				putc('"', output_file);
    998 				do {
    999 					putc(*s, output_file);
   1000 				} while (*++s);
   1001 				fprintf(output_file, "\",");
   1002 			}
   1003 		} else {
   1004 			j += 2;
   1005 			if (j > 80) {
   1006 				if (!rflag)
   1007 					++outline;
   1008 				putc('\n', output_file);
   1009 				j = 2;
   1010 			}
   1011 			fprintf(output_file, "0,");
   1012 		}
   1013 	}
   1014 	if (!rflag)
   1015 		outline += 2;
   1016 	fprintf(output_file, "\n};\n");
   1017 	free(symnam);
   1018 
   1019 	if (!rflag)
   1020 		++outline;
   1021 	fprintf(output_file,
   1022 	    "const char * const %srule[] =\n"
   1023 	    "\t{", symbol_prefix);
   1024 	for (i = 2; i < nrules; ++i) {
   1025 		fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
   1026 		for (j = rrhs[i]; ritem[j] > 0; ++j) {
   1027 			s = symbol_name[ritem[j]];
   1028 			if (s[0] == '"') {
   1029 				fprintf(output_file, " \\\"");
   1030 				while (*++s != '"') {
   1031 					if (*s == '\\') {
   1032 						if (s[1] == '\\')
   1033 							fprintf(output_file, "\\\\\\\\");
   1034 						else
   1035 							fprintf(output_file, "\\\\%c", s[1]);
   1036 						++s;
   1037 					} else
   1038 						putc(*s, output_file);
   1039 				}
   1040 				fprintf(output_file, "\\\"");
   1041 			} else if (s[0] == '\'') {
   1042 				if (s[1] == '"')
   1043 					fprintf(output_file, " '\\\"'");
   1044 				else if (s[1] == '\\') {
   1045 					if (s[2] == '\\')
   1046 						fprintf(output_file, " '\\\\\\\\");
   1047 					else
   1048 						fprintf(output_file, " '\\\\%c", s[2]);
   1049 					s += 2;
   1050 					while (*++s != '\'')
   1051 						putc(*s, output_file);
   1052 					putc('\'', output_file);
   1053 				} else
   1054 					fprintf(output_file, " '%c'", s[1]);
   1055 			} else
   1056 				fprintf(output_file, " %s", s);
   1057 		}
   1058 		if (!rflag)
   1059 			++outline;
   1060 		fprintf(output_file, "\",\n");
   1061 	}
   1062 
   1063 	if (!rflag)
   1064 		outline += 2;
   1065 	fprintf(output_file, "};\n#endif\n");
   1066 }
   1067 
   1068 
   1069 void
   1070 output_stype(void)
   1071 {
   1072 	if (!unionized && ntags == 0) {
   1073 		outline += 3;
   1074 		fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
   1075 	}
   1076 }
   1077 
   1078 
   1079 void
   1080 output_trailing_text(void)
   1081 {
   1082 	int c, last;
   1083 	FILE *in, *out;
   1084 
   1085 	if (line == 0)
   1086 		return;
   1087 
   1088 	in = input_file;
   1089 	out = code_file;
   1090 	c = (unsigned char)*cptr;
   1091 	if (c == '\n') {
   1092 		++lineno;
   1093 		if ((c = getc(in)) == EOF)
   1094 			return;
   1095 		if (!lflag) {
   1096 			++outline;
   1097 			fprintf(out, line_format, lineno, input_file_name);
   1098 		}
   1099 		if (c == '\n')
   1100 			++outline;
   1101 		putc(c, out);
   1102 		last = c;
   1103 	} else {
   1104 		if (!lflag) {
   1105 			++outline;
   1106 			fprintf(out, line_format, lineno, input_file_name);
   1107 		}
   1108 		do {
   1109 			putc(c, out);
   1110 		} while ((c = (unsigned char)*++cptr) != '\n');
   1111 		++outline;
   1112 		putc('\n', out);
   1113 		last = '\n';
   1114 	}
   1115 
   1116 	while ((c = getc(in)) != EOF) {
   1117 		if (c == '\n')
   1118 			++outline;
   1119 		putc(c, out);
   1120 		last = c;
   1121 	}
   1122 
   1123 	if (last != '\n') {
   1124 		++outline;
   1125 		putc('\n', out);
   1126 	}
   1127 	if (!lflag)
   1128 		fprintf(out, line_format, ++outline + 1, code_file_name);
   1129 }
   1130 
   1131 
   1132 void
   1133 output_semantic_actions(void)
   1134 {
   1135 	int c, last;
   1136 	FILE *out;
   1137 
   1138 	fclose(action_file);
   1139 	action_file = fopen(action_file_name, "r");
   1140 	if (action_file == NULL)
   1141 		open_error(action_file_name);
   1142 
   1143 	if ((c = getc(action_file)) == EOF)
   1144 		return;
   1145 
   1146 	out = code_file;
   1147 	last = c;
   1148 	if (c == '\n')
   1149 		++outline;
   1150 	putc(c, out);
   1151 	while ((c = getc(action_file)) != EOF) {
   1152 		if (c == '\n')
   1153 			++outline;
   1154 		putc(c, out);
   1155 		last = c;
   1156 	}
   1157 
   1158 	if (last != '\n') {
   1159 		++outline;
   1160 		putc('\n', out);
   1161 	}
   1162 
   1163 	if (!lflag)
   1164 		fprintf(out, line_format, ++outline + 1, code_file_name);
   1165 }
   1166 
   1167 
   1168 void
   1169 free_itemsets(void)
   1170 {
   1171 	core *cp, *next;
   1172 
   1173 	free(state_table);
   1174 	for (cp = first_state; cp; cp = next) {
   1175 		next = cp->next;
   1176 		free(cp);
   1177 	}
   1178 }
   1179 
   1180 
   1181 void
   1182 free_shifts(void)
   1183 {
   1184 	shifts *sp, *next;
   1185 
   1186 	free(shift_table);
   1187 	for (sp = first_shift; sp; sp = next) {
   1188 		next = sp->next;
   1189 		free(sp);
   1190 	}
   1191 }
   1192 
   1193 
   1194 
   1195 void
   1196 free_reductions(void)
   1197 {
   1198 	reductions *rp, *next;
   1199 
   1200 	free(reduction_table);
   1201 	for (rp = first_reduction; rp; rp = next) {
   1202 		next = rp->next;
   1203 		free(rp);
   1204 	}
   1205 }