Annotation of researchv10no/cmd/prefer/prefawk/b.c, revision 1.1.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.