Annotation of researchv10no/cmd/prefer/prefawk/b.c, revision 1.1

1.1     ! root        1: #define        DEBUG
        !             2: 
        !             3: #include "awk.h"
        !             4: #include <ctype.h>
        !             5: #include <stdio.h>
        !             6: #include "y.tab.h"
        !             7: 
        !             8: #define        HAT     (NCHARS-1)      /* matches ^ in regular expr */
        !             9:                                /* NCHARS is 2**n */
        !            10: #define MAXLIN 256
        !            11: 
        !            12: #define type(v)                (v)->nobj
        !            13: #define left(v)                (v)->narg[0]
        !            14: #define right(v)       (v)->narg[1]
        !            15: #define parent(v)      (v)->nnext
        !            16: 
        !            17: #define LEAF   case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL:
        !            18: #define UNARY  case STAR: case PLUS: case QUEST:
        !            19: 
        !            20: /* encoding in tree Nodes:
        !            21:        leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL):
        !            22:                left is index, right contains value or pointer to value
        !            23:        unary (STAR, PLUS, QUEST): left is child, right is null
        !            24:        binary (CAT, OR): left and right are children
        !            25:        parent contains pointer to parent
        !            26: */
        !            27: 
        !            28: 
        !            29: uchar  chars[MAXLIN];
        !            30: int    setvec[MAXLIN];
        !            31: int    tmpset[MAXLIN];
        !            32: Node   *point[MAXLIN];
        !            33: 
        !            34: int    rtok;           /* next token in current re */
        !            35: int    rlxval;
        !            36: uchar  *rlxstr;
        !            37: uchar  *prestr;        /* current position in current re */
        !            38: uchar  *lastre;        /* origin of last re */
        !            39: 
        !            40: static int setcnt;
        !            41: static int poscnt;
        !            42: 
        !            43: uchar  *patbeg;
        !            44: int    patlen;
        !            45: 
        !            46: #define        NFA     20      /* cache this many dynamic fa's */
        !            47: fa     *fatab[NFA];
        !            48: int    nfatab  = 0;    /* entries in fatab */
        !            49: fa     *mkdfa();
        !            50: 
        !            51: fa *makedfa(s, anchor) /* returns dfa for reg expr s */
        !            52:        uchar *s;
        !            53:        int anchor;
        !            54: {
        !            55:        int i, use, nuse;
        !            56:        fa *pfa;
        !            57: 
        !            58:        if (compile_time)       /* a constant for sure */
        !            59:                return mkdfa(s, anchor);
        !            60:        for (i = 0; i < nfatab; i++)    /* is it there already? */
        !            61:                if (fatab[i]->anchor == anchor && strcmp(fatab[i]->restr,s) == 0) {
        !            62:                        fatab[i]->use++;
        !            63:                        return fatab[i];
        !            64:        }
        !            65:        pfa = mkdfa(s, anchor);
        !            66:        if (nfatab < NFA) {     /* room for another */
        !            67:                fatab[nfatab] = pfa;
        !            68:                fatab[nfatab]->use = 1;
        !            69:                nfatab++;
        !            70:                return pfa;
        !            71:        }
        !            72:        use = fatab[0]->use;    /* replace least-recently used */
        !            73:        nuse = 0;
        !            74:        for (i = 1; i < nfatab; i++)
        !            75:                if (fatab[i]->use < use) {
        !            76:                        use = fatab[i]->use;
        !            77:                        nuse = i;
        !            78:                }
        !            79:        freefa(fatab[nuse]);
        !            80:        fatab[nuse] = pfa;
        !            81:        pfa->use = 1;
        !            82:        return pfa;
        !            83: }
        !            84: 
        !            85: fa *mkdfa(s, anchor)   /* does the real work of making a dfa */
        !            86:        uchar *s;
        !            87:        int anchor;     /* anchor = 1 for anchored matches, else 0 */
        !            88: {
        !            89:        Node *p, *p1, *reparse();
        !            90:        fa *f;
        !            91: 
        !            92:        p = reparse(s);
        !            93:        p1 = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p);
        !            94:                /* put ALL STAR in front of reg.  exp. */
        !            95:        p1 = op2(CAT, p1, op2(FINAL, NIL, NIL));
        !            96:                /* put FINAL after reg.  exp. */
        !            97: 
        !            98:        poscnt = 0;
        !            99:        penter(p1);     /* enter parent pointers and leaf indices */
        !           100:        if ((f = (fa *) Calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL)
        !           101:                overflo("no room for fa");
        !           102:        f->accept = poscnt-1;   /* penter has computed number of positions in re */
        !           103:        cfoll(f, p1);   /* set up follow sets */
        !           104:        freetr(p1);
        !           105:        if ((f->posns[0] = (int *) Calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL)
        !           106:                        overflo("out of space in makedfa");
        !           107:        if ((f->posns[1] = (int *) Calloc(1, sizeof(int))) == NULL)
        !           108:                overflo("out of space in makedfa");
        !           109:        *f->posns[1] = 0;
        !           110:        f->initstat = makeinit(f, anchor);
        !           111:        f->reset = 0;
        !           112:        f->anchor = anchor;
        !           113:        f->restr = tostring(s);
        !           114:        return f;
        !           115: }
        !           116: 
        !           117: int makeinit(f, anchor)
        !           118:        fa *f;
        !           119:        int anchor;
        !           120: {
        !           121:        register i, k;
        !           122: 
        !           123:        f->curstat = 2;
        !           124:        f->out[2] = 0;
        !           125:        k = *(f->re[0].lfollow);
        !           126:        xfree(f->posns[2]);                     
        !           127:        if ((f->posns[2] = (int *) Calloc(1, (k+1)*sizeof(int))) == NULL)
        !           128:                overflo("out of space in makeinit");
        !           129:        for (i=0; i<=k; i++) {
        !           130:                (f->posns[2])[i] = (f->re[0].lfollow)[i];
        !           131:        }
        !           132:        if ((f->posns[2])[1] == f->accept)
        !           133:                f->out[2] = 1;
        !           134:        for (i=0; i<NCHARS; i++)
        !           135:                f->gototab[2][i] = 0;
        !           136:        f->curstat = cgoto(f, 2, HAT);
        !           137:        if (anchor) {
        !           138:                *f->posns[2] = k-1;     /* leave out position 0 */
        !           139:                for (i=0; i<k; i++) {
        !           140:                        (f->posns[0])[i] = (f->posns[2])[i];
        !           141:                }
        !           142: 
        !           143:                f->out[0] = f->out[2];
        !           144:                if (f->curstat != 2)
        !           145:                        --(*f->posns[f->curstat]);
        !           146:        }
        !           147:        return f->curstat;
        !           148: }
        !           149: 
        !           150: penter(p)      /* set up parent pointers and leaf indices */
        !           151:        Node *p;
        !           152: {
        !           153:        switch(type(p)) {
        !           154:        LEAF
        !           155:                left(p) = (Node *) poscnt;
        !           156:                point[poscnt++] = p;
        !           157:                break;
        !           158:        UNARY
        !           159:                penter(left(p));
        !           160:                parent(left(p)) = p;
        !           161:                break;
        !           162:        case CAT:
        !           163:        case OR:
        !           164:                penter(left(p));
        !           165:                penter(right(p));
        !           166:                parent(left(p)) = p;
        !           167:                parent(right(p)) = p;
        !           168:                break;
        !           169:        default:
        !           170:                error(FATAL, "unknown type %d in penter\n", type(p));
        !           171:                break;
        !           172:        }
        !           173: }
        !           174: 
        !           175: freetr(p)      /* free parse tree */
        !           176:        Node *p;
        !           177: {
        !           178:        switch (type(p)) {
        !           179:        LEAF
        !           180:                xfree(p);
        !           181:                break;
        !           182:        UNARY
        !           183:                freetr(left(p));
        !           184:                xfree(p);
        !           185:                break;
        !           186:        case CAT:
        !           187:        case OR:
        !           188:                freetr(left(p));
        !           189:                freetr(right(p));
        !           190:                xfree(p);
        !           191:                break;
        !           192:        default:
        !           193:                error(FATAL, "unknown type %d in freetr", type(p));
        !           194:                break;
        !           195:        }
        !           196: }
        !           197: 
        !           198: uchar *cclenter(p)
        !           199:        register uchar *p;
        !           200: {
        !           201:        register int i, c;
        !           202:        uchar *op;
        !           203: 
        !           204:        op = p;
        !           205:        i = 0;
        !           206:        while ((c = *p++) != 0) {
        !           207:                if (c == '\\') {
        !           208:                        if ((c = *p++) == 't')
        !           209:                                c = '\t';
        !           210:                        else if (c == 'n')
        !           211:                                c = '\n';
        !           212:                        else if (c == 'f')
        !           213:                                c = '\f';
        !           214:                        else if (c == 'r')
        !           215:                                c = '\r';
        !           216:                        else if (c == 'b')
        !           217:                                c = '\b';
        !           218:                        else if (c == '\\')
        !           219:                                c = '\\';
        !           220:                        else if (isdigit(c)) {
        !           221:                                int n = c - '0';
        !           222:                                if (isdigit(*p)) {
        !           223:                                        n = 8 * n + *p++ - '0';
        !           224:                                        if (isdigit(*p))
        !           225:                                                n = 8 * n + *p++ - '0';
        !           226:                                }
        !           227:                                c = n;
        !           228:                        } /* else */
        !           229:                                /* c = c; */
        !           230:                } else if (c == '-' && i > 0 && chars[i-1] != 0) {
        !           231:                        if (*p != 0) {
        !           232:                                c = chars[i-1];
        !           233:                                while (c < *p) {        /* fails if *p is \\ */
        !           234:                                        if (i >= MAXLIN-1)
        !           235:                                                overflo("character class too big");
        !           236:                                        chars[i++] = ++c;
        !           237:                                }
        !           238:                                p++;
        !           239:                                continue;
        !           240:                        }
        !           241:                }
        !           242:                if (i >= MAXLIN-1)
        !           243:                        overflo("character class too big");
        !           244:                chars[i++] = c;
        !           245:        }
        !           246:        chars[i++] = '\0';
        !           247:        dprintf("cclenter: in = |%s|, out = |%s|\n", op, chars, NULL);
        !           248:        xfree(op);
        !           249:        return(tostring(chars));
        !           250: }
        !           251: 
        !           252: overflo(s)
        !           253:        uchar *s;
        !           254: {
        !           255:        error(FATAL, "regular expression too big: %s", s);
        !           256: }
        !           257: 
        !           258: cfoll(f, v)    /* enter follow set of each leaf of vertex v into lfollow[leaf] */
        !           259:        fa *f;
        !           260:        register Node *v;
        !           261: {
        !           262:        register int i;
        !           263:        register int *p;
        !           264: 
        !           265:        switch(type(v)) {
        !           266:        LEAF
        !           267:                f->re[(int) left(v)].ltype = type(v);
        !           268:                f->re[(int) left(v)].lval = (int) right(v);
        !           269:                for (i=0; i<=f->accept; i++)
        !           270:                        setvec[i] = 0;
        !           271:                setcnt = 0;
        !           272:                follow(v);      /* computes setvec and setcnt */
        !           273:                if ((p = (int *) Calloc(1, (setcnt+1)*sizeof(int))) == NULL)
        !           274:                        overflo("follow set overflow");
        !           275:                f->re[(int) left(v)].lfollow = p;
        !           276:                *p = setcnt;
        !           277:                for (i = f->accept; i >= 0; i--)
        !           278:                        if (setvec[i] == 1) *++p = i;
        !           279:                break;
        !           280:        UNARY
        !           281:                cfoll(f,left(v));
        !           282:                break;
        !           283:        case CAT:
        !           284:        case OR:
        !           285:                cfoll(f,left(v));
        !           286:                cfoll(f,right(v));
        !           287:                break;
        !           288:        default:
        !           289:                error(FATAL, "unknown type %d in cfoll", type(v));
        !           290:        }
        !           291: }
        !           292: 
        !           293: first(p)               /* collects initially active leaves of p into setvec */
        !           294:        register Node *p;       /* returns 0 or 1 depending on whether p matches empty string */
        !           295: {
        !           296:        register int b;
        !           297: 
        !           298:        switch(type(p)) {
        !           299:        LEAF
        !           300:                if (setvec[(int) left(p)] != 1) {
        !           301:                        setvec[(int) left(p)] = 1;
        !           302:                        setcnt++;
        !           303:                }
        !           304:                if (type(p) == CCL && (*(uchar *) right(p)) == '\0')
        !           305:                        return(0);              /* empty CCL */
        !           306:                else return(1);
        !           307:        case PLUS:
        !           308:                if (first(left(p)) == 0) return(0);
        !           309:                return(1);
        !           310:        case STAR:
        !           311:        case QUEST:
        !           312:                first(left(p));
        !           313:                return(0);
        !           314:        case CAT:
        !           315:                if (first(left(p)) == 0 && first(right(p)) == 0) return(0);
        !           316:                return(1);
        !           317:        case OR:
        !           318:                b = first(right(p));
        !           319:                if (first(left(p)) == 0 || b == 0) return(0);
        !           320:                return(1);
        !           321:        }
        !           322:        error(FATAL, "unknown type %d in first\n", type(p));
        !           323:        return(-1);
        !           324: }
        !           325: 
        !           326: follow(v)
        !           327:        Node *v;                /* collects leaves that can follow v into setvec */
        !           328: {
        !           329:        Node *p;
        !           330: 
        !           331:        if (type(v) == FINAL)
        !           332:                return;
        !           333:        p = parent(v);
        !           334:        switch (type(p)) {
        !           335:        case STAR:
        !           336:        case PLUS:
        !           337:                first(v);
        !           338:                follow(p);
        !           339:                return;
        !           340: 
        !           341:        case OR:
        !           342:        case QUEST:
        !           343:                follow(p);
        !           344:                return;
        !           345: 
        !           346:        case CAT:
        !           347:                if (v == left(p)) {     /* v is left child of p */
        !           348:                        if (first(right(p)) == 0) {
        !           349:                                follow(p);
        !           350:                                return;
        !           351:                        }
        !           352:                }
        !           353:                else            /* v is right child */
        !           354:                        follow(p);
        !           355:                return;
        !           356:        }
        !           357: }
        !           358: 
        !           359: member(c, s)   /* is c in s? */
        !           360:        register uchar c, *s;
        !           361: {
        !           362:        while (*s)
        !           363:                if (c == *s++)
        !           364:                        return(1);
        !           365:        return(0);
        !           366: }
        !           367: 
        !           368: 
        !           369: match(f, p)
        !           370:        register fa *f;
        !           371:        register uchar *p;
        !           372: {
        !           373:        register int s, ns;
        !           374: 
        !           375:        s = f->reset?makeinit(f,0):f->initstat;
        !           376:        if (f->out[s])
        !           377:                return(1);
        !           378:        do {
        !           379:                if (ns=f->gototab[s][*p])
        !           380:                        s=ns;
        !           381:                else
        !           382:                        s=cgoto(f,s,*p);
        !           383:                if (f->out[s])
        !           384:                        return(1);
        !           385:        } while (*p++ != 0);
        !           386:        return(0);
        !           387: }
        !           388: 
        !           389: pmatch(f, p)
        !           390:        register fa *f;
        !           391:        register uchar *p;
        !           392: {
        !           393:        register s, ns;
        !           394:        register uchar *q;
        !           395:        int i, k;
        !           396: 
        !           397:        s = f->reset?makeinit(f,1):f->initstat;
        !           398:        patbeg = p;
        !           399:        patlen = -1;
        !           400:        do {
        !           401:                q = p;
        !           402:                do {
        !           403:                        if (f->out[s])          /* final state */
        !           404:                                patlen = q-p;
        !           405:                        if (ns=f->gototab[s][*q])
        !           406:                                s=ns;
        !           407:                        else
        !           408:                                s=cgoto(f,s,*q);
        !           409:                        if (s==1)       /* no transition */
        !           410:                                if (patlen >= 0) {
        !           411:                                        patbeg = p;
        !           412:                                        return(1);
        !           413:                                }
        !           414:                                else
        !           415:                                        goto nextin;    /* no match */
        !           416:                } while (*q++ != 0);
        !           417:                if (f->out[s])
        !           418:                        patlen = q-p-1; /* don't count $ */
        !           419:                if (patlen >= 0) {
        !           420:                        patbeg = p;
        !           421:                        return(1);
        !           422:                }
        !           423:        nextin:
        !           424:                s = 2;
        !           425:                if (f->reset) {
        !           426:                        for (i=2; i<=f->curstat; i++)
        !           427:                                Free(f->posns[i]);
        !           428:                        k = *f->posns[0];                       
        !           429:                        if ((f->posns[2] = (int *) Calloc(1, (k+1)*sizeof(int))) == NULL)
        !           430:                                overflo("out of space in pmatch");
        !           431:                        for (i=0; i<=k; i++)
        !           432:                                (f->posns[2])[i] = (f->posns[0])[i];
        !           433:                        f->initstat = f->curstat = 2;
        !           434:                        f->out[2] = f->out[0];
        !           435:                        for (i=0; i<NCHARS; i++)
        !           436:                                f->gototab[2][i] = 0;
        !           437:                }
        !           438:        } while (*p++ != 0);
        !           439:        return (0);
        !           440: }
        !           441: 
        !           442: nematch(f, p)
        !           443:        register fa *f;
        !           444:        register uchar *p;
        !           445: {
        !           446:        register int s, ns;
        !           447:        register uchar *q;
        !           448:        int i, k;
        !           449: 
        !           450:        s = f->reset?makeinit(f,1):f->initstat;
        !           451:        patlen = -1;
        !           452:        while (*p) {
        !           453:                q = p;
        !           454:                do {
        !           455:                        if (f->out[s])          /* final state */
        !           456:                                patlen = q-p;
        !           457:                        if (ns=f->gototab[s][*q])
        !           458:                                s=ns;
        !           459:                        else
        !           460:                                s=cgoto(f,s,*q);
        !           461:                        if (s==1)       /* no transition */
        !           462:                                if (patlen > 0) {
        !           463:                                        patbeg = p;
        !           464:                                        return(1);
        !           465:                                }
        !           466:                                else
        !           467:                                        goto nnextin;   /* no nonempty match */
        !           468:                } while (*q++ != 0);
        !           469:                if (f->out[s])
        !           470:                        patlen = q-p-1; /* don't count $ */
        !           471:                if (patlen > 0 ) {
        !           472:                        patbeg = p;
        !           473:                        return(1);
        !           474:                }
        !           475:        nnextin:
        !           476:                s = 2;
        !           477:                if (f->reset) {
        !           478:                        for (i=2; i<=f->curstat; i++)
        !           479:                                Free(f->posns[i]);
        !           480:                        k = *f->posns[0];                       
        !           481:                        if ((f->posns[2] = (int *) Calloc(1, (k+1)*sizeof(int))) == NULL)
        !           482:                                overflo("out of state space");
        !           483:                        for (i=0; i<=k; i++)
        !           484:                                (f->posns[2])[i] = (f->posns[0])[i];
        !           485:                        f->initstat = f->curstat = 2;
        !           486:                        f->out[2] = f->out[0];
        !           487:                        for (i=0; i<NCHARS; i++)
        !           488:                                f->gototab[2][i] = 0;
        !           489:                }
        !           490:        p++;
        !           491:        }
        !           492:        return (0);
        !           493: }
        !           494: 
        !           495: Node *regexp(), *primary(), *concat(), *alt(), *unary();
        !           496: 
        !           497: Node *reparse(p)
        !           498:        uchar *p;
        !           499: {
        !           500:        /* parses regular expression pointed to by p */
        !           501:        /* uses relex() to scan regular expression */
        !           502:        Node *np;
        !           503: 
        !           504:        dprintf("reparse <%s>\n", p);
        !           505:        lastre = prestr = p;    /* prestr points to string to be parsed */
        !           506:        rtok = relex();
        !           507:        if (rtok == '\0')
        !           508:                error(FATAL, "empty regular expression");
        !           509:        np = regexp();
        !           510:        if (rtok == '\0')
        !           511:                return(np);
        !           512:        else
        !           513:                error(FATAL, "syntax error in regular expression %s at %s", lastre, prestr);
        !           514: }
        !           515: 
        !           516: Node *regexp()
        !           517: {
        !           518:        return (alt(concat(primary())));
        !           519: }
        !           520: 
        !           521: Node *primary()
        !           522: {
        !           523:        Node *np;
        !           524: 
        !           525:        switch (rtok) {
        !           526:        case CHAR:
        !           527:                np = op2(CHAR, NIL, (Node *) rlxval);
        !           528:                rtok = relex();
        !           529:                return (unary(np));
        !           530:        case ALL:
        !           531:                rtok = relex();
        !           532:                return (unary(op2(ALL, NIL, NIL)));
        !           533:        case DOT:
        !           534:                rtok = relex();
        !           535:                return (unary(op2(DOT, NIL, NIL)));
        !           536:        case CCL:
        !           537:                np = op2(CCL, NIL, cclenter(rlxstr));
        !           538:                rtok = relex();
        !           539:                return (unary(np));
        !           540:        case NCCL:
        !           541:                np = op2(NCCL, NIL, cclenter(rlxstr));
        !           542:                rtok = relex();
        !           543:                return (unary(np));
        !           544:        case '^':
        !           545:                rtok = relex();
        !           546:                return (unary(op2(CHAR, NIL, (Node *) HAT)));
        !           547:        case '$':
        !           548:                rtok = relex();
        !           549:                return (unary(op2(CHAR, NIL, NIL)));
        !           550:        case '(':
        !           551:                rtok = relex();
        !           552:                if (rtok == ')') {      /* special pleading for () */
        !           553:                        rtok = relex();
        !           554:                        return unary(op2(CCL, NIL, tostring("")));
        !           555:                }
        !           556:                np = regexp();
        !           557:                if (rtok == ')') {
        !           558:                        rtok = relex();
        !           559:                        return (unary(np));
        !           560:                }
        !           561:                else
        !           562:                        error(FATAL, "syntax error in regular expression %s at %s", lastre, prestr);
        !           563:        default:
        !           564:                error(FATAL, "illegal primary in regular expression %s at %s", lastre, prestr);
        !           565:        }
        !           566: }
        !           567: 
        !           568: Node *concat(np)
        !           569:        Node *np;
        !           570: {
        !           571:        switch (rtok) {
        !           572:        case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(':
        !           573:                return (concat(op2(CAT, np, primary())));
        !           574:        default:
        !           575:                return (np);
        !           576:        }
        !           577: }
        !           578: 
        !           579: Node *alt(np)
        !           580:        Node *np;
        !           581: {
        !           582:        if (rtok == OR) {
        !           583:                rtok = relex();
        !           584:                return (alt(op2(OR, np, concat(primary()))));
        !           585:        }
        !           586:        return (np);
        !           587: }
        !           588: 
        !           589: Node *unary(np)
        !           590:        Node *np;
        !           591: {
        !           592:        switch (rtok) {
        !           593:        case STAR:
        !           594:                rtok = relex();
        !           595:                return (unary(op2(STAR, np, NIL)));
        !           596:        case PLUS:
        !           597:                rtok = relex();
        !           598:                return (unary(op2(PLUS, np, NIL)));
        !           599:        case QUEST:
        !           600:                rtok = relex();
        !           601:                return (unary(op2(QUEST, np, NIL)));
        !           602:        default:
        !           603:                return (np);
        !           604:        }
        !           605: }
        !           606: 
        !           607: relex()                /* lexical analyzer for reparse */
        !           608: {
        !           609:        register int c;
        !           610:        uchar cbuf[150];
        !           611:        int clen, cflag;
        !           612: 
        !           613:        switch (c = *prestr++) {
        !           614:        case '|': return OR;
        !           615:        case '*': return STAR;
        !           616:        case '+': return PLUS;
        !           617:        case '?': return QUEST;
        !           618:        case '.': return DOT;
        !           619:        case '\0': prestr--; return '\0';
        !           620:        case '^':
        !           621:        case '$':
        !           622:        case '(':
        !           623:        case ')':
        !           624:                return c;
        !           625:        case '\\':
        !           626:                if ((c = *prestr++) == 't')
        !           627:                        c = '\t';
        !           628:                else if (c == 'n')
        !           629:                        c = '\n';
        !           630:                else if (c == 'f')
        !           631:                        c = '\f';
        !           632:                else if (c == 'r')
        !           633:                        c = '\r';
        !           634:                else if (c == 'b')
        !           635:                        c = '\b';
        !           636:                else if (c == '\\')
        !           637:                        c = '\\';
        !           638:                else if (isdigit(c)) {
        !           639:                        int n = c - '0';
        !           640:                        if (isdigit(*prestr)) {
        !           641:                                n = 8 * n + *prestr++ - '0';
        !           642:                                if (isdigit(*prestr))
        !           643:                                        n = 8 * n + *prestr++ - '0';
        !           644:                        }
        !           645:                        c = n;
        !           646:                } /* else it's now in c */
        !           647:                rlxval = c;
        !           648:                return CHAR;
        !           649:        default:
        !           650:                rlxval = c;
        !           651:                return CHAR;
        !           652:        case '[': 
        !           653:                clen = 0;
        !           654:                if (*prestr == '^') {
        !           655:                        cflag = 1;
        !           656:                        prestr++;
        !           657:                }
        !           658:                else
        !           659:                        cflag = 0;
        !           660:                for (;;) {
        !           661:                        if ((c = *prestr++) == '\\') {
        !           662:                                cbuf[clen++] = '\\';
        !           663:                                if ((c = *prestr++) == '\0')
        !           664:                                        error(FATAL, "nonterminated character class %s", lastre);
        !           665:                                cbuf[clen++] = c;
        !           666:                        } else if (c == ']') {
        !           667:                                cbuf[clen] = 0;
        !           668:                                rlxstr = tostring(cbuf);
        !           669:                                if (cflag == 0)
        !           670:                                        return CCL;
        !           671:                                else
        !           672:                                        return NCCL;
        !           673:                        } else if (c == '\n') {
        !           674:                                error(FATAL, "newline in character class %s...", lastre);
        !           675:                        } else if (c == '\0') {
        !           676:                                error(FATAL, "nonterminated character class %s", lastre);
        !           677:                        } else
        !           678:                                cbuf[clen++] = c;
        !           679:                }
        !           680:        }
        !           681: }
        !           682: 
        !           683: int cgoto(f, s, c)
        !           684:        fa *f;
        !           685:        int s, c;
        !           686: {
        !           687:        register int i, j, k;
        !           688:        register int *p, *q;
        !           689: 
        !           690:        for (i=0; i<=f->accept; i++)
        !           691:                setvec[i] = 0;
        !           692:        setcnt = 0;
        !           693:        /* compute positions of gototab[s,c] into setvec */
        !           694:        p = f->posns[s];
        !           695:        for (i=1; i<=*p; i++) {
        !           696:                if ((k = f->re[p[i]].ltype) != FINAL) {
        !           697:                        if (k == CHAR && c == f->re[p[i]].lval
        !           698:                                || k == DOT && c != 0 && c != HAT
        !           699:                                || k == ALL && c != 0
        !           700:                                || k == CCL && member(c, (uchar *) f->re[p[i]].lval)
        !           701:                                || k == NCCL && !member(c, (uchar *) f->re[p[i]].lval) && c != 0 && c != HAT) {
        !           702:                                        q = f->re[p[i]].lfollow;
        !           703:                                        for (j=1; j<=*q; j++) {
        !           704:                                                if (setvec[q[j]] == 0) {
        !           705:                                                        setcnt++;
        !           706:                                                        setvec[q[j]] = 1;
        !           707:                                                }
        !           708:                                        }
        !           709:                                }
        !           710:                }
        !           711:        }
        !           712:        /* determine if setvec is a previous state */
        !           713:        tmpset[0] = setcnt;
        !           714:        j = 1;
        !           715:        for (i = f->accept; i >= 0; i--)
        !           716:                if (setvec[i]) {
        !           717:                        tmpset[j++] = i;
        !           718:                }
        !           719:        /* tmpset == previous state? */
        !           720:        for (i=1; i<= f->curstat; i++) {
        !           721:                p = f->posns[i];
        !           722:                if ((k = tmpset[0]) != p[0])
        !           723:                        goto different;
        !           724:                for (j = 1; j <= k; j++)
        !           725:                        if (tmpset[j] != p[j])
        !           726:                                goto different;
        !           727:                /* setvec is state i */
        !           728:                f->gototab[s][c] = i;
        !           729:                return i;
        !           730:        different:;
        !           731:        }
        !           732: 
        !           733:        /* add tmpset to current set of states */
        !           734:        if (f->curstat >= NSTATES-1) {
        !           735:                f->curstat = 2;
        !           736:                f->reset = 1;
        !           737:                for (i=2; i<NSTATES; i++)
        !           738:                        Free(f->posns[i]);
        !           739:        }
        !           740:        else
        !           741:                ++(f->curstat);
        !           742:        for (i=0; i<NCHARS; i++)
        !           743:                f->gototab[f->curstat][i] = 0;
        !           744:        if ((p = (int *) Calloc(1, (setcnt+1)*sizeof(int))) == NULL)
        !           745:                overflo("out of space in cgoto");
        !           746: 
        !           747:        f->posns[f->curstat] = p;
        !           748:        f->gototab[s][c] = f->curstat;
        !           749:        for (i = 0; i <= setcnt; i++)
        !           750:                p[i] = tmpset[i];
        !           751:        if (setvec[f->accept])
        !           752:                f->out[f->curstat] = 1;
        !           753:        else
        !           754:                f->out[f->curstat] = 0;
        !           755:        return f->curstat;
        !           756: }
        !           757: 
        !           758: 
        !           759: freefa(f)
        !           760:        struct fa *f;
        !           761: {
        !           762: 
        !           763:        register int i;
        !           764: 
        !           765:        if (f == NULL)
        !           766:                return;
        !           767:        for (i=0; i<=f->curstat; i++)
        !           768:                Free(f->posns[i]);
        !           769:        for (i=0; i<=f->accept; i++)
        !           770:                Free(f->re[i].lfollow);
        !           771:        Free(f->restr);
        !           772:        Free(f);
        !           773: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.