📄 regc_color.c
字号:
return COLORLESS; } cm->cd[co].sub = sco; cm->cd[sco].sub = sco; /* open subcolor points to self */ } assert(sco != NOSUB); return sco;}/* * subrange - allocate new subcolors to this range of chrs, fill in arcs */static voidsubrange(struct vars * v, chr from, chr to, struct state * lp, struct state * rp){ uchr uf; int i; assert(from <= to); /* first, align "from" on a tree-block boundary */ uf = (uchr) from; i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf); for (; from <= to && i > 0; i--, from++) newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp); if (from > to) /* didn't reach a boundary */ return; /* deal with whole blocks */ for (; to - from >= BYTTAB; from += BYTTAB) subblock(v, from, lp, rp); /* clean up any remaining partial table */ for (; from <= to; from++) newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);}/* * subblock - allocate new subcolors for one tree block of chrs, fill in arcs */static voidsubblock(struct vars * v, chr start, /* first of BYTTAB chrs */ struct state * lp, struct state * rp){ uchr uc = start; struct colormap *cm = v->cm; int shift; int level; int i; int b; union tree *t; union tree *cb; union tree *fillt; union tree *lastt; int previ; int ndone; color co; color sco; assert((uc % BYTTAB) == 0); /* find its color block, making new pointer blocks as needed */ t = cm->tree; fillt = NULL; for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0; level++, shift -= BYTBITS) { b = (uc >> shift) & BYTMASK; lastt = t; t = lastt->tptr[b]; assert(t != NULL); fillt = &cm->tree[level + 1]; if (t == fillt && shift > BYTBITS) { /* need new ptr block */ t = (union tree *) MALLOC(sizeof(struct ptrs)); if (t == NULL) { CERR(REG_ESPACE); return; } memcpy(VS(t->tptr), VS(fillt->tptr), BYTTAB * sizeof(union tree *)); lastt->tptr[b] = t; } } /* special cases: fill block or solid block */ co = t->tcolor[0]; cb = cm->cd[co].block; if (t == fillt || t == cb) { /* either way, we want a subcolor solid block */ sco = newsub(cm, co); t = cm->cd[sco].block; if (t == NULL) { /* must set it up */ t = (union tree *) MALLOC(sizeof(struct colors)); if (t == NULL) { CERR(REG_ESPACE); return; } for (i = 0; i < BYTTAB; i++) t->tcolor[i] = sco; cm->cd[sco].block = t; } /* find loop must have run at least once */ lastt->tptr[b] = t; newarc(v->nfa, PLAIN, sco, lp, rp); cm->cd[co].nchrs -= BYTTAB; cm->cd[sco].nchrs += BYTTAB; return; } /* general case, a mixed block to be altered */ i = 0; while (i < BYTTAB) { co = t->tcolor[i]; sco = newsub(cm, co); newarc(v->nfa, PLAIN, sco, lp, rp); previ = i; do { t->tcolor[i++] = sco; } while (i < BYTTAB && t->tcolor[i] == co); ndone = i - previ; cm->cd[co].nchrs -= ndone; cm->cd[sco].nchrs += ndone; }}/* * okcolors - promote subcolors to full colors */static voidokcolors(struct nfa * nfa, struct colormap * cm){ struct colordesc *cd; struct colordesc *end = CDEND(cm); struct colordesc *scd; struct arc *a; color co; color sco; for (cd = cm->cd, co = 0; cd < end; cd++, co++) { sco = cd->sub; if (UNUSEDCOLOR(cd) || sco == NOSUB) { /* has no subcolor, no further action */ } else if (sco == co) { /* is subcolor, let parent deal with it */ } else if (cd->nchrs == 0) { /* parent empty, its arcs change color to subcolor */ cd->sub = NOSUB; scd = &cm->cd[sco]; assert(scd->nchrs > 0); assert(scd->sub == sco); scd->sub = NOSUB; while ((a = cd->arcs) != NULL) { assert(a->co == co); uncolorchain(cm, a); a->co = sco; colorchain(cm, a); } freecolor(cm, co); } else { /* parent's arcs must gain parallel subcolor arcs */ cd->sub = NOSUB; scd = &cm->cd[sco]; assert(scd->nchrs > 0); assert(scd->sub == sco); scd->sub = NOSUB; for (a = cd->arcs; a != NULL; a = a->colorchain) { assert(a->co == co); newarc(nfa, a->type, sco, a->from, a->to); } } }}/* * colorchain - add this arc to the color chain of its color */static voidcolorchain(struct colormap * cm, struct arc * a){ struct colordesc *cd = &cm->cd[a->co]; if (cd->arcs != NULL) cd->arcs->colorchainRev = a; a->colorchain = cd->arcs; a->colorchainRev = NULL; cd->arcs = a;}/* * uncolorchain - delete this arc from the color chain of its color */static voiduncolorchain(struct colormap * cm, struct arc * a){ struct colordesc *cd = &cm->cd[a->co]; struct arc *aa = a->colorchainRev; if (aa == NULL) { assert(cd->arcs == a); cd->arcs = a->colorchain; } else { assert(aa->colorchain == a); aa->colorchain = a->colorchain; } if (a->colorchain != NULL) a->colorchain->colorchainRev = aa; a->colorchain = NULL; /* paranoia */ a->colorchainRev = NULL;}/* * singleton - is this character in its own color? */static int /* predicate */singleton(struct colormap * cm, chr c){ color co; /* color of c */ co = GETCOLOR(cm, c); if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB) return 1; return 0;}/* * rainbow - add arcs of all full colors (but one) between specified states */static voidrainbow(struct nfa * nfa, struct colormap * cm, int type, pcolor but, /* COLORLESS if no exceptions */ struct state * from, struct state * to){ struct colordesc *cd; struct colordesc *end = CDEND(cm); color co; for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but && !(cd->flags & PSEUDO)) newarc(nfa, type, co, from, to);}/* * colorcomplement - add arcs of complementary colors * * The calling sequence ought to be reconciled with cloneouts(). */static voidcolorcomplement(struct nfa * nfa, struct colormap * cm, int type, struct state * of, /* complements of this guy's PLAIN * outarcs */ struct state * from, struct state * to){ struct colordesc *cd; struct colordesc *end = CDEND(cm); color co; assert(of != from); for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO)) if (findarc(of, PLAIN, co) == NULL) newarc(nfa, type, co, from, to);}#ifdef REG_DEBUG/* * dumpcolors - debugging output */static voiddumpcolors(struct colormap * cm, FILE *f){ struct colordesc *cd; struct colordesc *end; color co; chr c; char *has; fprintf(f, "max %ld\n", (long) cm->max); if (NBYTS > 1) fillcheck(cm, cm->tree, 0, f); end = CDEND(cm); for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */ if (!UNUSEDCOLOR(cd)) { assert(cd->nchrs > 0); has = (cd->block != NULL) ? "#" : ""; if (cd->flags & PSEUDO) fprintf(f, "#%2ld%s(ps): ", (long) co, has); else fprintf(f, "#%2ld%s(%2d): ", (long) co, has, cd->nchrs); /* * Unfortunately, it's hard to do this next bit more efficiently. * * Spencer's original coding has the loop iterating from CHR_MIN * to CHR_MAX, but that's utterly unusable for 32-bit chr. For * debugging purposes it seems fine to print only chr codes up to * 1000 or so. */ for (c = CHR_MIN; c < 1000; c++) if (GETCOLOR(cm, c) == co) dumpchr(c, f); fprintf(f, "\n"); }}/* * fillcheck - check proper filling of a tree */static voidfillcheck(struct colormap * cm, union tree * tree, int level, /* level number (top == 0) of this block */ FILE *f){ int i; union tree *t; union tree *fillt = &cm->tree[level + 1]; assert(level < NBYTS - 1); /* this level has pointers */ for (i = BYTTAB - 1; i >= 0; i--) { t = tree->tptr[i]; if (t == NULL) fprintf(f, "NULL found in filled tree!\n"); else if (t == fillt) { } else if (level < NBYTS - 2) /* more pointer blocks below */ fillcheck(cm, t, level + 1, f); }}/* * dumpchr - print a chr * * Kind of char-centric but works well enough for debug use. */static voiddumpchr(chr c, FILE *f){ if (c == '\\') fprintf(f, "\\\\"); else if (c > ' ' && c <= '~') putc((char) c, f); else fprintf(f, "\\u%04lx", (long) c);}#endif /* REG_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -