static grammar * maketables(nfagrammar *gr) { int i; nfa *nf; dfa *d; grammar *g; if (gr->gr_nnfas == 0) return NULL; g = newgrammar(gr->gr_nfa[0]->nf_type); /* XXX first rule must be start rule */ g->g_ll = gr->gr_ll; for (i = 0; i < gr->gr_nnfas; i++) { nf = gr->gr_nfa[i]; if (Py_DebugFlag) { printf("Dump of NFA for '%s' ...\n", nf->nf_name); dumpnfa(&gr->gr_ll, nf); printf("Making DFA for '%s' ...\n", nf->nf_name); } d = adddfa(g, nf->nf_type, nf->nf_name); makedfa(gr, gr->gr_nfa[i], d); } return g; }
refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */ { uchar *fr; int i, tempstat; fa *pfa; fr = fields; *fr = '\0'; if (*rec == '\0') return 0; pfa = makedfa(fs, 1); dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) ); tempstat = pfa->initstat; for (i = 1; i < nfields; i++) { if (!(fldtab[i].tval & DONTFREE)) xfree(fldtab[i].sval); fldtab[i].tval = FLD | STR | DONTFREE; fldtab[i].sval = fr; dprintf( ("refldbld: i=%d\n", i) ); if (nematch(pfa, rec)) { pfa->initstat = 2; /* horrible coupling */ dprintf( ("match %s (%d chars)\n", patbeg, patlen) ); strncpy(fr, rec, patbeg-rec); fr += patbeg - rec + 1; *(fr-1) = '\0'; rec = patbeg + patlen; } else { dprintf( ("no match %s\n", rec) ); strcpy(fr, rec); pfa->initstat = tempstat; break; } } return i; }
Cell *sub(Node **a, int nnn) /* substitute command */ { char *sptr, *pb, *q; Cell *x, *y, *result; char *t, *buf; fa *pfa; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in sub"); x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ result = False; if (pmatch(pfa, t)) { sptr = t; adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); pb = buf; while (sptr < patbeg) *pb++ = *sptr++; sptr = getsval(y); while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } *pb = '\0'; if (pb > buf + bufsz) FATAL("sub result1 %.30s too big; can't happen", buf); sptr = patbeg + patlen; if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); while ((*pb++ = *sptr++) != 0) ; } if (pb > buf + bufsz) FATAL("sub result2 %.30s too big; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy */ result = True;; } tempfree(x); tempfree(y); free(buf); return result; }
Cell *sub(Node **a, int nnn) /* substitute command */ { register uchar *sptr, *pb, *q; register Cell *x, *y, *result; uchar buf[SUBSIZE], *t; fa *pfa; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ result = false; if (pmatch(pfa, t)) { pb = buf; sptr = t; while (sptr < patbeg) *pb++ = *sptr++; sptr = getsval(y); while (*sptr != 0 && pb < buf + SUBSIZE - 1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; /* skip \, */ *pb++ = *sptr++; /* add & */ } else if (*sptr == '&') { sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; *pb = '\0'; if (pb >= buf + SUBSIZE) ERROR "sub() result %30s too big", buf FATAL; sptr = patbeg + patlen; if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) while (*pb++ = *sptr++) ; if (pb >= buf + SUBSIZE) ERROR "sub() result %.30s too big", buf FATAL; setsval(x, buf); result = true;; } tempfree(x); tempfree(y); return result; }
int refldbld(const char *rec, const char *fs) /* build fields from reg expr in FS */ { /* this relies on having fields[] the same length as $0 */ /* the fields are all stored in this one array with \0's */ char *fr; int i, tempstat, n; fa *pfa; n = strlen(rec); if (n > fieldssize) { xfree(fields); if ((fields = (char *) malloc(n+1)) == NULL) FATAL("out of space for fields in refldbld %d", n); fieldssize = n; } fr = fields; *fr = '\0'; if (*rec == '\0') return 0; pfa = makedfa(fs, 1); dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) ); tempstat = pfa->initstat; for (i = 1; ; i++) { if (i > nfields) growfldtab(i); if (freeable(fldtab[i])) xfree(fldtab[i]->sval); fldtab[i]->tval = FLD | STR | DONTFREE; fldtab[i]->sval = fr; dprintf( ("refldbld: i=%d\n", i) ); if (nematch(pfa, rec)) { pfa->initstat = 2; /* horrible coupling to b.c */ dprintf( ("match %s (%d chars)\n", patbeg, patlen) ); strncpy(fr, rec, patbeg-rec); fr += patbeg - rec + 1; *(fr-1) = '\0'; rec = patbeg + patlen; } else { dprintf( ("no match %s\n", rec) ); strcpy(fr, rec); pfa->initstat = tempstat; break; } } return i; }
static int refldbld(unsigned char *rec, unsigned char *fs) /* build fields from reg expr in FS */ { unsigned char *fr; int i; fa *pfa; fr = fields; *fr = '\0'; if (*rec == '\0') return 0; pfa = makedfa(fs, 1); dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) ); pfa->notbol = 0; for (i = 1; ; i++) { if (i >= MAXFLD) morefields(); if (!(fldtab[i]->tval & DONTFREE)) xfree(fldtab[i]->sval); fldtab[i]->tval = FLD | STR | DONTFREE; fldtab[i]->sval = fr; dprintf( ("refldbld: i=%d\n", i) ); if (nematch(pfa, rec)) { pfa->notbol = REG_NOTBOL; dprintf( ("match %s (%d chars\n", patbeg, patlen) ); strncpy((char*) fr, (char*) rec, patbeg-rec); fr += patbeg - rec + 1; *(fr-1) = '\0'; rec = patbeg + patlen; } else { dprintf( ("no match %s\n", rec) ); strcpy((char*) fr, (char*) rec); pfa->notbol = 0; break; } } return i; }
Cell *matchop(Node **a, int n) /* ~ and match() */ { Cell *x, *y; char *s, *t; int i; fa *pfa; int (*mf)(fa *, char *) = match, mode = 0; if (n == MATCHFCN) { mf = pmatch; mode = 1; } x = execute(a[1]); /* a[1] = target text */ s = getsval(x); if (a[0] == 0) /* a[1] == 0: already-compiled reg expr */ i = (*mf)((fa *) a[2], s); else { y = execute(a[2]); /* a[2] = regular expr */ t = getsval(y); pfa = makedfa(t, mode); i = (*mf)(pfa, s); tempfree(y); } tempfree(x); if (n == MATCHFCN) { int start = patbeg - s + 1; if (patlen < 0) start = 0; setfval(rstartloc, (Awkfloat) start); setfval(rlengthloc, (Awkfloat) patlen); x = gettemp(); x->tval = NUM; x->fval = start; return x; } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) return(true); else return(false); }
int readrec(uschar **pbuf, int *pbufsize, FILE *inf, int newflag) /* read one record into buf */ { int sep, c, isrec, found, tempstat; uschar *rr, *buf = *pbuf; int bufsize = *pbufsize; size_t len; if ((len = strlen(*FS)) < len_inputFS) { strcpy(inputFS, *FS); /* for subsequent field splitting */ } else { len_inputFS = len + 1; inputFS = realloc(inputFS, len_inputFS); if (inputFS == NULL) FATAL("field separator %.10s... is too long", *FS); memcpy(inputFS, *FS, len_inputFS); } /*fflush(stdout); avoids some buffering problem but makes it 25% slower*/ if (**RS && (*RS)[1]) { fa *pfa = makedfa(*RS, 1); if (newflag) found = fnematch(pfa, inf, &buf, &bufsize, recsize); else { tempstat = pfa->initstat; pfa->initstat = 2; found = fnematch(pfa, inf, &buf, &bufsize, recsize); pfa->initstat = tempstat; } if (found) *patbeg = 0; } else { if ((sep = **RS) == 0) { sep = '\n'; while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */ ; if (c != EOF) ungetc(c, inf); } for (rr = buf; ; ) { for (; (c=getc(inf)) != sep && c != EOF; ) { if (rr-buf+1 > bufsize) if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 1")) FATAL("input record `%.30s...'" " too long", buf); *rr++ = c; } if (**RS == sep || c == EOF) break; if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */ break; if (!adjbuf(&buf, &bufsize, 2+rr-buf, recsize, &rr, "readrec 2")) FATAL("input record `%.30s...' too long", buf); *rr++ = '\n'; *rr++ = c; } if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 3")) FATAL("input record `%.30s...' too long", buf); *rr = 0; } *pbuf = buf; *pbufsize = bufsize; isrec = *buf || !feof(inf); dprintf( ("readrec saw <%s>, returns %d\n", buf, isrec) ); return isrec; }
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ { Cell *x = 0, *y, *ap; char *s; int sep; char *t, temp, num[10], *fs = 0; int n, tempstat; y = execute(a[0]); /* source string */ s = getsval(y); if (a[2] == 0) /* fs string */ fs = *FS; else if ((int) a[3] == STRING) { /* split(str,arr,"string") */ x = execute(a[2]); fs = getsval(x); } else if ((int) a[3] == REGEXPR) fs = (char*) "(regexpr)"; /* split(str,arr,/regexpr/) */ else ERROR "illegal type of split()" FATAL; sep = *fs; ap = execute(a[1]); /* array name */ freesymtab(ap); dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) ); ap->tval &= ~STR; ap->tval |= ARR; ap->sval = (char *) makesymtab(NSYMTAB); n = 0; if ((*s != '\0' && strlen(fs) > 1) || (int) a[3] == REGEXPR) { /* reg expr */ fa *pfa; if ((int) a[3] == REGEXPR) { /* it's ready already */ pfa = (fa *) a[2]; } else { pfa = makedfa(fs, 1); } if (nematch(pfa,s)) { tempstat = pfa->initstat; pfa->initstat = 2; do { n++; sprintf((char *)num, "%d", n); temp = *patbeg; *patbeg = '\0'; if (isnumber(s)) setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); *patbeg = temp; s = patbeg + patlen; if (*(patbeg+patlen-1) == 0 || *s == 0) { n++; sprintf((char *)num, "%d", n); setsymtab(num, "", 0.0, STR, (Array *) ap->sval); pfa->initstat = tempstat; goto spdone; } } while (nematch(pfa,s)); } n++; sprintf((char *)num, "%d", n); if (isnumber(s)) setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); spdone: pfa = NULL; } else if (sep == ' ') { for (n = 0; ; ) { while (*s == ' ' || *s == '\t' || *s == '\n') s++; if (*s == 0) break; n++; t = s; do s++; while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); temp = *s; *s = '\0'; sprintf((char *)num, "%d", n); if (isnumber(t)) setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s != 0) s++; } } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ for (n = 0; *s != 0; s++) { char buf[2]; n++; sprintf((char *)num, "%d", n); buf[0] = *s; buf[1] = 0; if (isdigit(buf[0])) setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); else setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); } } else if (*s != 0) { for (;;) { n++; t = s; while (*s != sep && *s != '\n' && *s != '\0') s++; temp = *s; *s = '\0'; sprintf((char *)num, "%d", n); if (isnumber(t)) setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s++ == 0) break; } } tempfree(ap); tempfree(y); if (a[2] != 0 && (int) a[3] == STRING) tempfree(x); x = gettemp(); x->tval = NUM; x->fval = n; return(x); }
Cell *gsub(Node **a, int nnn) /* global substitute */ { Cell *x, *y; char *rptr, *sptr, *t, *pb, *q; char *buf; fa *pfa; int mflag, tempstat, num; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in gsub"); mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; pb = buf; rptr = getsval(y); do { if (patlen == 0 && *patbeg != 0) { /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } } if (*t == 0) /* at end */ goto done; adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); *pb++ = *t++; if (pb > buf + bufsz) /* BUG: not sure of this test */ FATAL("gsub result0 %.30s too big; can't happen", buf); mflag = 0; } else { /* matched nonempty string */ num++; sptr = t; adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); while (sptr < patbeg) *pb++ = *sptr++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } t = patbeg + patlen; if (patlen == 0 || *t == 0 || *(t-1) == 0) goto done; if (pb > buf + bufsz) FATAL("gsub result1 %.30s too big; can't happen", buf); mflag = 1; } } while (pmatch(pfa,t)); sptr = t; adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); while ((*pb++ = *sptr++) != 0) ; done: if (pb < buf + bufsz) *pb = '\0'; else if (*(pb-1) != '\0') FATAL("gsub result2 %.30s truncated; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy + free */ pfa->initstat = tempstat; } tempfree(x); tempfree(y); x = gettemp(); x->tval = NUM; x->fval = num; free(buf); return(x); }
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ { Cell *x = 0, *y, *ap; char *s, *origs; int sep; char *t, temp, num[50], *fs = 0; int n, tempstat, arg3type; y = execute(a[0]); /* source string */ origs = s = strdup(getsval(y)); arg3type = ptoi(a[3]); if (a[2] == 0) /* fs string */ fs = *FS; else if (arg3type == STRING) { /* split(str,arr,"string") */ x = execute(a[2]); fs = getsval(x); } else if (arg3type == REGEXPR) fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ else FATAL("illegal type of split"); sep = *fs; ap = execute(a[1]); /* array name */ freesymtab(ap); dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); ap->tval &= ~STR; ap->tval |= ARR; ap->sval = (char *) makesymtab(NSYMTAB); n = 0; if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) { /* split(s, a, //); have to arrange that it looks like empty sep */ arg3type = 0; fs = ""; sep = 0; } if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */ fa *pfa; if (arg3type == REGEXPR) { /* it's ready already */ pfa = (fa *) a[2]; } else { pfa = makedfa(fs, 1); } if (nematch(pfa,s)) { tempstat = pfa->initstat; pfa->initstat = 2; do { n++; sprintf(num, "%d", n); temp = *patbeg; *patbeg = '\0'; if (is_number(s)) setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); *patbeg = temp; s = patbeg + patlen; if (*(patbeg+patlen-1) == 0 || *s == 0) { n++; sprintf(num, "%d", n); setsymtab(num, "", 0.0, STR, (Array *) ap->sval); pfa->initstat = tempstat; goto spdone; } } while (nematch(pfa,s)); pfa->initstat = tempstat; /* bwk: has to be here to reset */ /* cf gsub and refldbld */ } n++; sprintf(num, "%d", n); if (is_number(s)) setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); spdone: pfa = NULL; } else if (sep == ' ') { for (n = 0; ; ) { while (*s == ' ' || *s == '\t' || *s == '\n') s++; if (*s == 0) break; n++; t = s; do s++; while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); temp = *s; *s = '\0'; sprintf(num, "%d", n); if (is_number(t)) setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s != 0) s++; } } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ for (n = 0; *s != 0; s++) { char buf[2]; n++; sprintf(num, "%d", n); buf[0] = *s; buf[1] = 0; if (isdigit((uschar)buf[0])) setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); else setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); } } else if (*s != 0) { for (;;) { n++; t = s; while (*s != sep && *s != '\n' && *s != '\0') s++; temp = *s; *s = '\0'; sprintf(num, "%d", n); if (is_number(t)) setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s++ == 0) break; } } tempfree(ap); tempfree(y); free(origs); if (a[2] != 0 && arg3type == STRING) { tempfree(x); } x = gettemp(); x->tval = NUM; x->fval = n; return(x); }
Cell *gsub(Node **a, int nnn) /* global substitute */ { register Cell *x, *y; register uchar *rptr, *sptr, *t, *pb; uchar buf[SUBSIZE]; register fa *pfa; int mflag, tempstat, num; mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; pb = buf; rptr = getsval(y); do { /* uchar *p; int i; printf("target string: %s, *patbeg = %o, patlen = %d\n", t, *patbeg, patlen); printf(" match found: "); p=patbeg; for (i=0; i<patlen; i++) printf("%c", *p++); printf("\n"); */ if (patlen == 0 && *patbeg != 0) { /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; while (*sptr != 0 && pb < buf + SUBSIZE-1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; *pb++ = *sptr++; } else if (*sptr == '&') { uchar *q; sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } if (*t == 0) /* at end */ goto done; *pb++ = *t++; if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; mflag = 0; } else { /* matched nonempty string */ num++; sptr = t; while (sptr < patbeg && pb < buf + SUBSIZE-1) *pb++ = *sptr++; sptr = rptr; while (*sptr != 0 && pb < buf + SUBSIZE-1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; *pb++ = *sptr++; } else if (*sptr == '&') { uchar *q; sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; t = patbeg + patlen; if ((*(t-1) == 0) || (*t == 0)) goto done; if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; mflag = 1; } } while (pmatch(pfa,t)); sptr = t; while (*pb++ = *sptr++) ; done: if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; *pb = '\0'; setsval(x, buf); pfa->initstat = tempstat; } tempfree(x); tempfree(y); x = gettemp(); x->tval = NUM; x->fval = num; return(x); }
yyparse() { short yys[YYMAXDEPTH]; short yyj, yym; register YYSTYPE *yypvt; register short yystate, *yyps, yyn; 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 ) printf( "state %d, char 0%o\n", yystate, yychar ); #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 ) if( (yychar=yylex())<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 ) if( (yychar=yylex())<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 */ yyerror( "syntax error" ); 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 char %d\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 ) printf("reduce %d\n",yyn); #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 44 "awk.g.y" { if (errorflag==0) winner = (node *)stat3(PROGRAM, yypvt[-2], yypvt[-1], yypvt[-0]); } break; case 2: # line 45 "awk.g.y" { yyclearin; yyerror("bailing out"); } break; case 3: # line 49 "awk.g.y" { PUTS("XBEGIN list"); yyval = yypvt[-1]; } break; case 5: # line 51 "awk.g.y" { PUTS("empty XBEGIN"); yyval = (hack)nullstat; } break; case 6: # line 55 "awk.g.y" { PUTS("XEND list"); yyval = yypvt[-1]; } break; case 8: # line 57 "awk.g.y" { PUTS("empty END"); yyval = (hack)nullstat; } break; case 9: # line 61 "awk.g.y" { PUTS("cond||cond"); yyval = op2(BOR, yypvt[-2], yypvt[-0]); } break; case 10: # line 62 "awk.g.y" { PUTS("cond&&cond"); yyval = op2(AND, yypvt[-2], yypvt[-0]); } break; case 11: # line 63 "awk.g.y" { PUTS("!cond"); yyval = op1(NOT, yypvt[-0]); } break; case 12: # line 64 "awk.g.y" { yyval = yypvt[-1]; } break; case 13: # line 68 "awk.g.y" { PUTS("pat||pat"); yyval = op2(BOR, yypvt[-2], yypvt[-0]); } break; case 14: # line 69 "awk.g.y" { PUTS("pat&&pat"); yyval = op2(AND, yypvt[-2], yypvt[-0]); } break; case 15: # line 70 "awk.g.y" { PUTS("!pat"); yyval = op1(NOT, yypvt[-0]); } break; case 16: # line 71 "awk.g.y" { yyval = yypvt[-1]; } break; case 17: # line 75 "awk.g.y" { PUTS("expr"); yyval = op2(NE, yypvt[-0], valtonode(lookup("$zero&null", symtab, 0), CCON)); } break; case 18: # line 76 "awk.g.y" { PUTS("relexpr"); } break; case 19: # line 77 "awk.g.y" { PUTS("lexexpr"); } break; case 20: # line 78 "awk.g.y" { PUTS("compcond"); } break; case 21: # line 82 "awk.g.y" { PUTS("else"); } break; case 22: # line 86 "awk.g.y" { PUTS("field"); yyval = valtonode(yypvt[-0], CFLD); } break; case 23: # line 87 "awk.g.y" { PUTS("ind field"); yyval = op1(INDIRECT, yypvt[-0]); } break; case 24: # line 91 "awk.g.y" { PUTS("if(cond)"); yyval = yypvt[-2]; } break; case 25: # line 95 "awk.g.y" { PUTS("expr~re"); yyval = op2(yypvt[-1], yypvt[-2], makedfa(yypvt[-0])); } break; case 26: # line 96 "awk.g.y" { PUTS("(lex_expr)"); yyval = yypvt[-1]; } break; case 27: # line 100 "awk.g.y" { PUTS("number"); yyval = valtonode(yypvt[-0], CCON); } break; case 28: # line 101 "awk.g.y" { PUTS("string"); yyval = valtonode(yypvt[-0], CCON); } break; case 29: # line 102 "awk.g.y" { PUTS("var"); yyval = valtonode(yypvt[-0], CVAR); } break; case 30: # line 103 "awk.g.y" { PUTS("array[]"); yyval = op2(ARRAY, yypvt[-3], yypvt[-1]); } break; case 33: # line 108 "awk.g.y" { PUTS("getline"); yyval = op1(GETLINE, 0); } break; case 34: # line 109 "awk.g.y" { PUTS("func"); yyval = op2(FNCN, yypvt[-0], valtonode(lookup("$record", symtab, 0), CFLD)); } break; case 35: # line 112 "awk.g.y" { PUTS("func()"); yyval = op2(FNCN, yypvt[-2], valtonode(lookup("$record", symtab, 0), CFLD)); } break; case 36: # line 115 "awk.g.y" { PUTS("func(expr)"); yyval = op2(FNCN, yypvt[-3], yypvt[-1]); } break; case 37: # line 116 "awk.g.y" { PUTS("sprintf"); yyval = op1(yypvt[-1], yypvt[-0]); } break; case 38: # line 118 "awk.g.y" { PUTS("substr(e,e,e)"); yyval = op3(SUBSTR, yypvt[-5], yypvt[-3], yypvt[-1]); } break; case 39: # line 120 "awk.g.y" { PUTS("substr(e,e,e)"); yyval = op3(SUBSTR, yypvt[-3], yypvt[-1], nullstat); } break; case 40: # line 122 "awk.g.y" { PUTS("split(e,e,e)"); yyval = op3(SPLIT, yypvt[-5], yypvt[-3], yypvt[-1]); } break; case 41: # line 124 "awk.g.y" { PUTS("split(e,e,e)"); yyval = op3(SPLIT, yypvt[-3], yypvt[-1], nullstat); } break; case 42: # line 126 "awk.g.y" { PUTS("index(e,e)"); yyval = op2(INDEX, yypvt[-3], yypvt[-1]); } break; case 43: # line 127 "awk.g.y" { PUTS("(expr)"); yyval = yypvt[-1]; } break; case 44: # line 128 "awk.g.y" { PUTS("t+t"); yyval = op2(ADD, yypvt[-2], yypvt[-0]); } break; case 45: # line 129 "awk.g.y" { PUTS("t-t"); yyval = op2(MINUS, yypvt[-2], yypvt[-0]); } break; case 46: # line 130 "awk.g.y" { PUTS("t*t"); yyval = op2(MULT, yypvt[-2], yypvt[-0]); } break; case 47: # line 131 "awk.g.y" { PUTS("t/t"); yyval = op2(DIVIDE, yypvt[-2], yypvt[-0]); } break; case 48: # line 132 "awk.g.y" { PUTS("t%t"); yyval = op2(MOD, yypvt[-2], yypvt[-0]); } break; case 49: # line 133 "awk.g.y" { PUTS("-term"); yyval = op1(UMINUS, yypvt[-0]); } break; case 50: # line 134 "awk.g.y" { PUTS("+term"); yyval = yypvt[-0]; } break; case 51: # line 135 "awk.g.y" { PUTS("++var"); yyval = op1(PREINCR, yypvt[-0]); } break; case 52: # line 136 "awk.g.y" { PUTS("--var"); yyval = op1(PREDECR, yypvt[-0]); } break; case 53: # line 137 "awk.g.y" { PUTS("var++"); yyval= op1(POSTINCR, yypvt[-1]); } break; case 54: # line 138 "awk.g.y" { PUTS("var--"); yyval= op1(POSTDECR, yypvt[-1]); } break; case 55: # line 142 "awk.g.y" { PUTS("term"); } break; case 56: # line 143 "awk.g.y" { PUTS("expr term"); yyval = op2(CAT, yypvt[-1], yypvt[-0]); } break; case 57: # line 144 "awk.g.y" { PUTS("var=expr"); yyval = stat2(yypvt[-1], yypvt[-2], yypvt[-0]); } break; case 60: # line 153 "awk.g.y" { PUTS("pattern"); yyval = stat2(PASTAT, yypvt[-0], genprint()); } break; case 61: # line 154 "awk.g.y" { PUTS("pattern {...}"); yyval = stat2(PASTAT, yypvt[-3], yypvt[-1]); } break; case 62: # line 155 "awk.g.y" { PUTS("srch,srch"); yyval = pa2stat(yypvt[-2], yypvt[-0], genprint()); } break; case 63: # line 157 "awk.g.y" { PUTS("srch, srch {...}"); yyval = pa2stat(yypvt[-5], yypvt[-3], yypvt[-1]); } break; case 64: # line 158 "awk.g.y" { PUTS("null pattern {...}"); yyval = stat2(PASTAT, nullstat, yypvt[-1]); } break; case 65: # line 162 "awk.g.y" { PUTS("pa_stats pa_stat"); yyval = linkum(yypvt[-2], yypvt[-1]); } break; case 66: # line 163 "awk.g.y" { PUTS("null pa_stat"); yyval = (hack)nullstat; } break; case 67: # line 164 "awk.g.y" { PUTS("pa_stats pa_stat"); yyval = linkum(yypvt[-1], yypvt[-0]); } break; case 68: # line 168 "awk.g.y" { PUTS("regex"); yyval = op2(MATCH, valtonode(lookup("$record", symtab, 0), CFLD), makedfa(yypvt[-0])); } break; case 69: # line 171 "awk.g.y" { PUTS("relexpr"); } break; case 70: # line 172 "awk.g.y" { PUTS("lexexpr"); } break; case 71: # line 173 "awk.g.y" { PUTS("comp pat"); } break; case 72: # line 177 "awk.g.y" { PUTS("expr"); } break; case 73: # line 178 "awk.g.y" { PUTS("pe_list"); } break; case 74: # line 179 "awk.g.y" { PUTS("null print_list"); yyval = valtonode(lookup("$record", symtab, 0), CFLD); } break; case 75: # line 183 "awk.g.y" { yyval = linkum(yypvt[-2], yypvt[-0]); } break; case 76: # line 184 "awk.g.y" { yyval = linkum(yypvt[-2], yypvt[-0]); } break; case 77: # line 185 "awk.g.y" { yyval = yypvt[-1]; } break; case 80: # line 194 "awk.g.y" { startreg(); } break; case 81: # line 196 "awk.g.y" { PUTS("/r/"); yyval = yypvt[-1]; } break; case 82: # line 200 "awk.g.y" { PUTS("regex CHAR"); yyval = op2(CHAR, (node *) 0, yypvt[-0]); } break; case 83: # line 201 "awk.g.y" { PUTS("regex DOT"); yyval = op2(DOT, (node *) 0, (node *) 0); } break; case 84: # line 202 "awk.g.y" { PUTS("regex CCL"); yyval = op2(CCL, (node *) 0, cclenter(yypvt[-0])); } break; case 85: # line 203 "awk.g.y" { PUTS("regex NCCL"); yyval = op2(NCCL, (node *) 0, cclenter(yypvt[-0])); } break; case 86: # line 204 "awk.g.y" { PUTS("regex ^"); yyval = op2(CHAR, (node *) 0, HAT); } break; case 87: # line 205 "awk.g.y" { PUTS("regex $"); yyval = op2(CHAR, (node *) 0 ,(node *) 0); } break; case 88: # line 206 "awk.g.y" { PUTS("regex OR"); yyval = op2(OR, yypvt[-2], yypvt[-0]); } break; case 89: # line 208 "awk.g.y" { PUTS("regex CAT"); yyval = op2(CAT, yypvt[-1], yypvt[-0]); } break; case 90: # line 209 "awk.g.y" { PUTS("regex STAR"); yyval = op2(STAR, yypvt[-1], (node *) 0); } break; case 91: # line 210 "awk.g.y" { PUTS("regex PLUS"); yyval = op2(PLUS, yypvt[-1], (node *) 0); } break; case 92: # line 211 "awk.g.y" { PUTS("regex QUEST"); yyval = op2(QUEST, yypvt[-1], (node *) 0); } break; case 93: # line 212 "awk.g.y" { PUTS("(regex)"); yyval = yypvt[-1]; } break; case 94: # line 217 "awk.g.y" { PUTS("expr relop expr"); yyval = op2(yypvt[-1], yypvt[-2], yypvt[-0]); } break; case 95: # line 219 "awk.g.y" { PUTS("(relexpr)"); yyval = yypvt[-1]; } break; case 98: # line 229 "awk.g.y" { PUTS("print>stat"); yyval = stat3(yypvt[-3], yypvt[-2], yypvt[-1], yypvt[-0]); } break; case 99: # line 231 "awk.g.y" { PUTS("print list"); yyval = stat3(yypvt[-1], yypvt[-0], nullstat, nullstat); } break; case 100: # line 233 "awk.g.y" { PUTS("printf>stat"); yyval = stat3(yypvt[-3], yypvt[-2], yypvt[-1], yypvt[-0]); } break; case 101: # line 235 "awk.g.y" { PUTS("printf list"); yyval = stat3(yypvt[-1], yypvt[-0], nullstat, nullstat); } break; case 102: # line 236 "awk.g.y" { PUTS("expr"); yyval = exptostat(yypvt[-0]); } break; case 103: # line 237 "awk.g.y" { PUTS("null simple statement"); yyval = (hack)nullstat; } break; case 104: # line 238 "awk.g.y" { yyclearin; yyerror("illegal statement"); } break; case 105: # line 242 "awk.g.y" { PUTS("simple stat"); } break; case 106: # line 243 "awk.g.y" { PUTS("if stat"); yyval = stat3(IF, yypvt[-1], yypvt[-0], nullstat); } break; case 107: # line 245 "awk.g.y" { PUTS("if-else stat"); yyval = stat3(IF, yypvt[-3], yypvt[-2], yypvt[-0]); } break; case 108: # line 246 "awk.g.y" { PUTS("while stat"); yyval = stat2(WHILE, yypvt[-1], yypvt[-0]); } break; case 109: # line 247 "awk.g.y" { PUTS("for stat"); } break; case 110: # line 248 "awk.g.y" { PUTS("next"); yyval = stat1(NEXT, 0); } break; case 111: # line 249 "awk.g.y" { PUTS("exit"); yyval = stat1(EXIT, 0); } break; case 112: # line 250 "awk.g.y" { PUTS("exit"); yyval = stat1(EXIT, yypvt[-1]); } break; case 113: # line 251 "awk.g.y" { PUTS("break"); yyval = stat1(BREAK, 0); } break; case 114: # line 252 "awk.g.y" { PUTS("continue"); yyval = stat1(CONTINUE, 0); } break; case 115: # line 253 "awk.g.y" { PUTS("{statlist}"); yyval = yypvt[-1]; } break; case 116: # line 257 "awk.g.y" { PUTS("stat_list stat"); yyval = linkum(yypvt[-1], yypvt[-0]); } break; case 117: # line 258 "awk.g.y" { PUTS("null stat list"); yyval = (hack)nullstat; } break; case 118: # line 262 "awk.g.y" { PUTS("while(cond)"); yyval = yypvt[-2]; } break; case 119: # line 267 "awk.g.y" { PUTS("for(e;e;e)"); yyval = stat4(FOR, yypvt[-7], yypvt[-5], yypvt[-3], yypvt[-0]); } break; case 120: # line 269 "awk.g.y" { PUTS("for(e;e;e)"); yyval = stat4(FOR, yypvt[-6], nullstat, yypvt[-3], yypvt[-0]); } break; case 121: # line 271 "awk.g.y" { PUTS("for(v in v)"); yyval = stat3(IN, yypvt[-5], yypvt[-3], yypvt[-0]); } break; } goto yystack; /* stack new state and value */ }