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