fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */ /* anchor = 1 for anchored matches, else 0 */ { Node *p, *p1; fa *f; p = reparse(s); p1 = op2(CAT, op2(STAR, op2(ALL, NIL, NIL), NIL), p); /* put ALL STAR in front of reg. exp. */ p1 = op2(CAT, p1, op2(FINAL, NIL, NIL)); /* put FINAL after reg. exp. */ poscnt = 0; penter(p1); /* enter parent pointers and leaf indices */ if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL) overflo("out of space for fa"); f->accept = poscnt-1; /* penter has computed number of positions in re */ cfoll(f, p1); /* set up follow sets */ freetr(p1); if ((f->posns[0] = (int *) calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL) overflo("out of space in makedfa"); if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL) overflo("out of space in makedfa"); *f->posns[1] = 0; f->initstat = makeinit(f, anchor); f->anchor = anchor; f->restr = (uschar *) tostring(s); return f; }
void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */ { int i; int *p; switch (type(v)) { ELEAF LEAF f->re[info(v)].ltype = type(v); f->re[info(v)].lval.np = right(v); while (f->accept >= maxsetvec) { /* guessing here! */ setvec = reallocarray(setvec, maxsetvec, 4 * sizeof(int)); tmpset = reallocarray(tmpset, maxsetvec, 4 * sizeof(int)); if (setvec == 0 || tmpset == 0) overflo("out of space in cfoll()"); maxsetvec *= 4; } for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; follow(v); /* computes setvec and setcnt */ if ((p = (int *) calloc(setcnt+1, sizeof(int))) == NULL) overflo("out of space building follow set"); f->re[info(v)].lfollow = p; *p = setcnt; for (i = f->accept; i >= 0; i--) if (setvec[i] == 1) *++p = i; break; UNARY cfoll(f,left(v)); break; case CAT: case OR: cfoll(f,left(v)); cfoll(f,right(v)); break; default: /* can't happen */ FATAL("can't happen: unknown type %d in cfoll", type(v)); } }
void main(int argc, char **argv) { int i; ARGBEGIN { # ifdef DEBUG case 'd': debug++; break; case 'y': yydebug = TRUE; break; # endif case 't': case 'T': Binit(&fout, 1, OWRITE); errorf= 2; foutopen = 1; break; case 'v': case 'V': report = 1; break; case 'n': case 'N': report = 0; break; case '9': nine = 1; break; default: warning("Unknown option %c", ARGC()); } ARGEND sargc = argc; sargv = argv; if (argc > 0){ yyfile = argv[fptr++]; fin = Bopen(yyfile, OREAD); if(fin == 0) error ("%s - can't open file: %r", yyfile); sargc--; sargv++; } else { yyfile = "/fd/0"; fin = myalloc(sizeof(Biobuf), 1); if(fin == 0) exits("core"); Binit(fin, 0, OREAD); } if(Bgetc(fin) == Beof) /* no input */ exits(0); Bseek(fin, 0, 0); gch(); /* may be gotten: def, subs, sname, stchar, ccl, dchar */ get1core(); /* may be gotten: name, left, right, nullstr, parent, ptr */ strcpy((char*)sp, "INITIAL"); sname[0] = sp; sp += strlen("INITIAL") + 1; sname[1] = 0; if(yyparse()) exits("error"); /* error return code */ /* may be disposed of: def, subs, dchar */ free1core(); /* may be gotten: tmpstat, foll, positions, gotof, nexts, nchar, state, atable, sfall, cpackflg */ get2core(); ptail(); mkmatch(); # ifdef DEBUG if(debug) pccl(); # endif sect = ENDSECTION; if(tptr>0)cfoll(tptr-1); # ifdef DEBUG if(debug)pfoll(); # endif cgoto(); # ifdef DEBUG if(debug){ print("Print %d states:\n",stnum+1); for(i=0;i<=stnum;i++)stprt(i); } # endif /* may be disposed of: positions, tmpstat, foll, state, name, left, right, parent, ccl, stchar, sname */ /* may be gotten: verify, advance, stoff */ free2core(); get3core(); layout(); /* may be disposed of: verify, advance, stoff, nexts, nchar, gotof, atable, ccpackflg, sfall */ # ifdef DEBUG free3core(); # endif fother = Bopen(cname,OREAD); if(fother == 0) error("Lex driver missing, file %s: %r",cname); while ( (i=Bgetc(fother)) != Beof) Bputc(&fout, i); Bterm(fother); Bterm(&fout); if( # ifdef DEBUG debug || # endif report == 1)statistics(); if (fin) Bterm(fin); exits(0); /* success return code */ }
int main(int argc, char **argv) { int i; int c; char *apath = NULL; char *ypath; Boolean eoption = 0, woption = 0; sargv = argv; sargc = argc; (void) setlocale(LC_ALL, ""); #ifdef DEBUG while ((c = getopt(argc, argv, "dyctvnewVQ:Y:")) != EOF) { #else while ((c = getopt(argc, argv, "ctvnewVQ:Y:")) != EOF) { #endif switch (c) { #ifdef DEBUG case 'd': debug++; break; case 'y': yydebug = TRUE; break; #endif case 'V': (void) fprintf(stderr, "lex: %s %s\n", (const char *)SGU_PKG, (const char *)SGU_REL); break; case 'Q': v_stmp = optarg; if (*v_stmp != 'y' && *v_stmp != 'n') error( "lex: -Q should be followed by [y/n]"); break; case 'Y': apath = (char *)malloc(strlen(optarg) + sizeof ("/nceucform") + 1); if (apath == NULL) error("No available memory " "for directory name."); else apath = strcpy(apath, optarg); break; case 'c': ratfor = FALSE; break; case 't': fout = stdout; break; case 'v': report = 1; break; case 'n': report = 0; break; case 'w': case 'W': woption = 1; handleeuc = 1; widecio = 1; break; case 'e': case 'E': eoption = 1; handleeuc = 1; widecio = 0; break; default: (void) fprintf(stderr, "Usage: lex [-ewctvnV] [-Y directory] " "[-Q(y/n)] [file]\n"); exit(1); } } if (woption && eoption) { error( "You may not specify both -w and -e simultaneously."); } no_input = argc - optind; if (no_input) { /* XCU4: recognize "-" file operand for stdin */ if (strcmp(argv[optind], "-") == 0) fin = stdin; else { fin = fopen(argv[optind], "r"); if (fin == NULL) error( "Can't open input file -- %s", argv[optind]); } } else fin = stdin; /* may be gotten: def, subs, sname, schar, ccl, dchar */ (void) gch(); /* may be gotten: name, left, right, nullstr, parent */ get1core(); scopy(L_INITIAL, sp); sname[0] = sp; sp += slength(L_INITIAL) + 1; sname[1] = 0; /* XCU4: %x exclusive start */ exclusive[0] = 0; if (!handleeuc) { /* * Set ZCH and ncg to their default values * as they may be needed to handle %t directive. */ ZCH = ncg = NCH; /* ncg behaves as constant in this mode. */ } /* may be disposed of: def, subs, dchar */ if (yyparse()) exit(1); /* error return code */ if (handleeuc) { ncg = ncgidtbl * 2; ZCH = ncg; if (ncg >= MAXNCG) error( "Too complex rules -- requires too many char groups."); sortcgidtbl(); } repbycgid(); /* Call this even in ASCII compat. mode. */ /* * maybe get: * tmpstat, foll, positions, gotof, nexts, * nchar, state, atable, sfall, cpackflg */ free1core(); get2core(); ptail(); mkmatch(); #ifdef DEBUG if (debug) pccl(); #endif sect = ENDSECTION; if (tptr > 0) cfoll(tptr-1); #ifdef DEBUG if (debug) pfoll(); #endif cgoto(); #ifdef DEBUG if (debug) { (void) printf("Print %d states:\n", stnum + 1); for (i = 0; i <= stnum; i++) stprt(i); } #endif /* * may be disposed of: * positions, tmpstat, foll, state, name, * left, right, parent, ccl, schar, sname * maybe get: verify, advance, stoff */ free2core(); get3core(); layout(); /* * may be disposed of: * verify, advance, stoff, nexts, nchar, * gotof, atable, ccpackflg, sfall */ #ifdef DEBUG free3core(); #endif if (handleeuc) { if (ratfor) error("Ratfor is not supported by -w or -e option."); ypath = EUCNAME; } else ypath = ratfor ? RATNAME : CNAME; if (apath != NULL) ypath = strcat(apath, strrchr(ypath, '/')); fother = fopen(ypath, "r"); if (fother == NULL) error("Lex driver missing, file %s", ypath); while ((i = getc(fother)) != EOF) (void) putc((char)i, fout); (void) fclose(fother); (void) fclose(fout); free(apath); if (report == 1) statistics(); (void) fclose(stdout); (void) fclose(stderr); return (0); /* success return code */ } static void get1core(void) { /*LINTED: E_BAD_PTR_CAST_ALIGN*/ ccptr = ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ def = (CHR **)myalloc(DEFSIZE, sizeof (*def)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname)); /* XCU4: exclusive start array */ /*LINTED: E_BAD_PTR_CAST_ALIGN*/ exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive)); /*LINTED: E_BAD_PTR_CAST_ALIGN*/ sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar)); if (ccl == 0 || def == 0 || pchar == 0 || subs == 0 || dchar == 0 || sname == 0 || exclusive == 0 || schar == 0) error("Too little core to begin"); }
void cfoll(int v) { int i,j,k; uint8_t *p; i = name[v]; if(i < NCH) i = 1; /* character */ switch(i){ case 1: case RSTR: case RCCL: case RNCCL: case RNULLS: for(j=0;j<tptr;j++) tmpstat[j] = FALSE; count = 0; follow(v); # ifdef PP padd(foll,v); /* packing version */ # endif # ifndef PP add(foll,v); /* no packing version */ # endif if(i == RSTR) cfoll(left[v]); else if(i == RCCL || i == RNCCL){ /* compress ccl list */ for(j=1; j<NCH;j++) symbol[j] = (i==RNCCL); p = ptr[v]; while(*p) symbol[*p++] = (i == RCCL); p = pcptr; for(j=1;j<NCH;j++) if(symbol[j]){ for(k=0;p+k < pcptr; k++) if(cindex[j] == *(p+k)) break; if(p+k >= pcptr)*pcptr++ = cindex[j]; } *pcptr++ = 0; if(pcptr > pchar + pchlen) error("Too many packed character classes"); ptr[v] = p; name[v] = RCCL; /* RNCCL eliminated */ # ifdef DEBUG if(debug && *p){ print("ccl %d: %d",v,*p++); while(*p) print(", %d",*p++); print("\n"); } # endif } break; case CARAT: cfoll(left[v]); break; case STAR: case PLUS: case QUEST: case RSCON: cfoll(left[v]); break; case BAR: case RCAT: case DIV: case RNEWE: cfoll(left[v]); cfoll(right[v]); break; # ifdef DEBUG case FINAL: case S1FINAL: case S2FINAL: break; default: warning("bad switch cfoll %d",v); # endif } }