# To unbundle, sh this file echo mkfile 1>&2 sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile' -CFLAGS=-O -YFLAGS=-d -NPROC=2 - -egrep: gram.o main.o egrep.o bm.o anal.o - $CC $CFLAGS -o $target $prereq - -install: egrep - cp egrep /usr/bin/egrep - strip /usr/bin/egrep - chmod 775 /usr/bin/egrep - chown bin,bin /usr/bin/egrep - -clean:V: - rm -f *.o egrep - -y.tab.h: gram.o -egrep.o anal.o: y.tab.h -anal.o bm.o egrep.o main.o gram.o: hdr.h - -pp: - smallpr mkfile hdr.h anal.c bm.c egrep.c gram.y main.c - -egrep.bundle:V: - bundle mkfile *.h *.c *.y > $target //GO.SYSIN DD mkfile echo hdr.h 1>&2 sed 's/.//' >hdr.h <<'//GO.SYSIN DD hdr.h' -#include <fio.h> -#include <ctype.h> -#include <libc.h> - -#define BLKSIZE 1024 /* size of reported disk blocks */ -#define MAXLIN 10000 -#define MAXPOS 20000 -#define NCHARS 256 -#define NSTATES 128 -#define FINAL -1 -#define LEFT '\177' /* serves as ^ */ -#define RIGHT '\n' /* serves as record separator and as $ */ - -typedef struct State -{ - struct State *gotofn[NCHARS]; - int out; -} State; -extern State states[]; -State *nxtst(); -extern int state[]; -extern int line; -extern int name[]; -extern int left[]; -extern int right[]; -extern int parent[]; -extern int foll[]; -extern int positions[]; -extern char chars[]; -extern int nxtpos; -extern int nxtfoll; -extern int inxtpos; -extern int nxtfoll; -extern int nxtchar; -extern int tmpstat[]; -extern State *istat; -extern int nstate; -extern int xstate; -extern int count; -extern char *input; -extern char *progname; - -extern char reinit; - -extern int begout; -extern int begcnt; -extern int begstat[]; - -extern int colpos[]; -extern int cntpos; - -extern long lnum; -extern int bflag; -extern int cflag; -extern int fflag; -extern int hflag; -extern int iflag; -extern int lflag; -extern int nflag; -extern int sflag; -extern int vflag; -extern int nfile; -extern long tln; -extern int nsucc; -extern int badbotch; - -extern int expfile; - -extern int bmegrep; -extern int scanexit; //GO.SYSIN DD hdr.h echo y.tab.h 1>&2 sed 's/.//' >y.tab.h <<'//GO.SYSIN DD y.tab.h' -# define CHAR 257 -# define DOT 258 -# define CCL 259 -# define NCCL 260 -# define OR 261 -# define CAT 262 -# define STAR 263 -# define PLUS 264 -# define QUEST 265 //GO.SYSIN DD y.tab.h echo anal.c 1>&2 sed 's/.//' >anal.c <<'//GO.SYSIN DD anal.c' -#include "hdr.h" -#include "y.tab.h" - -#define NLIT 256 -#define LSTART litp = litb -#define LEND {*litp = 0; if(strlen(litb) > strlen(blit))strcpy(blit,litb);} - -static char *litp, litb[NLIT], *blit; - - -/* - islit has to return 1 if we are to use boyer-moore. - in this case, set buf to the literal string and - set bmegrep to 1 if there is a regular expression - beside the literal (literal can be anywhere). -*/ -islit(buf) - char *buf; -{ - bmegrep = 0; - blit = buf; - *blit = 0; - LSTART; - -/* pr(line-2, ""); */ - - lit(line-2); - LEND; - if(strlen(blit) > 1){ - /* bmegrep set by lit */ - return(1); - } - return(0); -} - -/* - lit builds literal strings in litb. we ensure these are compulsory - literal string by only descending the right nodes. -*/ -lit(n) -{ - if(name[n] == CAT){ - lit(left[n]); - lit(right[n]); - } else if(name[n] == PLUS){ - lit(left[n]); - LEND; /* can't go on past a + */ - LSTART; - bmegrep = 1; - lit(left[n]); /* but we can start with one! */ - } else if((name[n] == CCL) && (chars[right[n]] == 1)){ - *litp++ = chars[right[n]+1]; - if(litp == &litb[NLIT]) - litp--; - } else if(left[n] == 0 && name[n] < 256 - && name[n] != LEFT && name[n] != RIGHT){ - *litp++ = name[n]; - if(litp == &litb[NLIT]) - litp--; - } else { - LEND; - LSTART; - bmegrep = 1; - } -} - -/*#ifdef DEBUG*/ - -pr(n, s) - char *s; -{ - char buf[256]; - int i, cnt; - - print("%s", s); - sprint(buf, "%s ", s); - switch(name[n]) - { - case FINAL: print("expr=\n"); pr(left[n], buf); break; - case DOT: print("%d: .\n",n); break; - case STAR: print("%d: *\n",n); pr(left[n], buf); break; - case PLUS: print("%d: +\n",n); pr(left[n], buf); break; - case QUEST: print("%d: ?\n",n); pr(left[n], buf); break; - case CAT: print("%d: cat\n", n); pr(left[n], buf); pr(right[n], buf); break; - case OR: print("%d: or\n", n); pr(left[n], buf); pr(right[n], buf); break; - case NCCL: - case CCL: print("%d: [%s", n, name[n]==NCCL? "^":""); - for(i = right[n], cnt = chars[i++]; cnt > 0; cnt--) - print("%c", chars[i++]); - print("]\n"); - break; - default: - if(name[n] < 256) - print("%d: '%c'\n", n, name[n]); - else - print("URK %d\n", name[n]); - break; - } -} -/*#endif*/ //GO.SYSIN DD anal.c echo bm.c 1>&2 sed 's/.//' >bm.c <<'//GO.SYSIN DD bm.c' -#include "hdr.h" - -#define LARGE 100000 - -static int delta0[256]; -static char cmap[256]; -static char *bmpat; - -bmprep(pattern) - char *pattern; -{ - register int j, patlen; - - patlen = strlen(bmpat = pattern); - for(j = 0; j < 256; j++){ - delta0[j] = patlen; - cmap[j] = j; - } - for(j = 0; j < patlen-1; j++) - delta0[pattern[j]] = patlen-j-1; - delta0[pattern[patlen-1]] = LARGE; - if(iflag){ - for(j = 0; j < patlen-1; j++) - if(islower(pattern[j])) - delta0[toupper(pattern[j])] = patlen-j-1; - if(islower(pattern[patlen-1])) - delta0[toupper(pattern[patlen-1])] = LARGE; - for(j = 'A'; j <= 'Z'; j++) - cmap[j] = tolower(j); - } -} - -bmexecute(file) -char *file; -{ - register char *p; - register char *endpt; - register char *s; - register int j; - int len, patlen = strlen(bmpat); - char *rdpt; - int fd, eof, n; - long seek; - char *nlp, *proc, *np, *op; - char buf[8*8192]; - - if(file){ - if((fd = open(file, 0)) < 0){ - fprint(2, "%s: can't open %s\n", progname, file); - badbotch=1; - return; - } - } else - fd = 0; - lnum = 1; - tln = 0; - rdpt = buf; - seek = 0; - for(eof = 0; eof == 0;){ - Fflush(1); - if((n = read(fd, rdpt, &buf[sizeof buf]-rdpt)) <= 0){ - if(rdpt == buf) - break; /* eof, nothing left to process */ - *rdpt = '\n'; /* terminate */ - endpt = rdpt+1; - eof = 1; - } else { - for(p = &rdpt[n]; p >= rdpt;) - if(*--p == '\n') - break; - if(p < rdpt){ /* line bigger than buf!! */ - rdpt = &buf[sizeof buf/2]; /* chop in half */ - continue; /* reading */ - } - endpt = p+1; - } - /* - invariants: - no newline between buf and rdpt[-1] - lnum = nlines before buf - seek = char offset of buf[0] - last char read is rdpt[n-1] - first char after last \n is endpt - - following is exited to three places: - succeed: match - refresh: !match (readjust ptrs and loop) - - */ - p = buf+patlen-1; - proc = buf-1; - scan: - for(;;){ - while((p += delta0[*(unsigned char *)p]) < endpt) - ; - if(p < (buf+LARGE)){ /* no match */ - goto refresh; - } - p -= LARGE; - for(j = patlen-2, s = p-1; j >= 0; j--) - if(cmap[*s--] != bmpat[j]) - break; - if(j < 0) /* match!! */ - goto succeed; - fail: - p++; - } - succeed: - if(bmegrep || !cflag || !sflag){ /* lflag doesn't matter */ - nlp = memchr(p, '\n', (endpt+1)-p); - op = p; - p -= patlen-1; - while(*p != '\n') - if(--p < buf) break; - p++; - if(bmegrep) - if(legrep(p) == 0){ - p = op; - goto fail; - } - } - nsucc = 1; - if (cflag){ - tln++; - p = nlp+1; - goto scan; - } else if(sflag){ - if(scanexit) exit(0); - } else if(lflag){ - Fprint(1, "%s\n", file); - close(fd); - return; - } else { - if (nfile > 1 && hflag) - Fprint(1, "%s:", file); - if (bflag) - Fprint(1, "%ld:", (seek+(p-buf))/BLKSIZE); - if (nflag){ - while(np = memchr(proc+1, '\n', p-proc)){ - lnum++; - proc = np; - } - Fprint(1, "%ld:", lnum); - } - Fwrite(1, p, nlp-p+1); - p = nlp+1; - if(p < endpt) - goto scan; - } - refresh: - if(nflag){ /* count newlines that we haven't proc */ - while(proc = memchr(proc+1, '\n', endpt-proc)) - lnum++; - } - memcpy(buf, endpt, j = &rdpt[n]-endpt); - rdpt = &buf[j]; - seek += n; - } -done: close(fd); - if (cflag) { - if (nfile > 1) - Fprint(1, "%s:", file); - Fprint(1, "%ld\n", tln); - } -} - -/* - isn't egrep pretty when it just has to mtach or not? -*/ - -legrep(p) - register char *p; -{ - register State *cstat, *t; - - if(reinit == 1) - clearg(); - cstat = istat; - if(cstat->out) - return(1); - for(;;){ - if((t = cstat->gotofn[*(unsigned char *)p]) == 0) - cstat = nxtst(cstat, *(unsigned char *)p); - else - cstat = t; - if(cstat->out){ - return(1); - } - if(*p++ == RIGHT){ - return(0); - } - } -} //GO.SYSIN DD bm.c echo egrep.c 1>&2 sed 's/.//' >egrep.c <<'//GO.SYSIN DD egrep.c' -#include "hdr.h" -#include "y.tab.h" - -cgotofn() { - register i; - count = cntpos = 0; - nxtpos = 0; - nxtfoll = MAXPOS-1; - begout = 0; - for (i=1; i<=line; i++) colpos[i] = 0; - if (first(line-1)==0) { - colpos[line] = 1; - cntpos++; - begout = 1; - } - for (i=1; i<=line; i++) tmpstat[i] = begstat[i] = colpos[i]; - count = begcnt = cntpos-1; /* leave out position 1 */ - tmpstat[1] = begstat[1] = 0; - addstate(1); - inxtpos = nxtpos; - istat = nxtst(states+1,LEFT); -} - -State * -nxtst(ss,c) -State *ss; -char c; -{ - register i, num, k; - int pos, curpos, number, newpos; - int s = ss-states; - num = positions[state[s]]; - count = begcnt; - for (i=3; i<=line; i++) tmpstat[i] = begstat[i]; - pos = state[s] + 1; - for (i=0; i<num; i++) { - curpos = positions[pos]; - if ((k = name[curpos]) >= 0) { - if ( - (k == c) - | (k == DOT && c != LEFT && c != RIGHT) - | (k == CCL && member(c, right[curpos], 1)) - | (k == NCCL && member(c, right[curpos], 0) && c != LEFT && c != RIGHT) - ) { - if (foll[curpos] == 0) { - cntpos = 0; - for (k=1; k<=line; k++) colpos[k] = 0; - follow(curpos); - addfoll(curpos); - } - number = positions[foll[curpos]]; - newpos = foll[curpos] - 1; - for (k=0; k<number; k++) { - if (tmpstat[positions[newpos]] != 1) { - tmpstat[positions[newpos]] = 1; - count++; - } - newpos--; - } - } - } - pos++; - } - if (notin(nstate)) { - if (++nstate >= NSTATES) { - nxtpos = inxtpos; - reinit = 1; - nstate = 1; - addstate(1); - return states+1; - } - addstate(nstate); - return(states[s].gotofn[c] = states+nstate); - } - else { - return(states[s].gotofn[c] = states+xstate); - } -} - -first(v) { - register b; - if (left[v] == 0) { - if (colpos[v] != 1) { - colpos[v] = 1; - cntpos++; - } - return(1); - } - else if (right[v] == 0) { - if (first(left[v]) == 0) return (0); - else if (name[v] == PLUS) return (1); - else return (0); - } - else if (name[v] == CAT) { - if (first(left[v]) == 0 && first(right[v]) == 0) return (0); - else return (1); - } - else { /* name[v] == OR */ - b = first(right[v]); - if (first(left[v]) == 0 || b == 0) return (0); - else return (1); - } -} - -member(symb, set, torf) { - register i, num, pos; - num = chars[set]; - pos = set + 1; - for (i=0; i<num; i++) - if (symb == chars[pos++]) return (torf); - return (!torf); -} - -notin(n) { - register i, j, pos; - for (i=1; i<=n; i++) { - if (positions[state[i]] == count) { - pos = state[i] + 1; - for (j=0; j < count; j++) { - if (tmpstat[positions[pos++]] != 1) goto nxt; } - xstate = i; - return (0); - } - nxt: ; - } - return (1); -} - -addstate(n) { - register i; - if (nxtpos + count >= nxtfoll) { - overflo(); } - for (i=0; i<NCHARS; i++) - states[n].gotofn[i] = 0; - state[n] = nxtpos; - positions[nxtpos++] = count; - for (i=3; i <= line; i++) { - if (tmpstat[i] == 1) { - positions[nxtpos++] = i; - } - } - if (tmpstat[line] == 1) - states[n].out = 1; - else - states[n].out = 0; -} - -addfoll(n) { - register i; - if (nxtfoll - cntpos <= nxtpos) { - overflo(); } - foll[n] = nxtfoll; - positions[nxtfoll--] = cntpos; - for (i=3; i <= line; i++) { - if (colpos[i] == 1) { - positions[nxtfoll--] = i; - } - } -} - -follow(v) int v; { - int p; - if (v == line) return; - p = parent[v]; - switch(name[p]) { - case STAR: - case PLUS: first(v); - follow(p); - return; - - case OR: - case QUEST: follow(p); - return; - - case CAT: if (v == left[p]) { - if (first(right[p]) == 0) { - follow(p); - return; - } - } - else follow(p); - return; - case FINAL: if (colpos[line] != 1) { - colpos[line] = 1; - cntpos++; - } - return; - } -} - -clearg() { - register i; - reinit = 0; - states[1].out = begout; - for (i=0; i<NCHARS; i++) - states[1].gotofn[i] = 0; - nstate = 1; - state[1] = 0; - istat = nxtst(states+1,LEFT); -} - -execute(file) -char *file; -{ - register char *p; - register State *cstat, *t; - int len; - char *nlp; - int f; - -#define READLINE if((p = nlp = Frdline(f)) == 0)\ - goto done;\ - else /* Frdline nulls the \n, put it back */\ - len = FIOLINELEN(f), nlp[len++] = RIGHT - - if (file) { - if ((f = open(file, 0)) < 0) { - fprint(2, "%s: can't open %s\n", progname, file); - badbotch=1; - return; - } - } - else f = 0; - Finit(f, (char *)0); - Ftie(f, 1); /* link input f with stdout */ - lnum = 1; - tln = 0; - READLINE; - cstat = istat; - if (cstat->out) goto found; - for (;;) { - if ((t = cstat->gotofn[*p]) == 0) - cstat = nxtst(cstat, *p); - else - cstat = t; - if (cstat->out) { - found: - if (vflag == 0) { - succeed: nsucc = 1; - if (cflag) tln++; - else if (sflag){ - if(scanexit) exit(0); - } else if (lflag) { - Fprint(1, "%s\n", file); - close(f); - return; - } - else { - if (nfile > 1 && hflag) - Fprint(1, "%s:", file); - if (bflag) - Fprint(1, "%ld:", (FIOSEEK(f)-len)/BLKSIZE); - if (nflag) - Fprint(1, "%ld:", lnum); - Fwrite(1, nlp, len); - } - } - lnum++; - READLINE; - if (reinit == 1) clearg(); - if ((cstat = istat)->out) - goto found; /* we are a match already */ - else - continue; /* normal pattern matching loop */ - } - if (*p++ == RIGHT) { - if (vflag) goto succeed; - else { - lnum++; - READLINE; - if (reinit == 1) clearg(); - if ((cstat = istat)->out) - goto found; /* we are a match already */ - } - } - } -done: close(f); - if (cflag) { - if (nfile > 1) - Fprint(1, "%s:", file); - Fprint(1, "%ld\n", tln); - } -} //GO.SYSIN DD egrep.c echo main.c 1>&2 sed 's/.//' >main.c <<'//GO.SYSIN DD main.c' -#include "hdr.h" - -State states[NSTATES]; -State *nxtst(); -int state[NSTATES]; -int line = 1; -int name[MAXLIN]; -int left[MAXLIN]; -int right[MAXLIN]; -int parent[MAXLIN]; -int foll[MAXLIN]; -int positions[MAXPOS]; -char chars[MAXLIN]; -int nxtpos = 0; -int inxtpos; -int nxtchar = 0; -int tmpstat[MAXLIN]; -int begstat[MAXLIN]; -int colpos[MAXLIN]; -State *istat; -int nstate = 1; -int xstate; -int count; -int icount; -char *input; -char *progname; -int begout; -int begcnt; -int cntpos; -int nxtfoll; - -char reinit = 0; - -long lnum; -int bflag; -int cflag; -int fflag; -int hflag = 1; -int iflag; -int lflag; -int nflag; -int sflag; -int vflag; -int nfile; -long tln; -int nsucc; -int badbotch; - -int expfile; -int bmegrep = 0; -int scanexit = 0; - -extern char *optarg; -extern int optind, getopt(); - -usage() -{ - fprint(2, "usage: %s [ -bchilnsv ] [ -e pattern ] [ -f file ] [ pattern ] [ file ] ...\n", progname); - exit(2); -} - -main(argc, argv) -char **argv; -{ - register c; - int errflg = 0; - int (*fn)(), execute(), bmexecute(); - int etext(); - char *ffile; - char buf[2048]; - - if(progname = strrchr(argv[0], '/')) - progname++; - else - progname = argv[0]; - -#ifdef forfutureuse - switch (progname[0]) { - case 'f': fgrep++; break; - case 'e': egrep++; break; - case 'g': grep++; break; - } -#endif - - while(( c = getopt(argc, argv, "bchie:f:lnsv?")) != -1) - switch(c) { - - case 'b': - bflag++; - continue; - - case 'c': - cflag++; - continue; - - case 'e': - input = optarg; - continue; - - case 'f': - fflag++; - ffile = optarg; - continue; - - case 'h': - hflag = 0; - continue; - - case 'i': - iflag++; - continue; - - case 'l': - lflag++; - continue; - - case 'n': - nflag++; - continue; - - case 's': - sflag++; - continue; - - case 'v': - vflag++; - continue; - - case '?': - errflg++; - continue; - } - - if (errflg) - usage(); - - argc -= optind; - argv += optind; - if (fflag) { - if ((expfile = open(ffile, 0)) < 0) { - fprint(2, "%s: can't open %s\n", progname, ffile); - exit(2); - } - } else if (input == 0) { - if ((input = *argv++) == 0) - usage(); - argc--; - } - Finit(1, (char *)0); - -#ifdef MAILPREP - mailprep(); -#endif /* MAILPREP */ - - yyparse(); - -#ifdef MAILPREP - maildone(); -#endif /* MAILPREP */ - - if(!vflag && islit(buf)){ - bmprep(buf); - fn = bmexecute; - } else - fn = execute; - - cgotofn(); - nfile = argc; - if (argc<=0) { - if (lflag) exit(1); - scanexit = 1; - (*fn)((char *)0); - } - else while (--argc >= 0) { - if (reinit == 1) clearg(); - scanexit = argc == 0; - (*fn)(*argv++); - } - exit(badbotch ? 2 : nsucc==0); -} //GO.SYSIN DD main.c echo y.tab.c 1>&2 sed 's/.//' >y.tab.c <<'//GO.SYSIN DD y.tab.c' -# define CHAR 257 -# define DOT 258 -# define CCL 259 -# define NCCL 260 -# define OR 261 -# define CAT 262 -# define STAR 263 -# define PLUS 264 -# define QUEST 265 - -# line 16 "gram.y" -#include "hdr.h" -#define yyclearin yychar = -1 -#define yyerrok yyerrflag = 0 -extern int yychar; -extern short yyerrflag; -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 150 -#endif -#ifndef YYSTYPE -#define YYSTYPE int -#endif -YYSTYPE yylval, yyval; -# define YYERRCODE 256 - -# line 63 "gram.y" - -yyerror(s) { - fprint(2, "egrep: %s\n", s); - exit(2); -} - -yylex() { - extern int yylval; - int cclcnt, x; - register char c, d; - switch(c = nextch()) { - case '^': c = LEFT; - goto defchar; - case '$': c = RIGHT; - goto defchar; - case '|': return (OR); - case '*': return (STAR); - case '+': return (PLUS); - case '?': return (QUEST); - case '(': return (c); - case ')': return (c); - case '.': return (DOT); - case '\0': return (0); - case RIGHT: return (OR); - case '[': - x = CCL; - cclcnt = 0; - count = nxtchar++; - if ((c = nextch()) == '^') { - x = NCCL; - c = nextch(); - } - do { - if (c == '\0') synerror(); - if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) { - if ((d = nextch()) != 0) { - c = chars[nxtchar-1]; - while (c < d) { - if (iflag && isalpha(c)) { - if (nxtchar >= MAXLIN-1) overflo(); - chars[nxtchar++] = isupper(++c)?tolower(c):toupper(c); - chars[nxtchar++] = c; - cclcnt += 2; - } - else { - if (nxtchar >= MAXLIN) overflo(); - chars[nxtchar++] = ++c; - cclcnt++; - } - } - continue; - } - } - if (iflag&&isalpha(c)) { - if (nxtchar >= MAXLIN-1) overflo(); - chars[nxtchar++] = isupper(c)?tolower(c):toupper(c); - chars[nxtchar++] = c; - cclcnt += 2; - } - else { - if (nxtchar >= MAXLIN) overflo(); - chars[nxtchar++] = c; - cclcnt++; - } - } while ((c = nextch()) != ']'); - chars[count] = cclcnt; - return (x); - case '\\': - if ((c = nextch()) == '\0') synerror(); - else if (c == '\n') c = nextch(); - defchar: - default: yylval = c; return (CHAR); - } -} - -static int mailfd = -1; - -nextch() { - register c; - if (fflag) { - if ((c = Fgetc(expfile)) < 0) - c = 0; - } - else c = *input++; -if(mailfd >= 0) Fputc(mailfd, c? c : '\n'); - return(c); -} - -synerror() { - fprint(2, "egrep: syntax error\n"); - exit(2); -} - -enter(x) int x; { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = 0; - right[line] = 0; - return(line++); -} - -cclenter(x) int x; { - register linno; - linno = enter(x); - right[linno] = count; - return (linno); -} - -node(x, l, r) { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = l; - right[line] = r; - parent[l] = line; - parent[r] = line; - return(line++); -} - -unary(x, d) { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = d; - right[line] = 0; - parent[d] = line; - return(line++); -} -overflo() { - fprint(2, "egrep: regular expression too long\n"); - exit(2); -} -#include <errno.h> -#define NAME "/tmp/grepdata" -mailprep() -{ - umask(0); - mailfd = open(NAME, 1); - if((mailfd < 0) && (errno != ECONC)) - mailfd = creat(NAME, 03666); - if(mailfd >= 0){ - Finit(mailfd, (char *)0); - Fseek(mailfd, 0L, 2); - Fprint(mailfd, "\321egrep: "); - } -} - -maildone() -{ - if(mailfd >= 0){ - Fflush(mailfd); - close(mailfd); - } -} -short yyexca[] ={ --1, 1, - 0, -1, - -2, 0, --1, 5, - 0, 2, - -2, 0, --1, 13, - 0, 5, - -2, 0, --1, 14, - 0, 12, - 257, 12, - 258, 12, - 259, 12, - 260, 12, - 261, 12, - 40, 12, - 41, 12, - -2, 0, --1, 19, - 0, 4, - -2, 0, --1, 20, - 0, 11, - 261, 11, - 41, 11, - -2, 0, --1, 23, - 0, 3, - -2, 0, - }; -# define YYNPROD 18 -# define YYLAST 261 -short yyact[]={ - - 10, 22, 4, 14, 11, 2, 1, 5, 0, 0, - 10, 15, 16, 17, 18, 0, 19, 20, 3, 0, - 10, 0, 0, 12, 0, 20, 0, 20, 0, 0, - 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 6, 7, 8, - 9, 21, 0, 15, 16, 17, 11, 6, 7, 8, - 9, 23, 0, 15, 16, 17, 11, 6, 7, 8, - 9, 13, 0, 15, 16, 17, 11, 6, 7, 8, - 9, 0, 0, 15, 16, 17, 11, 6, 7, 8, - 9 }; -short yypact[]={ - --259,-1000,-1000, 0,-1000, -20,-1000,-1000,-1000,-1000, - 0,-1000, 0, 0,-252,-1000,-1000,-1000, -40, -30, - -10, 0,-1000, 0 }; -short yypgo[]={ - - 0, 6, 5, 18, 3 }; -short yyr1[]={ - - 0, 1, 2, 2, 2, 2, 3, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4 }; -short yyr2[]={ - - 0, 1, 2, 4, 3, 3, 0, 1, 1, 1, - 1, 3, 2, 2, 2, 2, 3, 1 }; -short yychk[]={ - --1000, -1, -2, -3, 261, -4, 257, 258, 259, 260, - 40, 256, -3, 261, -4, 263, 264, 265, -4, -4, - -4, 261, 41, 261 }; -short yydef[]={ - - 6, -2, 1, 0, 6, -2, 7, 8, 9, 10, - 0, 17, 0, -2, -2, 13, 14, 15, 0, -2, - -2, 0, 16, -2 }; -# ifdef YYDEBUG -# include "y.debug" -# endif - -# define YYFLAG -1000 -# define YYERROR goto yyerrlab -# define YYACCEPT return(0) -# define YYABORT return(1) - -/* parser for yacc output */ - -#ifdef YYDEBUG -int yydebug = 0; /* 1 for debugging */ -#endif -YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */ -int yychar = -1; /* current input token number */ -int yynerrs = 0; /* number of errors */ -short yyerrflag = 0; /* error recovery flag */ - -yyparse() -{ short yys[YYMAXDEPTH]; - int yyj, yym; - register YYSTYPE *yypvt; - register int yystate, yyn; - register short *yyps; - register YYSTYPE *yypv; - register short *yyxi; - - yystate = 0; - yychar = -1; - yynerrs = 0; - yyerrflag = 0; - yyps= &yys[-1]; - yypv= &yyv[-1]; - -yystack: /* put a state and value onto the stack */ -#ifdef YYDEBUG - if(yydebug >= 3) - if(yychar < 0 || yytoknames[yychar] == 0) - printf("char %d in %s", yychar, yystates[yystate]); - else - printf("%s in %s", yytoknames[yychar], yystates[yystate]); -#endif - if( ++yyps >= &yys[YYMAXDEPTH] ) { - yyerror( "yacc stack overflow" ); - return(1); - } - *yyps = yystate; - ++yypv; - *yypv = yyval; -yynewstate: - yyn = yypact[yystate]; - if(yyn <= YYFLAG) goto yydefault; /* simple state */ - if(yychar<0) { - yychar = yylex(); -#ifdef YYDEBUG - if(yydebug >= 2) { - if(yychar <= 0) - printf("lex EOF\n"); - else if(yytoknames[yychar]) - printf("lex %s\n", yytoknames[yychar]); - else - printf("lex (%c)\n", yychar); - } -#endif - if(yychar < 0) - yychar = 0; - } - if((yyn += yychar) < 0 || yyn >= YYLAST) - goto yydefault; - if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */ - yychar = -1; - yyval = yylval; - yystate = yyn; - if( yyerrflag > 0 ) --yyerrflag; - goto yystack; - } -yydefault: - /* default state action */ - if( (yyn=yydef[yystate]) == -2 ) { - if(yychar < 0) { - yychar = yylex(); -#ifdef YYDEBUG - if(yydebug >= 2) - if(yychar < 0) - printf("lex EOF\n"); - else - printf("lex %s\n", yytoknames[yychar]); -#endif - if(yychar < 0) - yychar = 0; - } - /* look through exception table */ - for(yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate); - yyxi += 2 ) ; /* VOID */ - while( *(yyxi+=2) >= 0 ){ - if( *yyxi == yychar ) break; - } - if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */ - } - if( yyn == 0 ){ /* error */ - /* error ... attempt to resume parsing */ - switch( yyerrflag ){ - case 0: /* brand new error */ -#ifdef YYDEBUG - yyerror("syntax error\n%s", yystates[yystate]); - if(yytoknames[yychar]) - yyerror("saw %s\n", yytoknames[yychar]); - else if(yychar >= ' ' && yychar < '\177') - yyerror("saw `%c'\n", yychar); - else if(yychar == 0) - yyerror("saw EOF\n"); - else - yyerror("saw char 0%o\n", yychar); -#else - yyerror( "syntax error" ); -#endif -yyerrlab: - ++yynerrs; - case 1: - case 2: /* incompletely recovered error ... try again */ - yyerrflag = 3; - /* find a state where "error" is a legal shift action */ - while ( yyps >= yys ) { - yyn = yypact[*yyps] + YYERRCODE; - if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){ - yystate = yyact[yyn]; /* simulate a shift of "error" */ - goto yystack; - } - yyn = yypact[*yyps]; - /* the current yyps has no shift onn "error", pop stack */ -#ifdef YYDEBUG - if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); -#endif - --yyps; - --yypv; - } - /* there is no state on the stack with an error shift ... abort */ -yyabort: - return(1); - case 3: /* no shift yet; clobber input char */ -#ifdef YYDEBUG - if( yydebug ) { - printf("error recovery discards "); - if(yytoknames[yychar]) - printf("%s\n", yytoknames[yychar]); - else if(yychar >= ' ' && yychar < '\177') - printf("`%c'\n", yychar); - else if(yychar == 0) - printf("EOF\n"); - else - printf("char 0%o\n", yychar); - } -#endif - if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ - yychar = -1; - goto yynewstate; /* try again in the same state */ - } - } - /* reduction by production yyn */ -#ifdef YYDEBUG - if(yydebug) { char *s; - printf("reduce %d in:\n\t", yyn); - for(s = yystates[yystate]; *s; s++) { - putchar(*s); - if(*s == '\n' && *(s+1)) - putchar('\t'); - } - } -#endif - yyps -= yyr2[yyn]; - yypvt = yypv; - yypv -= yyr2[yyn]; - yyval = yypv[1]; - yym=yyn; - /* consult goto table to find next state */ - yyn = yyr1[yyn]; - yyj = yypgo[yyn] + *yyps + 1; - if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; - switch(yym){ - -case 1: -# line 21 "gram.y" -{ unary(FINAL, yypvt[-0]); - line--; - } break; -case 2: -# line 26 "gram.y" -{ yyval = node(CAT, yypvt[-1], yypvt[-0]); } break; -case 3: -# line 28 "gram.y" -{ yyval = node(CAT, yypvt[-2], yypvt[-1]); } break; -case 4: -# line 30 "gram.y" -{ yyval = node(CAT, yypvt[-1], yypvt[-0]); } break; -case 5: -# line 32 "gram.y" -{ yyval = node(CAT, yypvt[-2], yypvt[-1]); } break; -case 6: -# line 35 "gram.y" -{ yyval = enter(DOT); - yyval = unary(STAR, yyval); } break; -case 7: -# line 39 "gram.y" -{ yyval = iflag?node(OR, enter(tolower(yypvt[-0])), enter(toupper(yypvt[-0]))):enter(yypvt[-0]); } break; -case 8: -# line 41 "gram.y" -{ yyval = enter(DOT); } break; -case 9: -# line 43 "gram.y" -{ yyval = cclenter(CCL); } break; -case 10: -# line 45 "gram.y" -{ yyval = cclenter(NCCL); } break; -case 11: -# line 49 "gram.y" -{ yyval = node(OR, yypvt[-2], yypvt[-0]); } break; -case 12: -# line 51 "gram.y" -{ yyval = node(CAT, yypvt[-1], yypvt[-0]); } break; -case 13: -# line 53 "gram.y" -{ yyval = unary(STAR, yypvt[-1]); } break; -case 14: -# line 55 "gram.y" -{ yyval = unary(PLUS, yypvt[-1]); } break; -case 15: -# line 57 "gram.y" -{ yyval = unary(QUEST, yypvt[-1]); } break; -case 16: -# line 59 "gram.y" -{ yyval = yypvt[-1]; } break; - } - goto yystack; /* stack new state and value */ -} //GO.SYSIN DD y.tab.c echo gram.y 1>&2 sed 's/.//' >gram.y <<'//GO.SYSIN DD gram.y' -/* - * egrep -- print lines containing (or not containing) a regular expression - * - * status returns: - * 0 - ok, and some matches - * 1 - ok, but no matches - * 2 - some error; matches irrelevant - */ -%token CHAR DOT CCL NCCL OR CAT STAR PLUS QUEST -%left OR -%left CHAR DOT CCL NCCL '(' -%left CAT -%left STAR PLUS QUEST - -%{ -#include "hdr.h" -%} - -%% -s: t - { unary(FINAL, $1); - line--; - } - ; -t: b r - { $$ = node(CAT, $1, $2); } - | OR b r OR - { $$ = node(CAT, $2, $3); } - | OR b r - { $$ = node(CAT, $2, $3); } - | b r OR - { $$ = node(CAT, $1, $2); } - ; -b: - { $$ = enter(DOT); - $$ = unary(STAR, $$); } - ; -r: CHAR - { $$ = iflag?node(OR, enter(tolower($1)), enter(toupper($1))):enter($1); } - | DOT - { $$ = enter(DOT); } - | CCL - { $$ = cclenter(CCL); } - | NCCL - { $$ = cclenter(NCCL); } - ; - -r: r OR r - { $$ = node(OR, $1, $3); } - | r r %prec CAT - { $$ = node(CAT, $1, $2); } - | r STAR - { $$ = unary(STAR, $1); } - | r PLUS - { $$ = unary(PLUS, $1); } - | r QUEST - { $$ = unary(QUEST, $1); } - | '(' r ')' - { $$ = $2; } - | error - ; - -%% -yyerror(s) { - fprint(2, "%s: %s\n", progname, s); - exit(2); -} - -yylex() { - extern int yylval; - int cclcnt, x; - register char c, d; - switch(c = nextch()) { - case '^': c = LEFT; - goto defchar; - case '$': c = RIGHT; - goto defchar; - case '|': return (OR); - case '*': return (STAR); - case '+': return (PLUS); - case '?': return (QUEST); - case '(': return (c); - case ')': return (c); - case '.': return (DOT); - case '\0': return (0); - case RIGHT: return (OR); - case '[': - x = CCL; - cclcnt = 0; - count = nxtchar++; - if ((c = nextch()) == '^') { - x = NCCL; - c = nextch(); - } - do { - if (c == '\0') synerror(); - if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) { - if ((d = nextch()) != 0) { - c = chars[nxtchar-1]; - while (c < d) { - if (iflag && isalpha(c)) { - if (nxtchar >= MAXLIN-1) overflo(); - chars[nxtchar++] = isupper(++c)?tolower(c):toupper(c); - chars[nxtchar++] = c; - cclcnt += 2; - } - else { - if (nxtchar >= MAXLIN) overflo(); - chars[nxtchar++] = ++c; - cclcnt++; - } - } - continue; - } - } - if (iflag&&isalpha(c)) { - if (nxtchar >= MAXLIN-1) overflo(); - chars[nxtchar++] = isupper(c)?tolower(c):toupper(c); - chars[nxtchar++] = c; - cclcnt += 2; - } - else { - if (nxtchar >= MAXLIN) overflo(); - chars[nxtchar++] = c; - cclcnt++; - } - } while ((c = nextch()) != ']'); - chars[count] = cclcnt; - return (x); - case '\\': - if ((c = nextch()) == '\0') synerror(); - else if (c == '\n') c = nextch(); - defchar: - default: yylval = c; return (CHAR); - } -} - -#ifdef MAILPREP -static int mailfd = -1; -#endif /* MAILPREP */ - -nextch() { - register c; - if (fflag) { - if ((c = Fgetc(expfile)) < 0) - c = 0; - } - else c = *input++; -#ifdef MAILPREP -if(mailfd >= 0) Fputc(mailfd, c? c : '\n'); -#endif /* MAILPREP */ - return(c); -} - -synerror() { - fprint(2, "%s: syntax error\n", progname); - exit(2); -} - -enter(x) int x; { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = 0; - right[line] = 0; - return(line++); -} - -cclenter(x) int x; { - register linno; - linno = enter(x); - right[linno] = count; - return (linno); -} - -node(x, l, r) { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = l; - right[line] = r; - parent[l] = line; - parent[r] = line; - return(line++); -} - -unary(x, d) { - if(line >= MAXLIN) overflo(); - name[line] = x; - left[line] = d; - right[line] = 0; - parent[d] = line; - return(line++); -} -overflo() { - fprint(2, "%s: regular expression too long\n", progname); - exit(2); -} - -#ifdef MAILPREP -#include <errno.h> -#define NAME "/tmp/grepdata" -mailprep() -{ - umask(0); - mailfd = open(NAME, 1); - if((mailfd < 0) && (errno != ECONC)) - mailfd = creat(NAME, 03666); - if(mailfd >= 0){ - Finit(mailfd, (char *)0); - Fseek(mailfd, 0L, 2); - Fprint(mailfd, "\321egrep: "); - } -} - -maildone() -{ - if(mailfd >= 0){ - Fflush(mailfd); - close(mailfd); - } -} -#endif /* MAILPREP */ //GO.SYSIN DD gram.y