version 1.29, 2020/06/10 21:03:56 |
version 1.30, 2020/06/10 21:04:40 |
|
|
} |
} |
|
|
fa *mkdfa(const char *s, bool anchor) /* does the real work of making a dfa */ |
fa *mkdfa(const char *s, bool anchor) /* does the real work of making a dfa */ |
/* anchor = 1 for anchored matches, else 0 */ |
/* anchor = true for anchored matches, else false */ |
{ |
{ |
Node *p, *p1; |
Node *p, *p1; |
fa *f; |
fa *f; |
|
|
k = *(f->re[0].lfollow); |
k = *(f->re[0].lfollow); |
xfree(f->posns[2]); |
xfree(f->posns[2]); |
f->posns[2] = intalloc(k + 1, __func__); |
f->posns[2] = intalloc(k + 1, __func__); |
for (i=0; i <= k; i++) { |
for (i = 0; i <= k; i++) { |
(f->posns[2])[i] = (f->re[0].lfollow)[i]; |
(f->posns[2])[i] = (f->re[0].lfollow)[i]; |
} |
} |
if ((f->posns[2])[1] == f->accept) |
if ((f->posns[2])[1] == f->accept) |
f->out[2] = 1; |
f->out[2] = 1; |
for (i=0; i < NCHARS; i++) |
for (i = 0; i < NCHARS; i++) |
f->gototab[2][i] = 0; |
f->gototab[2][i] = 0; |
f->curstat = cgoto(f, 2, HAT); |
f->curstat = cgoto(f, 2, HAT); |
if (anchor) { |
if (anchor) { |
*f->posns[2] = k-1; /* leave out position 0 */ |
*f->posns[2] = k-1; /* leave out position 0 */ |
for (i=0; i < k; i++) { |
for (i = 0; i < k; i++) { |
(f->posns[0])[i] = (f->posns[2])[i]; |
(f->posns[0])[i] = (f->posns[2])[i]; |
} |
} |
|
|
|
|
} |
} |
if (type(p) == CCL && (*(char *) right(p)) == '\0') |
if (type(p) == CCL && (*(char *) right(p)) == '\0') |
return(0); /* empty CCL */ |
return(0); /* empty CCL */ |
else return(1); |
return(1); |
case PLUS: |
case PLUS: |
if (first(left(p)) == 0) return(0); |
if (first(left(p)) == 0) |
|
return(0); |
return(1); |
return(1); |
case STAR: |
case STAR: |
case QUEST: |
case QUEST: |
|
|
if (buf[--k] && ungetc(buf[k], f) == EOF) |
if (buf[--k] && ungetc(buf[k], f) == EOF) |
FATAL("unable to ungetc '%c'", buf[k]); |
FATAL("unable to ungetc '%c'", buf[k]); |
while (k > i + patlen); |
while (k > i + patlen); |
buf[k] = 0; |
buf[k] = '\0'; |
return true; |
return true; |
} |
} |
else |
else |
|
|
int i, j; |
int i, j; |
uschar *buf = NULL; |
uschar *buf = NULL; |
int ret = 1; |
int ret = 1; |
int init_q = (firstnum == 0); /* first added char will be ? */ |
bool init_q = (firstnum == 0); /* first added char will be ? */ |
int n_q_reps = secondnum-firstnum; /* m>n, so reduce until {1,m-n} left */ |
int n_q_reps = secondnum-firstnum; /* m>n, so reduce until {1,m-n} left */ |
int prefix_length = reptok - basestr; /* prefix includes first rep */ |
int prefix_length = reptok - basestr; /* prefix includes first rep */ |
int suffix_length = strlen((const char *) reptok) - reptoklen; /* string after rep specifier */ |
int suffix_length = strlen((const char *) reptok) - reptoklen; /* string after rep specifier */ |
|
|
buf[j++] = '('; |
buf[j++] = '('; |
buf[j++] = ')'; |
buf[j++] = ')'; |
} |
} |
for (i=1; i < firstnum; i++) { /* copy x reps */ |
for (i = 1; i < firstnum; i++) { /* copy x reps */ |
memcpy(&buf[j], atom, atomlen); |
memcpy(&buf[j], atom, atomlen); |
j += atomlen; |
j += atomlen; |
} |
} |
|
|
} else if (special_case == REPEAT_WITH_Q) { |
} else if (special_case == REPEAT_WITH_Q) { |
if (init_q) |
if (init_q) |
buf[j++] = '?'; |
buf[j++] = '?'; |
for (i = 0; i < n_q_reps; i++) { /* copy x? reps */ |
for (i = init_q; i < n_q_reps; i++) { /* copy x? reps */ |
memcpy(&buf[j], atom, atomlen); |
memcpy(&buf[j], atom, atomlen); |
j += atomlen; |
j += atomlen; |
buf[j++] = '?'; |
buf[j++] = '?'; |
|
|
if (commafound) { |
if (commafound) { |
if (digitfound) { /* {n,m} */ |
if (digitfound) { /* {n,m} */ |
m = num; |
m = num; |
if (m<n) |
if (m < n) |
FATAL("illegal repetition expression: class %.20s", |
FATAL("illegal repetition expression: class %.20s", |
lastre); |
lastre); |
if ((n==0) && (m==1)) { |
if (n == 0 && m == 1) { |
return QUEST; |
return QUEST; |
} |
} |
} else { /* {n,} */ |
} else { /* {n,} */ |
if (n==0) return STAR; |
if (n == 0) |
if (n==1) return PLUS; |
return STAR; |
|
else if (n == 1) |
|
return PLUS; |
} |
} |
} else { |
} else { |
if (digitfound) { /* {n} same as {n,n} */ |
if (digitfound) { /* {n} same as {n,n} */ |
|
|
} |
} |
if (repeat(starttok, prestr-starttok, lastatom, |
if (repeat(starttok, prestr-starttok, lastatom, |
startreptok - lastatom, n, m) > 0) { |
startreptok - lastatom, n, m) > 0) { |
if ((n==0) && (m==0)) { |
if (n == 0 && m == 0) { |
return EMPTYRE; |
return EMPTYRE; |
} |
} |
/* must rescan input for next token */ |
/* must rescan input for next token */ |
|
|
if (tmpset[j] != p[j]) |
if (tmpset[j] != p[j]) |
goto different; |
goto different; |
/* setvec is state i */ |
/* setvec is state i */ |
f->gototab[s][c] = i; |
if (c != HAT) |
|
f->gototab[s][c] = i; |
return i; |
return i; |
different:; |
different:; |
} |
} |
|
|
p = intalloc(setcnt + 1, __func__); |
p = intalloc(setcnt + 1, __func__); |
|
|
f->posns[f->curstat] = p; |
f->posns[f->curstat] = p; |
f->gototab[s][c] = f->curstat; |
if (c != HAT) |
|
f->gototab[s][c] = f->curstat; |
for (i = 0; i <= setcnt; i++) |
for (i = 0; i <= setcnt; i++) |
p[i] = tmpset[i]; |
p[i] = tmpset[i]; |
if (setvec[f->accept]) |
if (setvec[f->accept]) |
|
|
for (i = 0; i <= f->accept; i++) { |
for (i = 0; i <= f->accept; i++) { |
xfree(f->re[i].lfollow); |
xfree(f->re[i].lfollow); |
if (f->re[i].ltype == CCL || f->re[i].ltype == NCCL) |
if (f->re[i].ltype == CCL || f->re[i].ltype == NCCL) |
xfree((f->re[i].lval.np)); |
xfree(f->re[i].lval.np); |
} |
} |
xfree(f->restr); |
xfree(f->restr); |
xfree(f->out); |
xfree(f->out); |