diff options
Diffstat (limited to 'contrib/one-true-awk/b.c')
-rw-r--r-- | contrib/one-true-awk/b.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/contrib/one-true-awk/b.c b/contrib/one-true-awk/b.c index 8df127f..0d91f23 100644 --- a/contrib/one-true-awk/b.c +++ b/contrib/one-true-awk/b.c @@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -/* lasciate ogne speranza, voi ch'entrate. */ +/* lasciate ogne speranza, voi ch'intrate. */ #define DEBUG @@ -44,10 +44,11 @@ THIS SOFTWARE. #define parent(v) (v)->nnext #define LEAF case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL: +#define ELEAF case EMPTYRE: /* empty string in regexp */ #define UNARY case STAR: case PLUS: case QUEST: /* encoding in tree Nodes: - leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL): + leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL, EMPTYRE): left is index, right contains value or pointer to value unary (STAR, PLUS, QUEST): left is child, right is null binary (CAT, OR): left and right are children @@ -182,6 +183,7 @@ int makeinit(fa *f, int anchor) void penter(Node *p) /* set up parent pointers and leaf indices */ { switch (type(p)) { + ELEAF LEAF info(p) = poscnt; poscnt++; @@ -206,6 +208,7 @@ void penter(Node *p) /* set up parent pointers and leaf indices */ void freetr(Node *p) /* free parse tree */ { switch (type(p)) { + ELEAF LEAF xfree(p); break; @@ -309,7 +312,7 @@ char *cclenter(const char *argp) /* add a character class */ continue; } while (c < c2) { - if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1")) FATAL("out of space for character class [%.10s...] 2", p); *bp++ = ++c; i++; @@ -317,7 +320,7 @@ char *cclenter(const char *argp) /* add a character class */ continue; } } - if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2")) FATAL("out of space for character class [%.10s...] 3", p); *bp++ = c; i++; @@ -339,6 +342,7 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo int *p; switch (type(v)) { + ELEAF LEAF f->re[info(v)].ltype = type(v); f->re[info(v)].lval.np = right(v); @@ -375,11 +379,12 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo } int first(Node *p) /* collects initially active leaves of p into setvec */ - /* returns 1 if p matches empty string */ + /* returns 0 if p matches empty string */ { int b, lp; switch (type(p)) { + ELEAF LEAF lp = info(p); /* look for high-water mark of subscripts */ while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */ @@ -389,6 +394,10 @@ int first(Node *p) /* collects initially active leaves of p into setvec */ if (setvec == 0 || tmpset == 0) overflo("out of space in first()"); } + if (type(p) == EMPTYRE) { + setvec[lp] = 0; + return(0); + } if (setvec[lp] != 1) { setvec[lp] = 1; setcnt++; @@ -465,7 +474,7 @@ int match(fa *f, const char *p0) /* shortest match ? */ if (f->out[s]) return(1); do { - assert(*p < NCHARS); + /* assert(*p < NCHARS); */ if ((ns = f->gototab[s][*p]) != 0) s = ns; else @@ -496,7 +505,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */ do { if (f->out[s]) /* final state */ patlen = q-p; - assert(*q < NCHARS); + /* assert(*q < NCHARS); */ if ((ns = f->gototab[s][*q]) != 0) s = ns; else @@ -554,7 +563,7 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */ do { if (f->out[s]) /* final state */ patlen = q-p; - assert(*q < NCHARS); + /* assert(*q < NCHARS); */ if ((ns = f->gototab[s][*q]) != 0) s = ns; else @@ -601,9 +610,10 @@ Node *reparse(const char *p) /* parses regular expression pointed to by p */ lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */ rtok = relex(); /* GNU compatibility: an empty regexp matches anything */ - if (rtok == '\0') + if (rtok == '\0') { /* FATAL("empty regular expression"); previous */ - return(op2(ALL, NIL, NIL)); + return(op2(EMPTYRE, NIL, NIL)); + } np = regexp(); if (rtok != '\0') FATAL("syntax error in regular expression %s at %s", lastre, prestr); @@ -627,6 +637,9 @@ Node *primary(void) case ALL: rtok = relex(); return (unary(op2(ALL, NIL, NIL))); + case EMPTYRE: + rtok = relex(); + return (unary(op2(ALL, NIL, NIL))); case DOT: rtok = relex(); return (unary(op2(DOT, NIL, NIL))); @@ -666,7 +679,7 @@ Node *primary(void) Node *concat(Node *np) { switch (rtok) { - case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(': + case CHAR: case DOT: case ALL: case EMPTYRE: case CCL: case NCCL: case '$': case '(': return (concat(op2(CAT, np, primary()))); } return (np); @@ -787,7 +800,7 @@ int relex(void) /* lexical analyzer for reparse */ else cflag = 0; n = 2 * strlen((const char *) prestr)+1; - if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1")) FATAL("out of space for reg expr %.10s...", lastre); for (; ; ) { if ((c = *prestr++) == '\\') { @@ -806,7 +819,7 @@ int relex(void) /* lexical analyzer for reparse */ prestr[2 + cc->cc_namelen] == ']') { prestr += cc->cc_namelen + 3; for (i = 0; i < NCHARS; i++) { - if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0)) + if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2")) FATAL("out of space for reg expr %.10s...", lastre); if (cc->cc_func(i)) { *bp++ = i; @@ -855,6 +868,7 @@ int cgoto(fa *f, int s, int c) if ((k == CHAR && c == ptoi(f->re[p[i]].lval.np)) || (k == DOT && c != 0 && c != HAT) || (k == ALL && c != 0) + || (k == EMPTYRE && c != 0) || (k == CCL && member(c, (char *) f->re[p[i]].lval.up)) || (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) { q = f->re[p[i]].lfollow; |