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);
}