USG_PG3/usr/source/lexgen1/auto.c

# define NDEEP 40 /* NESTING DEPTH */
# include  "../lexgen1/ldefs.c"

/* make automaton for a string */
makeauto(s,m)
	char *s;
{
	int t, state,c, last[NCH], *lp, p, q, reverse;
	int quoted, oldc, level, w, njump[NDEEP], prev[NDEEP], *first;
	char *s1;
	level = 1;
	prev[0] = prev[1] = nstate;
	quoted = 0;
	s = start(s, first=last);
	while (*first)
		addslide(*first++, nstate);
	njump[1] = 0;
for (; c = *s; s++)
	{
	switch (c + (quoted ? 200 : 0))
		{
		case '\\': /* various escapes */
		case '\\' + 200:
			c = ctrans(&s);
		default: /* ordinary letter, match it */
		normal:
			if (ctable[c] == 0) chbad(c);
			addmove(nstate,ctable[c], nstate+1);
			ngo[nstate]=1;
			prev[level] = nstate;
			nstate++;
			break;
		case '"':
			quoted = !quoted;
			break;
		case '"'+200:
			quoted = !quoted;
			break;
		case '?':
			addslide(prev[level], nstate);
			break;
		case '*':
			addslide(prev[level], nstate+1);
		case '+':
			addslide(nstate, nstate+1);
			addslide(nstate, prev[level]);
			nstate++;
			break;
		case '[': /* class */
			reverse = *++s == '^';
			if (reverse) s++;
			lp = last;
			for (s1=s; *s != ']'; s++)
				{
				t= *s;
				c = ctrans(&s);
				if (t != '-' || s== s1 || *(s+1) == ']')
					*lp++ = oldc = c;
				else
					{
					p = oldc;
					s++;
					lp--;
					q = ctrans(&s);
					lp = range(lp,p,q);
					}
				}
			if (reverse) lp = invert(last,lp);
			ngo[nstate] = lp-last;
			while (lp>last)
				{
				t= *--lp;
				if (ctable[t]==0) chbad(t);
				addmove(nstate,ctable[t],nstate+1);
				}
			prev[level] = nstate;
			nstate++;
			break;
		case '.': /* all chars except \n */
			for(c=0; c<NCH; c++)
				if (c!= '\n' && ctable[c])
					{
					addmove(nstate, ctable[c], nstate+1);
					ngo[nstate]++;
					}
			prev[level]=nstate;
			nstate++;
			break;
		case '(':
			prev[level++] = nstate;
			njump[level] = 0;
			break;
		case ')':
			jumpfr(level, njump[level]++)->ii = nstate;
			nstate++;
			w = njump[level];
			for(t=0; t<w; t++)
				{
				p = jumpfr(level,t)->ii;
				addslide(p,nstate);
				}
			level--;
			break;
		case '|': /* alternation */
			jumpfr(level, njump[level]++)->ii = nstate;
			nstate++;
			t = prev[level-1];
			addslide(t, nstate);
			break;
		case '$': /* end of line */
			if (*(s+1) == 0)
				{
				c = '\n';
				extra[m] = 1;
				addstop(nstate, -m);
				}
			goto normal;
		case '/': /* context sensitivity */
			extra[m] = 1;
			addstop(nstate, -m);
			addslide(nstate, nstate+1);
			nstate++;
			break;
		}
	}
if (level != 1)
	warning("unbalanced parentheses");
/* finish up outer level alternations */
w = njump[level];
for(t=0; t<w; t++)
	addslide(jumpfr(level,t)->ii, nstate);
return (nstate++);
}
invert(lbot, ltop)
	int *lbot, *ltop;
{
	int temp[NCH];
	int c;
	for(c=0;c<NCH;c++)
		temp[c]=0;
	while(ltop>lbot)
		temp[*--ltop] = 1;
	for(c=0; c<NCH; c++)
		if (temp[c] == 0 && ctable[c] != 0)
			*lbot++ = c;
	return(lbot);
}