xref: /csrg-svn/old/awk/b.c (revision 6669)
1*6669Smckusick /*	b.c	4.1	82/05/07	*/
2*6669Smckusick 
3*6669Smckusick #include "awk.def"
4*6669Smckusick #include "stdio.h"
5*6669Smckusick #include "awk.h"
6*6669Smckusick 
7*6669Smckusick extern node *op2();
8*6669Smckusick extern struct fa *cgotofn();
9*6669Smckusick #define MAXLIN 256
10*6669Smckusick #define NCHARS 128
11*6669Smckusick #define NSTATES 256
12*6669Smckusick 
13*6669Smckusick #define type(v)	v->nobj
14*6669Smckusick #define left(v)	v->narg[0]
15*6669Smckusick #define right(v)	v->narg[1]
16*6669Smckusick #define parent(v)	v->nnext
17*6669Smckusick 
18*6669Smckusick #define LEAF	case CCL: case NCCL: case CHAR: case DOT:
19*6669Smckusick #define UNARY	case FINAL: case STAR: case PLUS: case QUEST:
20*6669Smckusick 
21*6669Smckusick /* encoding in tree nodes:
22*6669Smckusick 	leaf (CCL, NCCL, CHAR, DOT): left is index, right contains value or pointer to value
23*6669Smckusick 	unary (FINAL, STAR, PLUS, QUEST): left is child, right is null
24*6669Smckusick 	binary (CAT, OR): left and right are children
25*6669Smckusick 	parent contains pointer to parent
26*6669Smckusick */
27*6669Smckusick 
28*6669Smckusick struct fa {
29*6669Smckusick 	int cch;
30*6669Smckusick 	struct fa *st;
31*6669Smckusick };
32*6669Smckusick 
33*6669Smckusick int	*state[NSTATES];
34*6669Smckusick int	*foll[MAXLIN];
35*6669Smckusick char	chars[MAXLIN];
36*6669Smckusick int	setvec[MAXLIN];
37*6669Smckusick node	*point[MAXLIN];
38*6669Smckusick 
39*6669Smckusick int	setcnt;
40*6669Smckusick int	line;
41*6669Smckusick 
42*6669Smckusick 
43*6669Smckusick struct fa *makedfa(p)	/* returns dfa for tree pointed to by p */
44*6669Smckusick node *p;
45*6669Smckusick {
46*6669Smckusick 	node *p1;
47*6669Smckusick 	struct fa *fap;
48*6669Smckusick 	p1 = op2(CAT, op2(STAR, op2(DOT, (node *) 0, (node *) 0), (node *) 0), p);
49*6669Smckusick 		/* put DOT STAR in front of reg. exp. */
50*6669Smckusick 	p1 = op2(FINAL, p1, (node *) 0);		/* install FINAL node */
51*6669Smckusick 
52*6669Smckusick 	line = 0;
53*6669Smckusick 	penter(p1);	/* enter parent pointers and leaf indices */
54*6669Smckusick 	point[line] = p1;	/* FINAL node */
55*6669Smckusick 	setvec[0] = 1;		/* for initial DOT STAR */
56*6669Smckusick 	cfoll(p1);	/* set up follow sets */
57*6669Smckusick 	fap = cgotofn();
58*6669Smckusick 	freetr(p1);	/* add this when alloc works */
59*6669Smckusick 	return(fap);
60*6669Smckusick }
61*6669Smckusick 
62*6669Smckusick penter(p)	/* set up parent pointers and leaf indices */
63*6669Smckusick node *p;
64*6669Smckusick {
65*6669Smckusick 	switch(type(p)) {
66*6669Smckusick 		LEAF
67*6669Smckusick 			left(p) = (node *) line;
68*6669Smckusick 			point[line++] = p;
69*6669Smckusick 			break;
70*6669Smckusick 		UNARY
71*6669Smckusick 			penter(left(p));
72*6669Smckusick 			parent(left(p)) = p;
73*6669Smckusick 			break;
74*6669Smckusick 		case CAT:
75*6669Smckusick 		case OR:
76*6669Smckusick 			penter(left(p));
77*6669Smckusick 			penter(right(p));
78*6669Smckusick 			parent(left(p)) = p;
79*6669Smckusick 			parent(right(p)) = p;
80*6669Smckusick 			break;
81*6669Smckusick 		default:
82*6669Smckusick 			error(FATAL, "unknown type %d in penter\n", type(p));
83*6669Smckusick 			break;
84*6669Smckusick 	}
85*6669Smckusick }
86*6669Smckusick 
87*6669Smckusick freetr(p)	/* free parse tree and follow sets */
88*6669Smckusick node *p;
89*6669Smckusick {
90*6669Smckusick 	switch(type(p)) {
91*6669Smckusick 		LEAF
92*6669Smckusick 			xfree(foll[(int) left(p)]);
93*6669Smckusick 			xfree(p);
94*6669Smckusick 			break;
95*6669Smckusick 		UNARY
96*6669Smckusick 			freetr(left(p));
97*6669Smckusick 			xfree(p);
98*6669Smckusick 			break;
99*6669Smckusick 		case CAT:
100*6669Smckusick 		case OR:
101*6669Smckusick 			freetr(left(p));
102*6669Smckusick 			freetr(right(p));
103*6669Smckusick 			xfree(p);
104*6669Smckusick 			break;
105*6669Smckusick 		default:
106*6669Smckusick 			error(FATAL, "unknown type %d in freetr", type(p));
107*6669Smckusick 			break;
108*6669Smckusick 	}
109*6669Smckusick }
110*6669Smckusick char *cclenter(p)
111*6669Smckusick register char *p;
112*6669Smckusick {
113*6669Smckusick 	register i, c;
114*6669Smckusick 	char *op;
115*6669Smckusick 
116*6669Smckusick 	op = p;
117*6669Smckusick 	i = 0;
118*6669Smckusick 	while ((c = *p++) != 0) {
119*6669Smckusick 		if (c == '-' && i > 0 && chars[i-1] != 0) {
120*6669Smckusick 			if (*p != 0) {
121*6669Smckusick 				c = chars[i-1];
122*6669Smckusick 				while (c < *p) {
123*6669Smckusick 					if (i >= MAXLIN)
124*6669Smckusick 						overflo();
125*6669Smckusick 					chars[i++] = ++c;
126*6669Smckusick 				}
127*6669Smckusick 				p++;
128*6669Smckusick 				continue;
129*6669Smckusick 			}
130*6669Smckusick 		}
131*6669Smckusick 		if (i >= MAXLIN)
132*6669Smckusick 			overflo();
133*6669Smckusick 		chars[i++] = c;
134*6669Smckusick 	}
135*6669Smckusick 	chars[i++] = '\0';
136*6669Smckusick 	dprintf("cclenter: in = |%s|, out = |%s|\n", op, chars, NULL);
137*6669Smckusick 	xfree(op);
138*6669Smckusick 	return(tostring(chars));
139*6669Smckusick }
140*6669Smckusick 
141*6669Smckusick overflo()
142*6669Smckusick {
143*6669Smckusick 	error(FATAL, "regular expression too long\n");
144*6669Smckusick }
145*6669Smckusick 
146*6669Smckusick cfoll(v)		/* enter follow set of each leaf of vertex v into foll[leaf] */
147*6669Smckusick register node *v;
148*6669Smckusick {
149*6669Smckusick 	register i;
150*6669Smckusick 	int prev;
151*6669Smckusick 	int *add();
152*6669Smckusick 
153*6669Smckusick 	switch(type(v)) {
154*6669Smckusick 		LEAF
155*6669Smckusick 			setcnt = 0;
156*6669Smckusick 			for (i=1; i<=line; i++)
157*6669Smckusick 				setvec[i] = 0;
158*6669Smckusick 			follow(v);
159*6669Smckusick 			if (notin(foll, ( (int) left(v))-1, &prev)) {
160*6669Smckusick 				foll[(int) left(v)] = add(setcnt);
161*6669Smckusick 			}
162*6669Smckusick 			else
163*6669Smckusick 				foll[ (int) left(v)] = foll[prev];
164*6669Smckusick 			break;
165*6669Smckusick 		UNARY
166*6669Smckusick 			cfoll(left(v));
167*6669Smckusick 			break;
168*6669Smckusick 		case CAT:
169*6669Smckusick 		case OR:
170*6669Smckusick 			cfoll(left(v));
171*6669Smckusick 			cfoll(right(v));
172*6669Smckusick 			break;
173*6669Smckusick 		default:
174*6669Smckusick 			error(FATAL, "unknown type %d in cfoll", type(v));
175*6669Smckusick 	}
176*6669Smckusick }
177*6669Smckusick 
178*6669Smckusick first(p)			/* collects initially active leaves of p into setvec */
179*6669Smckusick register node *p;		/* returns 0 or 1 depending on whether p matches empty string */
180*6669Smckusick {
181*6669Smckusick 	register b;
182*6669Smckusick 
183*6669Smckusick 	switch(type(p)) {
184*6669Smckusick 		LEAF
185*6669Smckusick 			if (setvec[(int) left(p)] != 1) {
186*6669Smckusick 				setvec[(int) left(p)] = 1;
187*6669Smckusick 				setcnt++;
188*6669Smckusick 			}
189*6669Smckusick 			if (type(p) == CCL && (*(char *) right(p)) == '\0')
190*6669Smckusick 				return(0);		/* empty CCL */
191*6669Smckusick 			else return(1);
192*6669Smckusick 		case FINAL:
193*6669Smckusick 		case PLUS:
194*6669Smckusick 			if (first(left(p)) == 0) return(0);
195*6669Smckusick 			return(1);
196*6669Smckusick 		case STAR:
197*6669Smckusick 		case QUEST:
198*6669Smckusick 			first(left(p));
199*6669Smckusick 			return(0);
200*6669Smckusick 		case CAT:
201*6669Smckusick 			if (first(left(p)) == 0 && first(right(p)) == 0) return(0);
202*6669Smckusick 			return(1);
203*6669Smckusick 		case OR:
204*6669Smckusick 			b = first(right(p));
205*6669Smckusick 			if (first(left(p)) == 0 || b == 0) return(0);
206*6669Smckusick 			return(1);
207*6669Smckusick 	}
208*6669Smckusick 	error(FATAL, "unknown type %d in first\n", type(p));
209*6669Smckusick 	return(-1);
210*6669Smckusick }
211*6669Smckusick 
212*6669Smckusick follow(v)
213*6669Smckusick node *v;		/* collects leaves that can follow v into setvec */
214*6669Smckusick {
215*6669Smckusick 	node *p;
216*6669Smckusick 
217*6669Smckusick 	if (type(v) == FINAL)
218*6669Smckusick 		return;
219*6669Smckusick 	p = parent(v);
220*6669Smckusick 	switch (type(p)) {
221*6669Smckusick 		case STAR:
222*6669Smckusick 		case PLUS:	first(v);
223*6669Smckusick 				follow(p);
224*6669Smckusick 				return;
225*6669Smckusick 
226*6669Smckusick 		case OR:
227*6669Smckusick 		case QUEST:	follow(p);
228*6669Smckusick 				return;
229*6669Smckusick 
230*6669Smckusick 		case CAT:	if (v == left(p)) {	/* v is left child of p */
231*6669Smckusick 					if (first(right(p)) == 0) {
232*6669Smckusick 						follow(p);
233*6669Smckusick 						return;
234*6669Smckusick 					}
235*6669Smckusick 				}
236*6669Smckusick 				else		/* v is right child */
237*6669Smckusick 					follow(p);
238*6669Smckusick 				return;
239*6669Smckusick 		case FINAL:	if (setvec[line] != 1) {
240*6669Smckusick 					setvec[line] = 1;
241*6669Smckusick 					setcnt++;
242*6669Smckusick 				}
243*6669Smckusick 				return;
244*6669Smckusick 	}
245*6669Smckusick }
246*6669Smckusick 
247*6669Smckusick member(c, s)	/* is c in s? */
248*6669Smckusick register char c, *s;
249*6669Smckusick {
250*6669Smckusick 	while (*s)
251*6669Smckusick 		if (c == *s++)
252*6669Smckusick 			return(1);
253*6669Smckusick 	return(0);
254*6669Smckusick }
255*6669Smckusick 
256*6669Smckusick notin(array, n, prev)		/* is setvec in array[0] thru array[n]? */
257*6669Smckusick int **array;
258*6669Smckusick int *prev; {
259*6669Smckusick 	register i, j;
260*6669Smckusick 	int *ptr;
261*6669Smckusick 	for (i=0; i<=n; i++) {
262*6669Smckusick 		ptr = array[i];
263*6669Smckusick 		if (*ptr == setcnt) {
264*6669Smckusick 			for (j=0; j < setcnt; j++)
265*6669Smckusick 				if (setvec[*(++ptr)] != 1) goto nxt;
266*6669Smckusick 			*prev = i;
267*6669Smckusick 			return(0);
268*6669Smckusick 		}
269*6669Smckusick 		nxt: ;
270*6669Smckusick 	}
271*6669Smckusick 	return(1);
272*6669Smckusick }
273*6669Smckusick 
274*6669Smckusick int *add(n) {		/* remember setvec */
275*6669Smckusick 	int *ptr, *p;
276*6669Smckusick 	register i;
277*6669Smckusick 	if ((p = ptr = (int *) malloc((n+1)*sizeof(int))) == NULL)
278*6669Smckusick 		overflo();
279*6669Smckusick 	*ptr = n;
280*6669Smckusick 	dprintf("add(%d)\n", n, NULL, NULL);
281*6669Smckusick 	for (i=1; i <= line; i++)
282*6669Smckusick 		if (setvec[i] == 1) {
283*6669Smckusick 			*(++ptr) = i;
284*6669Smckusick 			dprintf("  ptr = %o, *ptr = %d, i = %d\n", ptr, *ptr, i);
285*6669Smckusick 		}
286*6669Smckusick 	dprintf("\n", NULL, NULL, NULL);
287*6669Smckusick 	return(p);
288*6669Smckusick }
289*6669Smckusick 
290*6669Smckusick struct fa *cgotofn()
291*6669Smckusick {
292*6669Smckusick 	register i, k;
293*6669Smckusick 	register int *ptr;
294*6669Smckusick 	char c;
295*6669Smckusick 	char *p;
296*6669Smckusick 	node *cp;
297*6669Smckusick 	int j, n, s, ind, numtrans;
298*6669Smckusick 	int finflg;
299*6669Smckusick 	int curpos, num, prev;
300*6669Smckusick 	struct fa *where[NSTATES];
301*6669Smckusick 
302*6669Smckusick 	int fatab[257];
303*6669Smckusick 	struct fa *pfa;
304*6669Smckusick 
305*6669Smckusick 	char index[MAXLIN];
306*6669Smckusick 	char iposns[MAXLIN];
307*6669Smckusick 	int sposns[MAXLIN];
308*6669Smckusick 	int spmax, spinit;
309*6669Smckusick 
310*6669Smckusick 	char symbol[NCHARS];
311*6669Smckusick 	char isyms[NCHARS];
312*6669Smckusick 	char ssyms[NCHARS];
313*6669Smckusick 	int ssmax, ssinit;
314*6669Smckusick 
315*6669Smckusick 	for (i=0; i<=line; i++) index[i] = iposns[i] = setvec[i] = 0;
316*6669Smckusick 	for (i=0; i<NCHARS; i++)  isyms[i] = symbol[i] = 0;
317*6669Smckusick 	setcnt = 0;
318*6669Smckusick 	/* compute initial positions and symbols of state 0 */
319*6669Smckusick 	ssmax = 0;
320*6669Smckusick 	ptr = state[0] = foll[0];
321*6669Smckusick 	spinit = *ptr;
322*6669Smckusick 	for (i=0; i<spinit; i++) {
323*6669Smckusick 		curpos = *(++ptr);
324*6669Smckusick 		sposns[i] = curpos;
325*6669Smckusick 		iposns[curpos] = 1;
326*6669Smckusick 		cp = point[curpos];
327*6669Smckusick 		dprintf("i = %d, spinit = %d, curpos = %d\n", i, spinit, curpos);
328*6669Smckusick 		switch (type(cp)) {
329*6669Smckusick 			case CHAR:
330*6669Smckusick 				k = (int) right(cp);
331*6669Smckusick 				if (isyms[k] != 1) {
332*6669Smckusick 					isyms[k] = 1;
333*6669Smckusick 					ssyms[ssmax++] = k;
334*6669Smckusick 				}
335*6669Smckusick 				break;
336*6669Smckusick 			case DOT:
337*6669Smckusick 				for (k=1; k<NCHARS; k++) {
338*6669Smckusick 					if (k != HAT) {
339*6669Smckusick 						if (isyms[k] != 1) {
340*6669Smckusick 							isyms[k] = 1;
341*6669Smckusick 							ssyms[ssmax++] = k;
342*6669Smckusick 						}
343*6669Smckusick 					}
344*6669Smckusick 				}
345*6669Smckusick 				break;
346*6669Smckusick 			case CCL:
347*6669Smckusick 				for (p = (char *) right(cp); *p; p++) {
348*6669Smckusick 					if (*p != HAT) {
349*6669Smckusick 						if (isyms[*p] != 1) {
350*6669Smckusick 							isyms[*p] = 1;
351*6669Smckusick 							ssyms[ssmax++] = *p;
352*6669Smckusick 						}
353*6669Smckusick 					}
354*6669Smckusick 				}
355*6669Smckusick 				break;
356*6669Smckusick 			case NCCL:
357*6669Smckusick 				for (k=1; k<NCHARS; k++) {
358*6669Smckusick 					if (k != HAT && !member(k, (char *) right(cp))) {
359*6669Smckusick 						if (isyms[k] != 1) {
360*6669Smckusick 							isyms[k] = 1;
361*6669Smckusick 							ssyms[ssmax++] = k;
362*6669Smckusick 						}
363*6669Smckusick 					}
364*6669Smckusick 				}
365*6669Smckusick 		}
366*6669Smckusick 	}
367*6669Smckusick 	ssinit = ssmax;
368*6669Smckusick 	n = 0;
369*6669Smckusick 	for (s=0; s<=n; s++)  {
370*6669Smckusick 	dprintf("s = %d\n", s, NULL, NULL);
371*6669Smckusick 		ind = 0;
372*6669Smckusick 		numtrans = 0;
373*6669Smckusick 		finflg = 0;
374*6669Smckusick 		if (*(state[s] + *state[s]) == line) {		/* s final? */
375*6669Smckusick 			finflg = 1;
376*6669Smckusick 			goto tenter;
377*6669Smckusick 		}
378*6669Smckusick 		spmax = spinit;
379*6669Smckusick 		ssmax = ssinit;
380*6669Smckusick 		ptr = state[s];
381*6669Smckusick 		num = *ptr;
382*6669Smckusick 		for (i=0; i<num; i++) {
383*6669Smckusick 			curpos = *(++ptr);
384*6669Smckusick 			if (iposns[curpos] != 1 && index[curpos] != 1) {
385*6669Smckusick 				index[curpos] = 1;
386*6669Smckusick 				sposns[spmax++] = curpos;
387*6669Smckusick 			}
388*6669Smckusick 			cp = point[curpos];
389*6669Smckusick 			switch (type(cp)) {
390*6669Smckusick 				case CHAR:
391*6669Smckusick 					k = (int) right(cp);
392*6669Smckusick 					if (isyms[k] == 0 && symbol[k] == 0) {
393*6669Smckusick 						symbol[k] = 1;
394*6669Smckusick 						ssyms[ssmax++] = k;
395*6669Smckusick 					}
396*6669Smckusick 					break;
397*6669Smckusick 				case DOT:
398*6669Smckusick 					for (k=1; k<NCHARS; k++) {
399*6669Smckusick 						if (k != HAT) {
400*6669Smckusick 							if (isyms[k] == 0 && symbol[k] == 0) {
401*6669Smckusick 								symbol[k] = 1;
402*6669Smckusick 								ssyms[ssmax++] = k;
403*6669Smckusick 							}
404*6669Smckusick 						}
405*6669Smckusick 					}
406*6669Smckusick 					break;
407*6669Smckusick 				case CCL:
408*6669Smckusick 					for (p = (char *) right(cp); *p; p++) {
409*6669Smckusick 						if (*p != HAT) {
410*6669Smckusick 							if (isyms[*p] == 0 && symbol[*p] == 0) {
411*6669Smckusick 								symbol[*p] = 1;
412*6669Smckusick 								ssyms[ssmax++] = *p;
413*6669Smckusick 							}
414*6669Smckusick 						}
415*6669Smckusick 					}
416*6669Smckusick 					break;
417*6669Smckusick 				case NCCL:
418*6669Smckusick 					for (k=1; k<NCHARS; k++) {
419*6669Smckusick 						if (k != HAT && !member(k, (char *) right(cp))) {
420*6669Smckusick 							if (isyms[k] == 0 && symbol[k] == 0) {
421*6669Smckusick 								symbol[k] = 1;
422*6669Smckusick 								ssyms[ssmax++] = k;
423*6669Smckusick 							}
424*6669Smckusick 						}
425*6669Smckusick 					}
426*6669Smckusick 			}
427*6669Smckusick 		}
428*6669Smckusick 		for (j=0; j<ssmax; j++) {	/* nextstate(s, ssyms[j]) */
429*6669Smckusick 			c = ssyms[j];
430*6669Smckusick 			symbol[c] = 0;
431*6669Smckusick 			setcnt = 0;
432*6669Smckusick 			for (k=0; k<=line; k++) setvec[k] = 0;
433*6669Smckusick 			for (i=0; i<spmax; i++) {
434*6669Smckusick 				index[sposns[i]] = 0;
435*6669Smckusick 				cp = point[sposns[i]];
436*6669Smckusick 				if ((k = type(cp)) != FINAL)
437*6669Smckusick 					if (k == CHAR && c == (int) right(cp)
438*6669Smckusick 					 || k == DOT
439*6669Smckusick 					 || k == CCL && member(c, (char *) right(cp))
440*6669Smckusick 					 || k == NCCL && !member(c, (char *) right(cp))) {
441*6669Smckusick 						ptr = foll[sposns[i]];
442*6669Smckusick 						num = *ptr;
443*6669Smckusick 						for (k=0; k<num; k++) {
444*6669Smckusick 							if (setvec[*(++ptr)] != 1
445*6669Smckusick 								&& iposns[*ptr] != 1) {
446*6669Smckusick 								setvec[*ptr] = 1;
447*6669Smckusick 								setcnt++;
448*6669Smckusick 							}
449*6669Smckusick 						}
450*6669Smckusick 					}
451*6669Smckusick 			} /* end nextstate */
452*6669Smckusick 			if (notin(state, n, &prev)) {
453*6669Smckusick 				if (n >= NSTATES) {
454*6669Smckusick 					dprintf("cgotofn: notin; state = %d, n = %d\n", state, n, NULL);
455*6669Smckusick 					overflo();
456*6669Smckusick 				}
457*6669Smckusick 				state[++n] = add(setcnt);
458*6669Smckusick 				dprintf("	delta(%d,%o) = %d", s,c,n);
459*6669Smckusick 				dprintf(", ind = %d\n", ind+1, NULL, NULL);
460*6669Smckusick 				fatab[++ind] = c;
461*6669Smckusick 				fatab[++ind] = n;
462*6669Smckusick 				numtrans++;
463*6669Smckusick 			}
464*6669Smckusick 			else {
465*6669Smckusick 				if (prev != 0) {
466*6669Smckusick 					dprintf("	delta(%d,%o) = %d", s,c,prev);
467*6669Smckusick 					dprintf(", ind = %d\n", ind+1, NULL, NULL);
468*6669Smckusick 					fatab[++ind] = c;
469*6669Smckusick 					fatab[++ind] = prev;
470*6669Smckusick 					numtrans++;
471*6669Smckusick 				}
472*6669Smckusick 			}
473*6669Smckusick 		}
474*6669Smckusick 	tenter:
475*6669Smckusick 		if ((pfa = (struct fa *) malloc((numtrans + 1) * sizeof(struct fa))) == NULL)
476*6669Smckusick 			overflo();
477*6669Smckusick 		where[s] = pfa;
478*6669Smckusick 		if (finflg)
479*6669Smckusick 			pfa->cch = -1;		/* s is a final state */
480*6669Smckusick 		else
481*6669Smckusick 			pfa->cch = numtrans;
482*6669Smckusick 		pfa->st = 0;
483*6669Smckusick 		for (i=1, pfa += 1; i<=numtrans; i++, pfa++) {
484*6669Smckusick 			pfa->cch = fatab[2*i-1];
485*6669Smckusick 			pfa->st = (struct fa *) fatab[2*i];
486*6669Smckusick 		}
487*6669Smckusick 	}
488*6669Smckusick 	for (i=0; i<=n; i++) {
489*6669Smckusick 		xfree(state[i]);	/* free state[i] */
490*6669Smckusick 		pfa = where[i];
491*6669Smckusick 		pfa->st = where[0];
492*6669Smckusick 		dprintf("state %d: (%o)\n", i, pfa, NULL);
493*6669Smckusick 		dprintf("	numtrans = %d,	default = %o\n", pfa->cch, pfa->st, NULL);
494*6669Smckusick 		for (k=1; k<=pfa->cch; k++) {
495*6669Smckusick 			(pfa+k)->st = where[ (int) (pfa+k)->st];
496*6669Smckusick 			dprintf("	char = %o,	nextstate = %o\n",(pfa+k)->cch, (pfa+k)->st, NULL);
497*6669Smckusick 		}
498*6669Smckusick 	}
499*6669Smckusick 	pfa = where[0];
500*6669Smckusick 	if ((num = pfa->cch) < 0)
501*6669Smckusick 		return(where[0]);
502*6669Smckusick 	for (pfa += num; num; num--, pfa--)
503*6669Smckusick 		if (pfa->cch == HAT) {
504*6669Smckusick 			return(pfa->st);
505*6669Smckusick 		}
506*6669Smckusick 	return(where[0]);
507*6669Smckusick }
508*6669Smckusick 
509*6669Smckusick match(pfa, p)
510*6669Smckusick register struct fa *pfa;
511*6669Smckusick register char *p;
512*6669Smckusick {
513*6669Smckusick 	register count;
514*6669Smckusick 	char c;
515*6669Smckusick 	if (p == 0) return(0);
516*6669Smckusick 	if (pfa->cch == 1) {		/* fast test for first character, if possible */
517*6669Smckusick 		c = (++pfa)->cch;
518*6669Smckusick 		do
519*6669Smckusick 			if (c == *p) {
520*6669Smckusick 				p++;
521*6669Smckusick 				pfa = pfa->st;
522*6669Smckusick 				goto adv;
523*6669Smckusick 			}
524*6669Smckusick 		while (*p++ != 0);
525*6669Smckusick 		return(0);
526*6669Smckusick 	}
527*6669Smckusick    adv: if ((count = pfa->cch) < 0) return(1);
528*6669Smckusick 	do {
529*6669Smckusick 		for (pfa += count; count; count--, pfa--)
530*6669Smckusick 			if (pfa->cch == *p) {
531*6669Smckusick 				break;
532*6669Smckusick 			}
533*6669Smckusick 		pfa = pfa->st;
534*6669Smckusick 		if ((count = pfa->cch) < 0) return(1);
535*6669Smckusick 	} while(*p++ != 0);
536*6669Smckusick 	return(0);
537*6669Smckusick }
538