Annotation of 43BSDReno/usr.bin/grep/old.egrep/old.egrep.y, revision 1.1.1.1

1.1       root        1: /*
                      2:  * egrep -- print lines containing (or not containing) a regular expression
                      3:  *
                      4:  *     status returns:
                      5:  *             0 - ok, and some matches
                      6:  *             1 - ok, but no matches
                      7:  *             2 - some error
                      8:  */
                      9: %token CHAR DOT CCL NCCL OR CAT STAR PLUS QUEST
                     10: %left OR
                     11: %left CHAR DOT CCL NCCL '('
                     12: %left CAT
                     13: %left STAR PLUS QUEST
                     14: 
                     15: %{
                     16: static char *sccsid = "@(#)old.egrep.y 4.6 (Berkeley) 10/7/87";
                     17: #include <stdio.h>
                     18: #include <sys/types.h>
                     19: #include <sys/stat.h>
                     20: #include <ctype.h>
                     21: 
                     22: #define BLKSIZE 8192
                     23: #define MAXLIN 350
                     24: #define MAXPOS 4000
                     25: #define NCHARS 128
                     26: #define NSTATES 128
                     27: #define FINAL -1
                     28: char gotofn[NSTATES][NCHARS];
                     29: char cmap[256];
                     30: int state[NSTATES];
                     31: char out[NSTATES];
                     32: int line = 1;
                     33: int name[MAXLIN];
                     34: int left[MAXLIN];
                     35: int right[MAXLIN];
                     36: int parent[MAXLIN];
                     37: int foll[MAXLIN];
                     38: int positions[MAXPOS];
                     39: char chars[MAXLIN];
                     40: int nxtpos;
                     41: int nxtchar = 0;
                     42: int tmpstat[MAXLIN];
                     43: int initstat[MAXLIN];
                     44: int xstate;
                     45: int count;
                     46: int icount;
                     47: char *input;
                     48: FILE *exprfile;
                     49: 
                     50: long   lnum;
                     51: int    bflag;
                     52: int    cflag;
                     53: int    fflag;
                     54: int    iflag;
                     55: int    lflag;
                     56: int    nflag;
                     57: int    hflag   = 1;
                     58: int    oflag;
                     59: int    sflag;
                     60: int    vflag;
                     61: int    retcode = 0;
                     62: int    nfile;
                     63: int    blkno;
                     64: long   tln;
                     65: int    nsucc;
                     66: 
                     67: int    f;
                     68: char   *fname;
                     69: %}
                     70: 
                     71: %%
                     72: s:     t
                     73:                ={ unary(FINAL, $1);
                     74:                  line--;
                     75:                }
                     76:        ;
                     77: t:     b r
                     78:                ={ $$ = node(CAT, $1, $2); }
                     79:        | OR b r OR
                     80:                ={ $$ = node(CAT, $2, $3); }
                     81:        | OR b r
                     82:                ={ $$ = node(CAT, $2, $3); }
                     83:        | b r OR
                     84:                ={ $$ = node(CAT, $1, $2); }
                     85:        ;
                     86: b:
                     87:                ={ $$ = enter(DOT);
                     88:                   $$ = unary(STAR, $$); }
                     89:        ;
                     90: r:     CHAR
                     91:                ={ $$ = enter($1); }
                     92:        | DOT
                     93:                ={ $$ = enter(DOT); }
                     94:        | CCL
                     95:                ={ $$ = cclenter(CCL); }
                     96:        | NCCL
                     97:                ={ $$ = cclenter(NCCL); }
                     98:        ;
                     99: 
                    100: r:     r OR r
                    101:                ={ $$ = node(OR, $1, $3); }
                    102:        | r r %prec CAT
                    103:                ={ $$ = node(CAT, $1, $2); }
                    104:        | r STAR
                    105:                ={ $$ = unary(STAR, $1); }
                    106:        | r PLUS
                    107:                ={ $$ = unary(PLUS, $1); }
                    108:        | r QUEST
                    109:                ={ $$ = unary(QUEST, $1); }
                    110:        | '(' r ')'
                    111:                ={ $$ = $2; }
                    112:        | error 
                    113:        ;
                    114: 
                    115: %%
                    116: yyerror(s) {
                    117:        fprintf(stderr, "egrep: %s\n", s);
                    118:        exit(2);
                    119: }
                    120: 
                    121: yylex() {
                    122:        extern int yylval;
                    123:        int cclcnt, x;
                    124:        register char c, d;
                    125:        switch(c = nextch()) {
                    126:                case '$':
                    127:                case '^': c = '\n';
                    128:                        goto defchar;
                    129:                case '|': return (OR);
                    130:                case '*': return (STAR);
                    131:                case '+': return (PLUS);
                    132:                case '?': return (QUEST);
                    133:                case '(': return (c);
                    134:                case ')': return (c);
                    135:                case '.': return (DOT);
                    136:                case '\0': return (0);
                    137:                case '\n': return (OR);
                    138:                case '[': 
                    139:                        x = CCL;
                    140:                        cclcnt = 0;
                    141:                        count = nxtchar++;
                    142:                        if ((c = nextch()) == '^') {
                    143:                                x = NCCL;
                    144:                                c = nextch();
                    145:                        }
                    146:                        do {
                    147:                                if (c == '\0') synerror();
                    148:                                if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) {
                    149:                                        if ((d = nextch()) != 0) {
                    150:                                                c = chars[nxtchar-1];
                    151:                                                while (c < d) {
                    152:                                                        if (nxtchar >= MAXLIN) overflo();
                    153:                                                        chars[nxtchar++] = ++c;
                    154:                                                        cclcnt++;
                    155:                                                }
                    156:                                                continue;
                    157:                                        }
                    158:                                }
                    159:                                if (nxtchar >= MAXLIN) overflo();
                    160:                                chars[nxtchar++] = c;
                    161:                                cclcnt++;
                    162:                        } while ((c = nextch()) != ']');
                    163:                        chars[count] = cclcnt;
                    164:                        return (x);
                    165:                case '\\':
                    166:                        if ((c = nextch()) == '\0') synerror();
                    167:                defchar:
                    168:                default: yylval = c; return (CHAR);
                    169:        }
                    170: }
                    171: nextch() {
                    172:        register int c;
                    173:        if (fflag) {
                    174:                if ((c = getc(exprfile)) == EOF) {
                    175:                        fclose(exprfile);
                    176:                        return(0);
                    177:                }
                    178:        }
                    179:        else c = *input++;
                    180:        return(c);
                    181: }
                    182: 
                    183: synerror() {
                    184:        fprintf(stderr, "egrep: syntax error\n");
                    185:        exit(2);
                    186: }
                    187: 
                    188: enter(x) int x; {
                    189:        if(line >= MAXLIN) overflo();
                    190:        name[line] = x;
                    191:        left[line] = 0;
                    192:        right[line] = 0;
                    193:        return(line++);
                    194: }
                    195: 
                    196: cclenter(x) int x; {
                    197:        register linno;
                    198:        linno = enter(x);
                    199:        right[linno] = count;
                    200:        return (linno);
                    201: }
                    202: 
                    203: node(x, l, r) {
                    204:        if(line >= MAXLIN) overflo();
                    205:        name[line] = x;
                    206:        left[line] = l;
                    207:        right[line] = r;
                    208:        parent[l] = line;
                    209:        parent[r] = line;
                    210:        return(line++);
                    211: }
                    212: 
                    213: unary(x, d) {
                    214:        if(line >= MAXLIN) overflo();
                    215:        name[line] = x;
                    216:        left[line] = d;
                    217:        right[line] = 0;
                    218:        parent[d] = line;
                    219:        return(line++);
                    220: }
                    221: overflo() {
                    222:        fprintf(stderr, "egrep: regular expression too long\n");
                    223:        exit(2);
                    224: }
                    225: 
                    226: cfoll(v) {
                    227:        register i;
                    228:        if (left[v] == 0) {
                    229:                count = 0;
                    230:                for (i=1; i<=line; i++) tmpstat[i] = 0;
                    231:                follow(v);
                    232:                add(foll, v);
                    233:        }
                    234:        else if (right[v] == 0) cfoll(left[v]);
                    235:        else {
                    236:                cfoll(left[v]);
                    237:                cfoll(right[v]);
                    238:        }
                    239: }
                    240: cgotofn() {
                    241:        register c, i, k;
                    242:        int n, s;
                    243:        char symbol[NCHARS];
                    244:        int j, nc, pc, pos;
                    245:        int curpos, num;
                    246:        int number, newpos;
                    247:        count = 0;
                    248:        for (n=3; n<=line; n++) tmpstat[n] = 0;
                    249:        if (cstate(line-1)==0) {
                    250:                tmpstat[line] = 1;
                    251:                count++;
                    252:                out[0] = 1;
                    253:        }
                    254:        for (n=3; n<=line; n++) initstat[n] = tmpstat[n];
                    255:        count--;                /*leave out position 1 */
                    256:        icount = count;
                    257:        tmpstat[1] = 0;
                    258:        add(state, 0);
                    259:        n = 0;
                    260:        for (s=0; s<=n; s++)  {
                    261:                if (out[s] == 1) continue;
                    262:                for (i=0; i<NCHARS; i++) symbol[i] = 0;
                    263:                num = positions[state[s]];
                    264:                count = icount;
                    265:                for (i=3; i<=line; i++) tmpstat[i] = initstat[i];
                    266:                pos = state[s] + 1;
                    267:                for (i=0; i<num; i++) {
                    268:                        curpos = positions[pos];
                    269:                        if ((c = name[curpos]) >= 0) {
                    270:                                if (c < NCHARS) symbol[c] = 1;
                    271:                                else if (c == DOT) {
                    272:                                        for (k=0; k<NCHARS; k++)
                    273:                                                if (k!='\n') symbol[k] = 1;
                    274:                                }
                    275:                                else if (c == CCL) {
                    276:                                        nc = chars[right[curpos]];
                    277:                                        pc = right[curpos] + 1;
                    278:                                        for (k=0; k<nc; k++) symbol[chars[pc++]] = 1;
                    279:                                }
                    280:                                else if (c == NCCL) {
                    281:                                        nc = chars[right[curpos]];
                    282:                                        for (j = 0; j < NCHARS; j++) {
                    283:                                                pc = right[curpos] + 1;
                    284:                                                for (k = 0; k < nc; k++)
                    285:                                                        if (j==chars[pc++]) goto cont;
                    286:                                                if (j!='\n') symbol[j] = 1;
                    287:                                                cont:;
                    288:                                        }
                    289:                                }
                    290:                                else printf("something's funny\n");
                    291:                        }
                    292:                        pos++;
                    293:                }
                    294:                for (c=0; c<NCHARS; c++) {
                    295:                        if (symbol[c] == 1) { /* nextstate(s,c) */
                    296:                                count = icount;
                    297:                                for (i=3; i <= line; i++) tmpstat[i] = initstat[i];
                    298:                                pos = state[s] + 1;
                    299:                                for (i=0; i<num; i++) {
                    300:                                        curpos = positions[pos];
                    301:                                        if ((k = name[curpos]) >= 0)
                    302:                                                if (
                    303:                                                        (k == c)
                    304:                                                        | (k == DOT)
                    305:                                                        | (k == CCL && member(c, right[curpos], 1))
                    306:                                                        | (k == NCCL && member(c, right[curpos], 0))
                    307:                                                ) {
                    308:                                                        number = positions[foll[curpos]];
                    309:                                                        newpos = foll[curpos] + 1;
                    310:                                                        for (k=0; k<number; k++) {
                    311:                                                                if (tmpstat[positions[newpos]] != 1) {
                    312:                                                                        tmpstat[positions[newpos]] = 1;
                    313:                                                                        count++;
                    314:                                                                }
                    315:                                                                newpos++;
                    316:                                                        }
                    317:                                                }
                    318:                                        pos++;
                    319:                                } /* end nextstate */
                    320:                                if (notin(n)) {
                    321:                                        if (n >= NSTATES) overflo();
                    322:                                        add(state, ++n);
                    323:                                        if (tmpstat[line] == 1) out[n] = 1;
                    324:                                        gotofn[s][c] = n;
                    325:                                }
                    326:                                else {
                    327:                                        gotofn[s][c] = xstate;
                    328:                                }
                    329:                        }
                    330:                }
                    331:        }
                    332: }
                    333: 
                    334: cstate(v) {
                    335:        register b;
                    336:        if (left[v] == 0) {
                    337:                if (tmpstat[v] != 1) {
                    338:                        tmpstat[v] = 1;
                    339:                        count++;
                    340:                }
                    341:                return(1);
                    342:        }
                    343:        else if (right[v] == 0) {
                    344:                if (cstate(left[v]) == 0) return (0);
                    345:                else if (name[v] == PLUS) return (1);
                    346:                else return (0);
                    347:        }
                    348:        else if (name[v] == CAT) {
                    349:                if (cstate(left[v]) == 0 && cstate(right[v]) == 0) return (0);
                    350:                else return (1);
                    351:        }
                    352:        else { /* name[v] == OR */
                    353:                b = cstate(right[v]);
                    354:                if (cstate(left[v]) == 0 || b == 0) return (0);
                    355:                else return (1);
                    356:        }
                    357: }
                    358: 
                    359: 
                    360: member(symb, set, torf) {
                    361:        register i, num, pos;
                    362:        num = chars[set];
                    363:        pos = set + 1;
                    364:        for (i=0; i<num; i++)
                    365:                if (symb == chars[pos++]) return (torf);
                    366:        return (!torf);
                    367: }
                    368: 
                    369: notin(n) {
                    370:        register i, j, pos;
                    371:        for (i=0; i<=n; i++) {
                    372:                if (positions[state[i]] == count) {
                    373:                        pos = state[i] + 1;
                    374:                        for (j=0; j < count; j++)
                    375:                                if (tmpstat[positions[pos++]] != 1) goto nxt;
                    376:                        xstate = i;
                    377:                        return (0);
                    378:                }
                    379:                nxt: ;
                    380:        }
                    381:        return (1);
                    382: }
                    383: 
                    384: add(array, n) int *array; {
                    385:        register i;
                    386:        if (nxtpos + count > MAXPOS) overflo();
                    387:        array[n] = nxtpos;
                    388:        positions[nxtpos++] = count;
                    389:        for (i=3; i <= line; i++) {
                    390:                if (tmpstat[i] == 1) {
                    391:                        positions[nxtpos++] = i;
                    392:                }
                    393:        }
                    394: }
                    395: 
                    396: follow(v) int v; {
                    397:        int p;
                    398:        if (v == line) return;
                    399:        p = parent[v];
                    400:        switch(name[p]) {
                    401:                case STAR:
                    402:                case PLUS:      cstate(v);
                    403:                                follow(p);
                    404:                                return;
                    405: 
                    406:                case OR:
                    407:                case QUEST:     follow(p);
                    408:                                return;
                    409: 
                    410:                case CAT:       if (v == left[p]) {
                    411:                                        if (cstate(right[p]) == 0) {
                    412:                                                follow(p);
                    413:                                                return;
                    414:                                        }
                    415:                                }
                    416:                                else follow(p);
                    417:                                return;
                    418:                case FINAL:     if (tmpstat[line] != 1) {
                    419:                                        tmpstat[line] = 1;
                    420:                                        count++;
                    421:                                }
                    422:                                return;
                    423:        }
                    424: }
                    425: 
                    426: 
                    427: main(argc, argv)
                    428: char **argv;
                    429: {
                    430:        register int i;
                    431: 
                    432:        while (--argc > 0 && (++argv)[0][0]=='-')
                    433:                switch (argv[0][1]) {
                    434: 
                    435:                case 's':
                    436:                        sflag++;
                    437:                        continue;
                    438: 
                    439:                case 'h':
                    440:                        hflag = 0;
                    441:                        continue;
                    442: 
                    443:                case 'o':
                    444:                        oflag++;
                    445:                        continue;
                    446: 
                    447:                case 'b':
                    448:                        bflag++;
                    449:                        continue;
                    450: 
                    451:                case 'c':
                    452:                        cflag++;
                    453:                        continue;
                    454: 
                    455:                case 'e':
                    456:                        argc--;
                    457:                        argv++;
                    458:                        goto out;
                    459: 
                    460:                case 'f':
                    461:                        fflag++;
                    462:                        continue;
                    463: 
                    464:                case 'i':
                    465:                        iflag++;
                    466:                        for ( i = 'A'; i <= 'Z'; i++ )
                    467:                                cmap[i] = (char) tolower ( i );
                    468:                        continue;
                    469: 
                    470:                case 'l':
                    471:                        lflag++;
                    472:                        continue;
                    473: 
                    474:                case 'n':
                    475:                        nflag++;
                    476:                        continue;
                    477: 
                    478:                case 'v':
                    479:                        vflag++;
                    480:                        continue;
                    481: 
                    482:                default:
                    483:                        fprintf(stderr, "egrep: unknown flag\n");
                    484:                        continue;
                    485:                }
                    486: out:
                    487:        if (argc<=0)
                    488:                exit(2);
                    489: 
                    490:        for (i = 0; i < 256; ++i)
                    491:                cmap[i] = (char)i;
                    492: 
                    493:        if (fflag) {
                    494:                fname = *argv;
                    495:                exprfile = fopen(fname, "r");
                    496:                if (exprfile == (FILE *)NULL) {
                    497:                        fprintf(stderr, "egrep: can't open %s\n", fname);
                    498:                        exit(2);
                    499:                }
                    500:        }
                    501:        else input = *argv;
                    502:        if ( iflag ) {
                    503:                register char *s;
                    504:                for ( s = input; *s != '\0'; s++ )
                    505:                        if ( isupper ( (int)(*s) ) )
                    506:                                *s = (char) tolower ( (int)(*s) );
                    507:        }
                    508:        argc--;
                    509:        argv++;
                    510: 
                    511:        yyparse();
                    512: 
                    513:        cfoll(line-1);
                    514:        cgotofn();
                    515:        nfile = argc;
                    516:        if (argc<=0) {
                    517:                if (lflag) exit(1);
                    518:                execute(0);
                    519:        }
                    520:        else while (--argc >= 0) {
                    521:                execute(*argv);
                    522:                argv++;
                    523:        }
                    524:        exit(retcode != 0 ? retcode : nsucc == 0);
                    525: }
                    526: 
                    527: execute(file)
                    528: char *file;
                    529: {
                    530:        register char *p;
                    531:        register cstat;
                    532:        register ccount;
                    533:        register char *cmapr = cmap;
                    534:        static char *buf;
                    535:        static int blksize;
                    536:        struct stat stb;
                    537:        char *nlp;
                    538:        int istat;
                    539:        if (file) {
                    540:                if ((f = open(file, 0)) < 0) {
                    541:                        fprintf(stderr, "egrep: can't open %s\n", file);
                    542:                        retcode = 2;
                    543:                        return;
                    544:                }
                    545:        }
                    546:        else f = 0;
                    547:        if (buf == NULL) {
                    548:                if (fstat(f, &stb) > 0 && stb.st_blksize > 0)
                    549:                        blksize = stb.st_blksize;
                    550:                else
                    551:                        blksize = BLKSIZE;
                    552:                buf = (char *)malloc(2*blksize);
                    553:                if (buf == NULL) {
                    554:                        fprintf(stderr, "egrep: no memory for %s\n", file);
                    555:                        retcode = 2;
                    556:                        return;
                    557:                }
                    558:        }
                    559:        ccount = 0;
                    560:        lnum = 1;
                    561:        tln = 0;
                    562:        blkno = 0;
                    563:        p = buf;
                    564:        nlp = p;
                    565:        if ((ccount = read(f,p,blksize))<=0) goto done;
                    566:        istat = cstat = gotofn[0]['\n'];
                    567:        if (out[cstat]) goto found;
                    568:        for (;;) {
                    569:                cstat = gotofn[cstat][(unsigned char)cmapr[*(unsigned char *)p]];
                    570:                if (out[cstat]) {
                    571:                found:  for(;;) {
                    572:                                if (*p++ == '\n') {
                    573:                                        if (vflag == 0) {
                    574:                                succeed:        nsucc = 1;
                    575:                                                if (cflag) tln++;
                    576:                                                else if (sflag)
                    577:                                                        ;       /* ugh */
                    578:                                                else if (lflag) {
                    579:                                                        printf("%s\n", file);
                    580:                                                        close(f);
                    581:                                                        return;
                    582:                                                }
                    583:                                                else {
                    584:                                                        if (nfile > 1 && hflag || oflag) printf("%s:", file);
                    585:                                                        if (bflag) printf("%d:", blkno);
                    586:                                                        if (nflag) printf("%ld:", lnum);
                    587:                                                        if (p <= nlp) {
                    588:                                                                while (nlp < &buf[2*blksize]) putchar(*nlp++);
                    589:                                                                nlp = buf;
                    590:                                                        }
                    591:                                                        while (nlp < p) putchar(*nlp++);
                    592:                                                }
                    593:                                        }
                    594:                                        lnum++;
                    595:                                        nlp = p;
                    596:                                        if ((out[(cstat=istat)]) == 0) goto brk2;
                    597:                                }
                    598:                                cfound:
                    599:                                if (--ccount <= 0) {
                    600:                                        if (p <= &buf[blksize]) {
                    601:                                                if ((ccount = read(f, p, blksize)) <= 0) goto done;
                    602:                                        }
                    603:                                        else if (p == &buf[2*blksize]) {
                    604:                                                p = buf;
                    605:                                                if ((ccount = read(f, p, blksize)) <= 0) goto done;
                    606:                                        }
                    607:                                        else {
                    608:                                                if ((ccount = read(f, p, &buf[2*blksize]-p)) <= 0) goto done;
                    609:                                        }
                    610:                                        blkno += ccount / 512;
                    611:                                }
                    612:                        }
                    613:                }
                    614:                if (*p++ == '\n') {
                    615:                        if (vflag) goto succeed;
                    616:                        else {
                    617:                                lnum++;
                    618:                                nlp = p;
                    619:                                if (out[(cstat=istat)]) goto cfound;
                    620:                        }
                    621:                }
                    622:                brk2:
                    623:                if (--ccount <= 0) {
                    624:                        if (p <= &buf[blksize]) {
                    625:                                if ((ccount = read(f, p, blksize)) <= 0) break;
                    626:                        }
                    627:                        else if (p == &buf[2*blksize]) {
                    628:                                p = buf;
                    629:                                if ((ccount = read(f, p, blksize)) <= 0) break;
                    630:                        }
                    631:                        else {
                    632:                                if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
                    633:                        }
                    634:                        blkno += ccount / 512;
                    635:                }
                    636:        }
                    637: done:  close(f);
                    638:        if (cflag) {
                    639:                if (nfile > 1)
                    640:                        printf("%s:", file);
                    641:                printf("%ld\n", tln);
                    642:        }
                    643: }

unix.superglobalmegacorp.com

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