hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

sub2.c (24913B)


      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.
     24  * All rights reserved.
     25  * Use is subject to license terms.
     26  */
     27 
     28 /*	Copyright (c) 1988 AT&T	*/
     29 /*	All Rights Reserved	*/
     30 
     31 /*	from OpenSolaris "sub2.c	6.15	05/06/08 SMI"	*/
     32 
     33 /*
     34  * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
     35  *
     36  * Sccsid @(#)sub2.c	1.7 (gritter) 01/12/07
     37  */
     38 
     39 #include "ldefs.c"
     40 
     41 static void add(int **array, int n);
     42 static void follow(int v);
     43 static void first(int v);
     44 static void nextstate(int s, int c);
     45 static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit);
     46 static void acompute(int s);
     47 static void rprint(int *a, char *s, int n);
     48 static void shiftr(int *a, int n);
     49 static void upone(int *a, int n);
     50 static void bprint(char *a, char *s, int n);
     51 static int notin(int n);
     52 static int member(int d, CHR *t);
     53 
     54 #ifdef PP
     55 static void padd(int **array, int n);
     56 #endif
     57 
     58 void
     59 cfoll(int v)
     60 {
     61 	int i, j, k;
     62 	CHR *p;
     63 	i = name[v];
     64 	if (!ISOPERATOR(i))
     65 		i = 1;
     66 	switch (i) {
     67 		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
     68 			for (j = 0; j < tptr; j++)
     69 				tmpstat[j] = FALSE;
     70 			count = 0;
     71 			follow(v);
     72 #ifdef PP
     73 			padd(foll, v); /* packing version */
     74 #else
     75 			add(foll, v); /* no packing version */
     76 #endif
     77 			if (i == RSTR)
     78 				cfoll(left[v]);
     79 			else if (i == RCCL || i == RNCCL) {
     80 				for (j = 1; j < ncg; j++)
     81 					symbol[j] = (i == RNCCL);
     82 				p = (CHR *) left[v];
     83 				while (*p)
     84 					symbol[*p++] = (i == RCCL);
     85 				p = pcptr;
     86 				for (j = 1; j < ncg; j++)
     87 					if (symbol[j]) {
     88 						for (k = 0; p + k < pcptr; k++)
     89 						    if (cindex[j] == *(p + k))
     90 							break;
     91 						if (p + k >= pcptr)
     92 							*pcptr++ = cindex[j];
     93 					}
     94 				*pcptr++ = 0;
     95 				if (pcptr > pchar + pchlen)
     96 					error(
     97 					"Too many packed character classes");
     98 				left[v] = (intptr_t)p;
     99 				name[v] = RCCL;	/* RNCCL eliminated */
    100 #ifdef DEBUG
    101 				if (debug && *p) {
    102 					printf("ccl %d: %d", v, *p++);
    103 					while (*p)
    104 						printf(", %d", *p++);
    105 					putchar('\n');
    106 				}
    107 #endif
    108 			}
    109 			break;
    110 		case CARAT:
    111 			cfoll(left[v]);
    112 			break;
    113 
    114 		/* XCU4: add RXSCON */
    115 		case RXSCON:
    116 
    117 		case STAR: case PLUS: case QUEST: case RSCON:
    118 			cfoll(left[v]);
    119 			break;
    120 		case BAR: case RCAT: case DIV: case RNEWE:
    121 			cfoll(left[v]);
    122 			cfoll(right[v]);
    123 			break;
    124 #ifdef DEBUG
    125 		case FINAL:
    126 		case S1FINAL:
    127 		case S2FINAL:
    128 			break;
    129 		default:
    130 			warning("bad switch cfoll %d", v);
    131 #endif
    132 	}
    133 }
    134 
    135 #ifdef DEBUG
    136 void
    137 pfoll(void)
    138 {
    139 	int i, k, *p;
    140 	int j;
    141 	/* print sets of chars which may follow positions */
    142 	printf("pos\tchars\n");
    143 	for (i = 0; i < tptr; i++)
    144 		if (p = foll[i]) {
    145 			j = *p++;
    146 			if (j >= 1) {
    147 				printf("%d:\t%d", i, *p++);
    148 				for (k = 2; k <= j; k++)
    149 					printf(", %d", *p++);
    150 				putchar('\n');
    151 			}
    152 		}
    153 }
    154 #endif
    155 
    156 static void
    157 add(int **array, int n)
    158 {
    159 	int i, *temp;
    160 	CHR *ctemp;
    161 	temp = nxtpos;
    162 	ctemp = tmpstat;
    163 	array[n] = nxtpos;	/* note no packing is done in positions */
    164 	*temp++ = count;
    165 	for (i = 0; i < tptr; i++)
    166 		if (ctemp[i] == TRUE)
    167 			*temp++ = i;
    168 	nxtpos = temp;
    169 	if (nxtpos >= positions+maxpos)
    170 		error(
    171 		"Too many positions %s",
    172 		(maxpos == MAXPOS ? "\nTry using %p num" : ""));
    173 }
    174 
    175 static void
    176 follow(int v)
    177 {
    178 	int p;
    179 	if (v >= tptr-1)
    180 		return;
    181 	p = parent[v];
    182 	if (p == 0)
    183 		return;
    184 	switch (name[p]) {
    185 	/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
    186 	case RSTR:
    187 		if (tmpstat[p] == FALSE) {
    188 			count++;
    189 			tmpstat[p] = TRUE;
    190 		}
    191 		break;
    192 	case STAR: case PLUS:
    193 		first(v);
    194 		follow(p);
    195 		break;
    196 	case BAR: case QUEST: case RNEWE:
    197 		follow(p);
    198 		break;
    199 	case RCAT: case DIV:
    200 		if (v == left[p]) {
    201 			if (nullstr[right[p]])
    202 				follow(p);
    203 			first(right[p]);
    204 		}
    205 		else
    206 			follow(p);
    207 		break;
    208 	/* XCU4: add RXSCON */
    209 	case RXSCON:
    210 	case RSCON: case CARAT:
    211 		follow(p);
    212 		break;
    213 #ifdef DEBUG
    214 	default:
    215 		warning("bad switch follow %d", p);
    216 #endif
    217 	}
    218 }
    219 
    220 /*
    221  * Check if I have a RXSCON in my upper node
    222  */
    223 static int
    224 check_me(int v)
    225 {
    226 	int tmp = parent[v];
    227 
    228 	while (name[tmp] != RNEWE) {
    229 		if (name[tmp] == RXSCON)
    230 			return (1);
    231 		tmp = parent[tmp];
    232 	}
    233 	return (0);
    234 }
    235 
    236 /* calculate set of positions with v as root which can be active initially */
    237 static void
    238 first(int v)
    239 {
    240 	int i;
    241 	CHR *p;
    242 	i = name[v];
    243 	if (!ISOPERATOR(i))
    244 		i = 1;
    245 	switch (i) {
    246 	case 1: case RCCL: case RNCCL:
    247 	case RNULLS: case FINAL:
    248 	case S1FINAL: case S2FINAL:
    249 	/*
    250 	 * XCU4: if we are working on an exclusive start state and
    251 	 * the parent of this position is not RXSCON or RSTR this
    252 	 * is not an active position.
    253 	 *
    254 	 * (There is a possibility that RSXCON appreas as the
    255 	 *  (parent)* node. Check it by check_me().)
    256 	 */
    257 		if ((exclusive[stnum/2]) &&
    258 		    ISOPERATOR(name[parent[v]]) &&
    259 		    (name[parent[v]] != RXSCON) &&
    260 		    (name[parent[v]] != RSTR) &&
    261 		    (check_me(v) == 0)) {
    262 				break;
    263 		}
    264 		if (tmpstat[v] == FALSE) {
    265 			count++;
    266 			tmpstat[v] = TRUE;
    267 		}
    268 		break;
    269 	case BAR: case RNEWE:
    270 		first(left[v]);
    271 		first(right[v]);
    272 		break;
    273 	case CARAT:
    274 		if (stnum % 2 == 1)
    275 			first(left[v]);
    276 		break;
    277 	/* XCU4: add RXSCON */
    278 	case RXSCON:
    279 	case RSCON:
    280 		i = stnum/2 +1;
    281 		p = (CHR *) right[v];
    282 		while (*p)
    283 			if (*p++ == i) {
    284 				first(left[v]);
    285 				break;
    286 			}
    287 		break;
    288 	case STAR: case QUEST:
    289 	case PLUS:  case RSTR:
    290 	/*
    291 	 * XCU4: if we are working on an exclusive start state and
    292 	 * the parent of this position is not RXSCON or RSTR this
    293 	 * is not an active position.
    294 	 *
    295 	 * (There is a possibility that RSXCON appreas as the
    296 	 *  (parent)* node. Check it by check_me().)
    297 	 */
    298 		if ((exclusive[stnum/2]) &&
    299 		    ISOPERATOR(name[parent[v]]) &&
    300 		    (name[parent[v]] != RXSCON) &&
    301 		    (name[parent[v]] != RSTR) &&
    302 		    (check_me(v) == 0)) {
    303 				break;
    304 		}
    305 		first(left[v]);
    306 		break;
    307 	case RCAT: case DIV:
    308 		first(left[v]);
    309 		if (nullstr[left[v]])
    310 			first(right[v]);
    311 		break;
    312 #ifdef DEBUG
    313 	default:
    314 		warning("bad switch first %d", v);
    315 #endif
    316 	}
    317 }
    318 
    319 void
    320 cgoto(void)
    321 {
    322 	int i, j;
    323 	static int s;
    324 	int npos, curpos, n;
    325 	int tryit;
    326 	CHR tch[MAXNCG];
    327 	int tst[MAXNCG];
    328 	CHR *q;
    329 	/* generate initial state, for each start condition */
    330 	if (ratfor) {
    331 		fprintf(fout, "blockdata\n");
    332 		fprintf(fout, "common /Lvstop/ vstop\n");
    333 		fprintf(fout, "define Svstop %d\n", nstates+1);
    334 		fprintf(fout, "integer vstop(Svstop)\n");
    335 	} else
    336 		fprintf(fout, "int yyvstop[] = {\n0,\n");
    337 	while (stnum < 2 || stnum/2 < sptr) {
    338 		for (i = 0; i < tptr; i++)
    339 			tmpstat[i] = 0;
    340 		count = 0;
    341 		if (tptr > 0)
    342 			first(tptr-1);
    343 		add(state, stnum);
    344 #ifdef DEBUG
    345 		if (debug) {
    346 			if (stnum > 1)
    347 				printf("%ls:\n", sname[stnum/2]);
    348 			pstate(stnum);
    349 		}
    350 #endif
    351 		stnum++;
    352 	}
    353 	stnum--;
    354 	/* even stnum = might not be at line begin */
    355 	/* odd stnum  = must be at line begin */
    356 	/* even states can occur anywhere, odd states only at line begin */
    357 	for (s = 0; s <= stnum; s++) {
    358 		tryit = FALSE;
    359 		cpackflg[s] = FALSE;
    360 		sfall[s] = -1;
    361 		acompute(s);
    362 		for (i = 0; i < ncg; i++)
    363 			symbol[i] = 0;
    364 		npos = *state[s];
    365 		for (i = 1; i <= npos; i++) {
    366 			curpos = *(state[s]+i);
    367 			if (!ISOPERATOR(name[curpos]))
    368 				symbol[name[curpos]] = TRUE;
    369 			else {
    370 				switch (name[curpos]) {
    371 				case RCCL:
    372 					tryit = TRUE;
    373 					q = (CHR *)left[curpos];
    374 					while (*q) {
    375 						for (j = 1; j < ncg; j++)
    376 						    if (cindex[j] == *q)
    377 							symbol[j] = TRUE;
    378 						q++;
    379 					}
    380 					break;
    381 				case RSTR:
    382 					symbol[right[curpos]] = TRUE;
    383 					break;
    384 #ifdef DEBUG
    385 				case RNULLS:
    386 				case FINAL:
    387 				case S1FINAL:
    388 				case S2FINAL:
    389 					break;
    390 				default:
    391 					warning(
    392 					"bad switch cgoto %d state %d",
    393 					curpos, s);
    394 					break;
    395 #endif
    396 				}
    397 			}
    398 		}
    399 #ifdef DEBUG
    400 		if (debug) {
    401 			printf("State %d transitions on char-group {", s);
    402 			charc = 0;
    403 			for (i = 1; i < ncg; i++) {
    404 				if (symbol[i]) {
    405 					printf("%d,", i);
    406 				}
    407 				if (i == ncg-1)
    408 					printf("}\n");
    409 				if (charc > LINESIZE/4) {
    410 					charc = 0;
    411 					printf("\n\t");
    412 				}
    413 			}
    414 		}
    415 #endif
    416 		/* for each char, calculate next state */
    417 		n = 0;
    418 		for (i = 1; i < ncg; i++) {
    419 			if (symbol[i]) {
    420 				/* executed for each state, transition pair */
    421 				nextstate(s, i);
    422 				xstate = notin(stnum);
    423 				if (xstate == -2)
    424 					warning("bad state  %d %o", s, i);
    425 				else if (xstate == -1) {
    426 					if (stnum+1 >= nstates) {
    427 						stnum++;
    428 						error("Too many states %s",
    429 						(nstates == NSTATES ?
    430 						"\nTry using %n num":""));
    431 					}
    432 					add(state, ++stnum);
    433 #ifdef DEBUG
    434 					if (debug)
    435 						pstate(stnum);
    436 #endif
    437 					tch[n] = i;
    438 					tst[n++] = stnum;
    439 				} else { /* xstate >= 0 ==> state exists */
    440 					tch[n] = i;
    441 					tst[n++] = xstate;
    442 				}
    443 			}
    444 		}
    445 		tch[n] = 0;
    446 		tst[n] = -1;
    447 		/* pack transitions into permanent array */
    448 		if (n > 0)
    449 			packtrans(s, tch, tst, n, tryit);
    450 		else
    451 			gotof[s] = -1;
    452 	}
    453 	ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n");
    454 }
    455 
    456 /*
    457  * Beware -- 70% of total CPU time is spent in this subroutine -
    458  * if you don't believe me - try it yourself !
    459  */
    460 static void
    461 nextstate(int s, int c)
    462 {
    463 	int j, *newpos;
    464 	CHR *temp, *tz;
    465 	int *pos, i, *f, num, curpos, number;
    466 	/* state to goto from state s on char c */
    467 	num = *state[s];
    468 	temp = tmpstat;
    469 	pos = state[s] + 1;
    470 	for (i = 0; i < num; i++) {
    471 		curpos = *pos++;
    472 		j = name[curpos];
    473 		if ((!ISOPERATOR(j)) && j == c ||
    474 			j == RSTR && c == right[curpos] ||
    475 			j == RCCL && member(c, (CHR *) left[curpos])) {
    476 			f = foll[curpos];
    477 			number = *f;
    478 			newpos = f+1;
    479 			for (j = 0; j < number; j++)
    480 				temp[*newpos++] = 2;
    481 		}
    482 	}
    483 	j = 0;
    484 	tz = temp + tptr;
    485 	while (temp < tz) {
    486 		if (*temp == 2) {
    487 			j++;
    488 			*temp++ = 1;
    489 		}
    490 		else
    491 			*temp++ = 0;
    492 	}
    493 	count = j;
    494 }
    495 
    496 static int
    497 notin(int n)
    498 {	/* see if tmpstat occurs previously */
    499 	int *j, k;
    500 	CHR *temp;
    501 	int i;
    502 	if (count == 0)
    503 		return (-2);
    504 	temp = tmpstat;
    505 	for (i = n; i >= 0; i--) { /* for each state */
    506 		j = state[i];
    507 		if (count == *j++) {
    508 			for (k = 0; k < count; k++)
    509 				if (!temp[*j++])
    510 					break;
    511 			if (k >= count)
    512 				return (i);
    513 		}
    514 	}
    515 	return (-1);
    516 }
    517 
    518 static void
    519 packtrans(int st, CHR *tch, int *tst, int cnt, int tryit)
    520 {
    521 	/*
    522 	 * pack transitions into nchar, nexts
    523 	 * nchar is terminated by '\0', nexts uses cnt, followed by elements
    524 	 * gotof[st] = index into nchr, nexts for state st
    525 	 * sfall[st] =  t implies t is fall back state for st
    526 	 * == -1 implies no fall back
    527 	 */
    528 
    529 	int cmin, cval, tcnt, diff, p, *ast;
    530 	int i, j, k;
    531 	CHR *ach;
    532 	int go[MAXNCG], temp[MAXNCG], index, c;
    533 	int swork[MAXNCG];
    534 	CHR cwork[MAXNCG];
    535 	int upper;
    536 
    537 	rcount += (long)cnt;
    538 	cmin = -1;
    539 	cval = ncg;
    540 	ast = tst;
    541 	ach = tch;
    542 	/* try to pack transitions using ccl's */
    543 	if (!optim)
    544 		goto nopack; /* skip all compaction */
    545 	if (tryit) { /* ccl's used */
    546 		for (i = 1; i < ncg; i++) {
    547 			go[i] = temp[i] = -1;
    548 			symbol[i] = 1;
    549 		}
    550 		for (i = 0; i < cnt; i++) {
    551 			index = (unsigned char) tch[i];
    552 			if ((index >= 0) && (index < NCH)) {
    553 				go[index] = tst[i];
    554 				symbol[index] = 0;
    555 			} else {
    556 				fprintf(stderr,
    557 "lex`sub2`packtran: tch[%d] out of bounds (%ld)\n",
    558 				i, (long)tch[i]);
    559 			}
    560 		}
    561 		for (i = 0; i < cnt; i++) {
    562 			c = match[tch[i]];
    563 			if (go[c] != tst[i] || c == tch[i])
    564 				temp[tch[i]] = tst[i];
    565 		}
    566 		/* fill in error entries */
    567 		for (i = 1; i < ncg; i++)
    568 			if (symbol[i])
    569 				temp[i] = -2;	/* error trans */
    570 		/* count them */
    571 		k = 0;
    572 		for (i = 1; i < ncg; i++)
    573 			if (temp[i] != -1)
    574 				k++;
    575 		if (k < cnt) { /* compress by char */
    576 #ifdef DEBUG
    577 			if (debug)
    578 				printf(
    579 				"use compression  %d,  %d vs %d\n", st, k, cnt);
    580 #endif
    581 			k = 0;
    582 			for (i = 1; i < ncg; i++)
    583 				if (temp[i] != -1) {
    584 					cwork[k] = i;
    585 					swork[k++] =
    586 					(temp[i] == -2 ? -1 : temp[i]);
    587 				}
    588 			cwork[k] = 0;
    589 #ifdef PC
    590 			ach = cwork;
    591 			ast = swork;
    592 			cnt = k;
    593 			cpackflg[st] = TRUE;
    594 #endif
    595 		}
    596 	}
    597 	/*
    598 	 * get most similar state
    599 	 * reject state with more transitions,
    600 	 * state already represented by a third state,
    601 	 * and state which is compressed by char if ours is not to be
    602 	 */
    603 	for (i = 0; i < st; i++) {
    604 		if (sfall[i] != -1)
    605 			continue;
    606 		if (cpackflg[st] == 1)
    607 			if (!(cpackflg[i] == 1))
    608 				continue;
    609 		p = gotof[i];
    610 		if (p == -1) /* no transitions */
    611 			continue;
    612 		tcnt = nexts[p];
    613 		if (tcnt > cnt)
    614 			continue;
    615 		diff = 0;
    616 		k = 0;
    617 		j = 0;
    618 		upper = p + tcnt;
    619 		while (ach[j] && p < upper) {
    620 			while (ach[j] < nchar[p] && ach[j]) {
    621 				diff++;
    622 				j++;
    623 			}
    624 			if (ach[j] == 0)
    625 				break;
    626 			if (ach[j] > nchar[p]) {
    627 				diff = ncg;
    628 				break;
    629 			}
    630 			/* ach[j] == nchar[p] */
    631 			if (ast[j] != nexts[++p] ||
    632 				ast[j] == -1 ||
    633 				(cpackflg[st] && ach[j] != match[ach[j]]))
    634 				diff++;
    635 			j++;
    636 		}
    637 		while (ach[j]) {
    638 			diff++;
    639 			j++;
    640 		}
    641 		if (p < upper)
    642 			diff = ncg;
    643 		if (diff < cval && diff < tcnt) {
    644 			cval = diff;
    645 			cmin = i;
    646 			if (cval == 0)
    647 				break;
    648 		}
    649 	}
    650 	/* cmin = state "most like" state st */
    651 #ifdef DEBUG
    652 	if (debug)
    653 		printf("select st %d for st %d diff %d\n",
    654 			cmin, st, cval);
    655 #endif
    656 #ifdef PS
    657 	if (cmin != -1) { /* if we can use st cmin */
    658 		gotof[st] = nptr;
    659 		k = 0;
    660 		sfall[st] = cmin;
    661 		p = gotof[cmin] + 1;
    662 		j = 0;
    663 		while (ach[j]) {
    664 			/* if cmin has a transition on c, then so will st */
    665 			/* st may be "larger" than cmin, however */
    666 			while (ach[j] < nchar[p-1] && ach[j]) {
    667 				k++;
    668 				nchar[nptr] = ach[j];
    669 				nexts[++nptr] = ast[j];
    670 				j++;
    671 			}
    672 			if (nchar[p-1] == 0)
    673 				break;
    674 			if (ach[j] > nchar[p-1]) {
    675 				warning("bad transition %d %d", st, cmin);
    676 				goto nopack;
    677 			}
    678 			/* ach[j] == nchar[p-1] */
    679 			if (ast[j] != nexts[p] ||
    680 				ast[j] == -1 ||
    681 				(cpackflg[st] && ach[j] != match[ach[j]])) {
    682 				k++;
    683 				nchar[nptr] = ach[j];
    684 				nexts[++nptr] = ast[j];
    685 			}
    686 			p++;
    687 			j++;
    688 		}
    689 		while (ach[j]) {
    690 			nchar[nptr] = ach[j];
    691 			nexts[++nptr] = ast[j++];
    692 			k++;
    693 		}
    694 		nexts[gotof[st]] = cnt = k;
    695 		nchar[nptr++] = 0;
    696 	} else {
    697 #endif
    698 nopack:
    699 	/* stick it in */
    700 		gotof[st] = nptr;
    701 		nexts[nptr] = cnt;
    702 		for (i = 0; i < cnt; i++) {
    703 			nchar[nptr] = ach[i];
    704 			nexts[++nptr] = ast[i];
    705 		}
    706 		nchar[nptr++] = 0;
    707 #ifdef PS
    708 	}
    709 #endif
    710 	if (cnt < 1) {
    711 		gotof[st] = -1;
    712 		nptr--;
    713 	} else
    714 		if (nptr > ntrans)
    715 			error(
    716 			"Too many transitions %s",
    717 			(ntrans == NTRANS ? "\nTry using %a num" : ""));
    718 }
    719 
    720 #ifdef DEBUG
    721 void
    722 pstate(int s)
    723 {
    724 	int *p, i, j;
    725 	printf("State %d:\n", s);
    726 	p = state[s];
    727 	i = *p++;
    728 	if (i == 0)
    729 		return;
    730 	printf("%4d", *p++);
    731 	for (j = 1; j < i; j++) {
    732 		printf(", %4d", *p++);
    733 		if (j%30 == 0)
    734 			putchar('\n');
    735 	}
    736 	putchar('\n');
    737 }
    738 #endif
    739 
    740 static int
    741 member(int d, CHR *t)
    742 {
    743 	int c;
    744 	CHR *s;
    745 	c = d;
    746 	s = t;
    747 	c = cindex[c];
    748 	while (*s)
    749 		if (*s++ == c)
    750 			return (1);
    751 	return (0);
    752 }
    753 
    754 #ifdef DEBUG
    755 void
    756 stprt(int i)
    757 {
    758 	int p, t;
    759 	printf("State %d:", i);
    760 	/* print actions, if any */
    761 	t = atable[i];
    762 	if (t != -1)
    763 		printf(" final");
    764 	putchar('\n');
    765 	if (cpackflg[i] == TRUE)
    766 		printf("backup char in use\n");
    767 	if (sfall[i] != -1)
    768 		printf("fall back state %d\n", sfall[i]);
    769 	p = gotof[i];
    770 	if (p == -1)
    771 		return;
    772 	printf("(%d transitions)\n", nexts[p]);
    773 	while (nchar[p]) {
    774 		charc = 0;
    775 		if (nexts[p+1] >= 0)
    776 			printf("%d\t", nexts[p+1]);
    777 		else
    778 			printf("err\t");
    779 		allprint(nchar[p++]);
    780 		while (nexts[p] == nexts[p+1] && nchar[p]) {
    781 			if (charc > LINESIZE) {
    782 				charc = 0;
    783 				printf("\n\t");
    784 			}
    785 			allprint(nchar[p++]);
    786 		}
    787 		putchar('\n');
    788 	}
    789 	putchar('\n');
    790 }
    791 #endif
    792 
    793 /* compute action list = set of poss. actions */
    794 static void
    795 acompute(int s)
    796 {
    797 	int *p, i, j;
    798 	int q, r;
    799 	int cnt, m;
    800 	int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n;
    801 	k = 0;
    802 	n = 0;
    803 	p = state[s];
    804 	cnt = *p++;
    805 	if (cnt > MAXPOSSTATE)
    806 		error("Too many positions for one state - acompute");
    807 	for (i = 0; i < cnt; i++) {
    808 		q = *p;
    809 		if (name[q] == FINAL)
    810 			temp[k++] = left[q];
    811 		else if (name[q] == S1FINAL) {
    812 			temp[k++] = left[q];
    813 			if ((r = left[q]) >= NACTIONS)
    814 				error(
    815 				"INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r);
    816 			extra[r] = 1;
    817 		} else if (name[q] == S2FINAL)
    818 			neg[n++] = left[q];
    819 		p++;
    820 	}
    821 	atable[s] = -1;
    822 	if (k < 1 && n < 1)
    823 		return;
    824 #ifdef DEBUG
    825 	if (debug)
    826 		printf("final %d actions:", s);
    827 #endif
    828 	/* sort action list */
    829 	for (i = 0; i < k; i++)
    830 		for (j = i+1; j < k; j++)
    831 			if (temp[j] < temp[i]) {
    832 				m = temp[j];
    833 				temp[j] = temp[i];
    834 				temp[i] = m;
    835 			}
    836 	/* remove dups */
    837 	for (i = 0; i < k-1; i++)
    838 		if (temp[i] == temp[i+1])
    839 			temp[i] = 0;
    840 	/* copy to permanent quarters */
    841 	atable[s] = aptr;
    842 #ifdef DEBUG
    843 	if (!ratfor)
    844 		fprintf(fout, "/* actions for state %d */", s);
    845 #endif
    846 	putc('\n', fout);
    847 	for (i = 0; i < k; i++)
    848 		if (temp[i] != 0) {
    849 			ratfor ?
    850 			fprintf(fout, "data vstop(%d)/%d/\n", aptr, temp[i]) :
    851 			fprintf(fout, "%d,\n", temp[i]);
    852 #ifdef DEBUG
    853 			if (debug)
    854 				printf("%d ", temp[i]);
    855 #endif
    856 			aptr++;
    857 		}
    858 	for (i = 0; i < n; i++) { /* copy fall back actions - all neg */
    859 		ratfor ?
    860 		fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) :
    861 		fprintf(fout, "%d,\n", neg[i]);
    862 		aptr++;
    863 #ifdef DEBUG
    864 		if (debug)
    865 			printf("%d ", neg[i]);
    866 #endif
    867 		}
    868 #ifdef DEBUG
    869 	if (debug)
    870 		putchar('\n');
    871 #endif
    872 	ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) :
    873 		fprintf(fout, "0, \n");
    874 	aptr++;
    875 }
    876 
    877 #ifdef DEBUG
    878 void
    879 pccl(void)
    880 {
    881 	/* print character class sets */
    882 	int i, j;
    883 	printf("char class intersection\n");
    884 	for (i = 0; i < ccount; i++) {
    885 		charc = 0;
    886 		printf("class %d:\n\t", i);
    887 		for (j = 1; j < ncg; j++)
    888 			if (cindex[j] == i) {
    889 				allprint(j);
    890 				if (charc > LINESIZE) {
    891 					printf("\n\t");
    892 					charc = 0;
    893 				}
    894 			}
    895 		putchar('\n');
    896 	}
    897 	charc = 0;
    898 	printf("match:\n");
    899 	for (i = 0; i < ncg; i++) {
    900 		allprint(match[i]);
    901 		if (charc > LINESIZE) {
    902 			putchar('\n');
    903 			charc = 0;
    904 		}
    905 	}
    906 	putchar('\n');
    907 }
    908 #endif
    909 
    910 void
    911 mkmatch(void)
    912 {
    913 	int i;
    914 	CHR tab[MAXNCG];
    915 	for (i = 0; i < ccount; i++)
    916 		tab[i] = 0;
    917 	for (i = 1; i < ncg; i++)
    918 		if (tab[cindex[i]] == 0)
    919 			tab[cindex[i]] = i;
    920 	/* tab[i] = principal char for new ccl i */
    921 	for (i = 1; i < ncg; i++)
    922 		match[i] = tab[cindex[i]];
    923 }
    924 
    925 void
    926 layout(void)
    927 {
    928 	/* format and output final program's tables */
    929 	int i, j, k;
    930 	int  top, bot, startup, omin;
    931 	startup = 0;
    932 	for (i = 0; i < outsize; i++)
    933 		verify[i] = advance[i] = 0;
    934 	omin = 0;
    935 	yytop = 0;
    936 	for (i = 0; i <= stnum; i++) { /* for each state */
    937 		j = gotof[i];
    938 		if (j == -1) {
    939 			stoff[i] = 0;
    940 			continue;
    941 		}
    942 		bot = j;
    943 		while (nchar[j])
    944 			j++;
    945 		top = j - 1;
    946 #if DEBUG
    947 		if (debug) {
    948 			printf("State %d: (layout)\n", i);
    949 			for (j = bot; j <= top; j++) {
    950 				printf("  %o", nchar[j]);
    951 				if (j % 10 == 0)
    952 					putchar('\n');
    953 			}
    954 			putchar('\n');
    955 		}
    956 #endif
    957 		while (verify[omin+ZCH])
    958 			omin++;
    959 		startup = omin;
    960 #if DEBUG
    961 		if (debug)
    962 			printf(
    963 			"bot,top %d, %d startup begins %d\n",
    964 			bot, top, startup);
    965 #endif
    966 		if (chset) {
    967 			do {
    968 				startup += 1;
    969 				if (startup > outsize - ZCH)
    970 					error("output table overflow");
    971 				for (j = bot; j <= top; j++) {
    972 					k = startup+ctable[nchar[j]];
    973 					if (verify[k])
    974 						break;
    975 				}
    976 			} while (j <= top);
    977 #if DEBUG
    978 			if (debug)
    979 				printf(" startup will be %d\n", startup);
    980 #endif
    981 			/* have found place */
    982 			for (j = bot; j <= top; j++) {
    983 				k = startup + ctable[nchar[j]];
    984 				if (ctable[nchar[j]] <= 0)
    985 					printf(
    986 					"j %d nchar %ld ctable.nch %d\n",
    987 					j, (long)nchar[j], ctable[nchar[k]]);
    988 				verify[k] = i + 1;	/* state number + 1 */
    989 				advance[k] = nexts[j+1]+1;
    990 				if (yytop < k)
    991 					yytop = k;
    992 			}
    993 		} else {
    994 			do {
    995 				startup += 1;
    996 				if (startup > outsize - ZCH)
    997 					error("output table overflow");
    998 				for (j = bot; j <= top; j++) {
    999 					k = startup + nchar[j];
   1000 					if (verify[k])
   1001 						break;
   1002 				}
   1003 			} while (j <= top);
   1004 			/* have found place */
   1005 #if DEBUG
   1006 	if (debug)
   1007 		printf(" startup going to be %d\n", startup);
   1008 #endif
   1009 			for (j = bot; j <= top; j++) {
   1010 				k = startup + nchar[j];
   1011 				verify[k] = i+1; /* state number + 1 */
   1012 				advance[k] = nexts[j+1] + 1;
   1013 				if (yytop < k)
   1014 					yytop = k;
   1015 			}
   1016 		}
   1017 		stoff[i] = startup;
   1018 	}
   1019 
   1020 	/* stoff[i] = offset into verify, advance for trans for state i */
   1021 	/* put out yywork */
   1022 	if (ratfor) {
   1023 		fprintf(fout, "define YYTOPVAL %d\n", yytop);
   1024 		rprint(verify, "verif", yytop+1);
   1025 		rprint(advance, "advan", yytop+1);
   1026 		shiftr(stoff, stnum);
   1027 		rprint(stoff, "stoff", stnum+1);
   1028 		shiftr(sfall, stnum);
   1029 		upone(sfall, stnum+1);
   1030 		rprint(sfall, "fall", stnum+1);
   1031 		bprint(extra, "extra", casecount+1);
   1032 		bprint((char *)match, "match", ncg);
   1033 		shiftr(atable, stnum);
   1034 		rprint(atable, "atable", stnum+1);
   1035 	}
   1036 	fprintf(fout,
   1037 	"# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char");
   1038 	fprintf(fout,
   1039 	"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
   1040 	for (i = 0; i <= yytop; i += 4) {
   1041 		for (j = 0; j < 4; j++) {
   1042 			k = i+j;
   1043 			if (verify[k])
   1044 				fprintf(fout,
   1045 				"{ %d,%d },\t", verify[k], advance[k]);
   1046 			else
   1047 				fprintf(fout, "{ 0,0 },\t");
   1048 		}
   1049 		putc('\n', fout);
   1050 	}
   1051 	fprintf(fout, "{0,0}};\n");
   1052 
   1053 	/* put out yysvec */
   1054 
   1055 	fprintf(fout, "struct yysvf yysvec[] = {\n");
   1056 	fprintf(fout, "{ 0,\t0,\t0 },\n");
   1057 	for (i = 0; i <= stnum; i++) {	/* for each state */
   1058 		if (cpackflg[i])
   1059 			stoff[i] = -stoff[i];
   1060 		fprintf(fout, "{ yycrank+%d,\t", stoff[i]);
   1061 		if (sfall[i] != -1)
   1062 			fprintf(fout,
   1063 			"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
   1064 		else
   1065 			fprintf(fout, "0,\t\t");
   1066 		if (atable[i] != -1)
   1067 			fprintf(fout, "yyvstop+%d", atable[i]);
   1068 		else
   1069 			fprintf(fout, "0");
   1070 #ifdef DEBUG
   1071 		fprintf(fout, " },\t\t/* state %d */", i);
   1072 #endif
   1073 		fprintf(fout, " },\t\t/* state %d */", i);
   1074 	}
   1075 	fprintf(fout, "{ 0,\t0,\t0}};\n");
   1076 
   1077 	/* put out yymatch */
   1078 
   1079 	fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop);
   1080 	fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n");
   1081 	if (optim) {
   1082 		if (handleeuc) {
   1083 			fprintf(fout, "int yymatch[] = {\n");
   1084 		} else {
   1085 			fprintf(fout, "char yymatch[] = {\n");
   1086 		}
   1087 		if (chset == 0) { /* no chset, put out in normal order */
   1088 			for (i = 0; i < ncg; i += 8) {
   1089 				for (j = 0; j < 8; j++) {
   1090 					int fbch;
   1091 					fbch = match[i+j];
   1092 					fprintf(fout, "%3d, ", fbch);
   1093 				}
   1094 				putc('\n', fout);
   1095 			}
   1096 		} else {
   1097 			int *fbarr;
   1098 			fbarr = myalloc(2*MAXNCG, sizeof (*fbarr));
   1099 			if (fbarr == 0)
   1100 				error("No space for char table reverse", 0);
   1101 			for (i = 0; i < MAXNCG; i++)
   1102 				fbarr[i] = 0;
   1103 			for (i = 0; i < ncg; i++)
   1104 				fbarr[ctable[i]] = ctable[match[i]];
   1105 			for (i = 0; i < ncg; i += 8) {
   1106 				for (j = 0; j < 8; j++)
   1107 					fprintf(fout, "0%-3o,", fbarr[i+j]);
   1108 				putc('\n', fout);
   1109 			}
   1110 			free(fbarr);
   1111 		}
   1112 		fprintf(fout, "0};\n");
   1113 	}
   1114 	/* put out yyextra */
   1115 	fprintf(fout, "char yyextra[] = {\n");
   1116 	for (i = 0; i < casecount; i += 8) {
   1117 		for (j = 0; j < 8; j++)
   1118 			fprintf(fout, "%d,", i+j < NACTIONS ?
   1119 				extra[i+j] : 0);
   1120 		putc('\n', fout);
   1121 	}
   1122 	fprintf(fout, "0};\n");
   1123 	if (handleeuc) {
   1124 		/* Put out yycgidtbl */
   1125 		fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl);
   1126 		fprintf(fout, "\tunsigned long yycgidtbl[]={");
   1127 		/*
   1128 		 * Use "unsigned long" instead of "lchar" to minimize
   1129 		 * the name-space polution for the application program.
   1130 		 */
   1131 		for (i = 0; i < ncgidtbl; ++i) {
   1132 			if (i%8 == 0)
   1133 				fprintf(fout, "\n\t\t");
   1134 			fprintf(fout, "0x%08lx, ",  yycgidtbl[i]);
   1135 		}
   1136 		fprintf(fout, "\n\t0};\n");
   1137 	}
   1138 }
   1139 
   1140 static void
   1141 rprint(int *a, char *s, int n)
   1142 {
   1143 	int i;
   1144 	fprintf(fout, "block data\n");
   1145 	fprintf(fout, "common /L%s/ %s\n", s, s);
   1146 	fprintf(fout, "define S%s %d\n", s, n);
   1147 	fprintf(fout, "integer %s (S%s)\n", s, s);
   1148 	for (i = 1; i <= n; i++) {
   1149 		if (i%8 == 1)
   1150 			fprintf(fout, "data ");
   1151 		fprintf(fout, "%s (%d)/%d/", s, i, a[i]);
   1152 		fprintf(fout, (i%8 && i < n) ? ", " : "\n");
   1153 	}
   1154 	fprintf(fout, "end\n");
   1155 }
   1156 
   1157 static void
   1158 shiftr(int *a, int n)
   1159 {
   1160 	int i;
   1161 	for (i = n; i >= 0; i--)
   1162 		a[i+1] = a[i];
   1163 }
   1164 
   1165 static void
   1166 upone(int *a, int n)
   1167 {
   1168 	int i;
   1169 	for (i = 0; i <= n; i++)
   1170 		a[i]++;
   1171 }
   1172 
   1173 static void
   1174 bprint(char *a, char *s, int n)
   1175 {
   1176 	int i, j, k;
   1177 	fprintf(fout, "block data\n");
   1178 	fprintf(fout, "common /L%s/ %s\n", s, s);
   1179 	fprintf(fout, "define S%s %d\n", s, n);
   1180 	fprintf(fout, "integer %s (S%s)\n", s, s);
   1181 	for (i = 1; i < n; i += 8) {
   1182 		fprintf(fout, "data %s (%d)/%d/", s, i, a[i]);
   1183 		for (j = 1; j < 8; j++) {
   1184 			k = i+j;
   1185 			if (k < n)
   1186 				fprintf(fout, ", %s (%d)/%d/", s, k, a[k]);
   1187 		}
   1188 		putc('\n', fout);
   1189 	}
   1190 	fprintf(fout, "end\n");
   1191 }
   1192 
   1193 #ifdef PP
   1194 static void
   1195 padd(int **array, int n)
   1196 {
   1197 	int i, *j, k;
   1198 	array[n] = nxtpos;
   1199 	if (count == 0) {
   1200 		*nxtpos++ = 0;
   1201 		return;
   1202 	}
   1203 	for (i = tptr-1; i >= 0; i--) {
   1204 		j = array[i];
   1205 		if (j && *j++ == count) {
   1206 			for (k = 0; k < count; k++)
   1207 				if (!tmpstat[*j++])
   1208 					break;
   1209 			if (k >= count) {
   1210 				array[n] = array[i];
   1211 				return;
   1212 			}
   1213 		}
   1214 	}
   1215 	add(array, n);
   1216 }
   1217 #endif