📄 sprog.c
字号:
if(lev > DLEV+1) return 0; if(*ep=='s') { switch(ep[-1]) { case 'y': if(ISVOWEL(ep[-2])||ISUPPER(*word)) break; /*says Kennedys*/ case 'x': case 'z': case 's': return 0; case 'h': switch(ep[-2]) { case 'c': case 's': return 0; } } } return strip(ep,d,a,lev,flag);}Bitsan(char* ep, char* d, char* a, int lev, int flag){ USED(d); if(!ISUPPER(*word)) /*must be proper name*/ return 0; return trypref(ep,a,lev,flag);}Bitsize(char* ep, char* d, char* a, int lev, int flag){ int temp = ep[-1]; Bits h; USED(a); ep[-1] = 'e'; h = strip(ep,"",d,lev,flag); ep[-1] = temp; return h;}Bitsy_to_e(char* ep, char* d, char* a, int lev, int flag){ Bits h; int temp; USED(a); switch(ep[-1]) { case 'a': case 'e': case 'i': return 0; } temp = *ep; *ep++ = 'e'; h = strip(ep,"",d,lev,flag); ep[-1] = temp; return h;}Bitsily(char* ep, char* d, char* a, int lev, int flag){ int temp = ep[0]; char *cp = ep; if(temp==ep[-1]&&temp==ep[-2]) /* sillly */ return 0; if(*--cp=='y' && !ISVOWEL(*--cp)) /* happyly */ while(cp>word) if(ISVOWEL(*--cp)) /* shyness */ return 0; if(ep[-1]=='i') return i_to_y(ep,d,a,lev,flag); return cstrip(ep,d,a,lev,flag);}Bitsbility(char* ep, char* d, char* a, int lev, int flag){ *ep++ = 'l'; return y_to_e(ep,d,a,lev,flag);}Bitsi_to_y(char* ep, char* d, char* a, int lev, int flag){ Bits h; int temp; if(ISUPPER(*word)) return 0; if((temp=ep[-1])=='i' && !ISVOWEL(ep[-2])) { ep[-1] = 'y'; a = d; } h = cstrip(ep,"",a,lev,flag); ep[-1] = temp; return h;}Bitses(char* ep, char* d, char* a, int lev, int flag){ if(lev>DLEV) return 0; switch(ep[-1]) { default: return 0; case 'i': return i_to_y(ep,d,a,lev,flag); case 'h': switch(ep[-2]) { default: return 0; case 'c': case 's': break; } case 's': case 'z': case 'x': return strip(ep,d,a,lev,flag); }}Bitssubst(char* ep, char* d, char* a, int lev, int flag){ char *u,*t; Bits h; USED(a); if(skipv(skipv(ep-1)) < word) return 0; for(t=d; *t!='+'; t++) continue; for(u=ep; *--t!='-';) *--u = *t; h = strip(ep,"",d,lev,flag); while(*++t != '+') continue; while(*++t) *u++ = *t; return h;}Bitstion(char* ep, char* d, char* a, int lev, int flag){ switch(ep[-2]) { default: return trypref(ep,a,lev,flag); case 'a': case 'e': case 'i': case 'o': case 'u': return y_to_e(ep,d,a,lev,flag); }}/* * possible consonant-consonant-e ending */BitsCCe(char* ep, char* d, char* a, int lev, int flag){ Bits h; switch(ep[-1]) { case 'l': if(ISVOWEL(ep[-2])) break; switch(ep[-2]) { case 'l': case 'r': case 'w': break; default: return y_to_e(ep,d,a,lev,flag); } break; case 'c': case 'g': if(*ep == 'a') /* prevent -able for -eable */ return 0; case 's': case 'v': case 'z': if(ep[-2]==ep[-1]) break; if(ISVOWEL(ep[-2])) break; case 'u': if(h = y_to_e(ep,d,a,lev,flag)) return h; if(!(ep[-2]=='n' && ep[-1]=='g')) return 0; } return VCe(ep,d,a,lev,flag);}/* * possible consonant-vowel-consonant-e ending */BitsVCe(char* ep, char* d, char* a, int lev, int flag){ int c; Bits h; c = ep[-1]; if(c=='e') return 0; if(!ISVOWEL(c) && ISVOWEL(ep[-2])) { c = *ep; *ep++ = 'e'; h = trypref(ep,d,lev,flag); if(!h) h = trysuff(ep,lev,flag); if(h) return h; ep--; *ep = c; } return cstrip(ep,d,a,lev,flag);}Ptab*lookuppref(uchar** wp, char* ep){ Ptab *sp; uchar *bp,*cp; unsigned int initchar = Tolower(**wp); if(!ISALPHA(initchar)) return 0; for(sp=preftab[initchar-'a'];sp->s;sp++) { bp = *wp; for(cp= (uchar*)sp->s;*cp; ) if(*bp++!=*cp++) goto next; for(cp=bp;cp<(uchar*)ep;cp++) if(ISVOWEL(*cp)) { *wp = bp; return sp; } next:; } return 0;}/* while word is not in dictionary try stripping * prefixes. Fail if no more prefixes. */Bitstrypref(char* ep, char* a, int lev, int flag){ Ptab *tp; char *bp, *cp; char *pp; Bits h; char space[20]; if(lev<DSIZ) { deriv[lev].mesg = a; deriv[lev].type = *a=='.'? NONE: SUFF; } if(h = tryword(word,ep,lev,flag)) { if(Set(h, flag&~MONO) && (flag&MONO) <= Set(h, MONO)) return h; h = 0; } bp = word; pp = space; if(lev<DSIZ) { deriv[lev+1].mesg = pp; deriv[lev+1].type = 0; } while(tp=lookuppref((uchar**)&bp,ep)) { *pp++ = '+'; cp = tp->s; while(pp<space+sizeof(space) && (*pp = *cp++)) pp++; deriv[lev+1].type += PREF; h = tryword(bp,ep,lev+1,flag); if(Set(h,NOPREF) || ((tp->flag&IN) && inun(bp-2,h)==0)) { h = 0; break; } if(Set(h,flag&~MONO) && (flag&MONO) <= Set(h, MONO)) break; h = 0; } if(lev < DSIZ) { deriv[lev+1] = emptyderiv; deriv[lev+2] = emptyderiv; } return h;}Bitstryword(char* bp, char* ep, int lev, int flag){ int j; Bits h = 0; char duple[3]; if(ep-bp <= 1) return h; if(flag&MONO) { if(lev<DSIZ) { deriv[++lev].mesg = duple; deriv[lev].type = SUFF; } duple[0] = '+'; duple[1] = *ep; duple[2] = 0; } h = dict(bp, ep); if(vflag==0 || h==0) return h; /* * when derivations are wanted, collect them * for printing */ j = lev; prefcount = suffcount = 0; do { if(j<DSIZ && deriv[j].type) { strcat(affix, deriv[j].mesg); if(deriv[j].type == SUFF) suffcount++; else if(deriv[j].type != NONE) prefcount = deriv[j].type/PREF; } } while(--j > 0); return h;}intinun(char* bp, Bits h){ if(*bp == 'u') return Set(h, IN) == 0; /* *bp == 'i' */ if(Set(h, IN) == 0) return 0; switch(bp[2]) { case 'r': return bp[1] == 'r'; case 'm': case 'p': return bp[1] == 'm'; } return bp[1] == 'n';}char*skipv(char *s){ if(s >= word && ISVOWEL(*s)) s--; while(s >= word && !ISVOWEL(*s)) s--; return s;}/* * crummy way to Britishise */voidise(void){ Suftab *p; int i; for(i=0; i<26; i++) for(p = suftab[i]; p->suf; p++) { p->suf = ztos(p->suf); p->d1 = ztos(p->d1); p->a1 = ztos(p->a1); }}char*ztos(char *as){ char *s, *ds; for(s=as; *s; s++) if(*s == 'z') goto copy; return as;copy: ds = strdup(as); for(s=ds; *s; s++) if(*s == 'z') *s = 's'; return ds;}Bitsdict(char* bp, char* ep){ char *cp, *cp1, *w, *wp, *we; int n, f; w = bp; we = ep; n = ep-bp; if(n <= 1) return NOUN; f = w[0] & 0x7f; f *= 128; f += w[1] & 0x7f; bp = spacep[f]; ep = spacep[f+1];loop: if(bp >= ep) { if(xflag) fprint(2, "=%.*s\n", utfnlen(w, n), w); return 0; } /* * find the beginning of some word in the middle */ cp = bp + (ep-bp)/2; while(cp > bp && !(*cp & 0x80)) cp--; while(cp > bp && (cp[-1] & 0x80)) cp--; wp = w + 2; /* skip two letters */ cp1 = cp + 2; /* skip affix code */ for(;;) { if(wp >= we) { if(*cp1 & 0x80) goto found; else f = 1; break; } if(*cp1 & 0x80) { f = -1; break; } f = *cp1++ - *wp++; if(f != 0) break; } if(f < 0) { while(!(*cp1 & 0x80)) cp1++; bp = cp1; goto loop; } ep = cp; goto loop;found: f = ((cp[0] & 0x7) << 8) | (cp[1] & 0xff); if(xflag) { fprint(2, "=%.*s ", utfnlen(w, n), w); typeprint(encode[f]); } return encode[f];}voidtypeprint(Bits h){ pcomma(""); if(h & NOUN) pcomma("n"); if(h & PROP_COLLECT) pcomma("pc"); if(h & VERB) { if((h & VERB) == VERB) pcomma("v"); else if((h & VERB) == V_IRREG) pcomma("vi"); else if(h & ED) pcomma("ed"); } if(h & ADJ) pcomma("a"); if(h & COMP) { if((h & COMP) == ACTOR) pcomma("er"); else pcomma("comp"); } if(h & DONT_TOUCH) pcomma("d"); if(h & N_AFFIX) pcomma("na"); if(h & ADV) pcomma("adv"); if(h & ION) pcomma("ion"); if(h & V_AFFIX) pcomma("va"); if(h & MAN) pcomma("man"); if(h & NOPREF) pcomma("nopref"); if(h & MONO) pcomma("ms"); if(h & IN) pcomma("in"); if(h & _Y) pcomma("y"); if(h & STOP) pcomma("s"); fprint(2, "\n");}voidpcomma(char *s){ static flag; if(*s == 0) { flag = 0; return; } if(!flag) { fprint(2, "%s", s); flag = 1; } else fprint(2, ",%s", s);}/* * is the word on of the following * 12th teen * 21st end in 1 * 23rd end in 3 * 77th default * called knowing word[0] is a digit */intordinal(void){ char *cp = word; static char sp[4]; while(ISDIGIT(*cp)) cp++; strncpy(sp,cp,3); if(ISUPPER(cp[0]) && ISUPPER(cp[1])) { sp[0] = Tolower(cp[0]); sp[1] = Tolower(cp[1]); } return 0 == strncmp(sp, cp[-2]=='1'? "th": /* out of bounds if 1 digit */ *--cp=='1'? "st": /* harmless */ *cp=='2'? "nd": *cp=='3'? "rd": "th", 3);}/* * read in the dictionary. * format is * { * short nencode; * long encode[nencode]; * char space[*]; * }; * * the encodings are a table all different * affixes. * the dictionary proper has 2 bytes * that demark and then the rest of the * word. the 2 bytes have the following * 0x80 0x00 flag * 0x78 0x00 count of prefix bytes * common with prev word * 0x07 0xff affix code * * all ints are big endians in the file. */voidreaddict(char *file){ char *s, *is, *lasts, *ls; int c, i, sp, p; int f; long l; lasts = 0; f = open(file, 0); if(f == -1) { fprint(2, "cannot open %s\n", file); exits("open"); } if(read(f, space, 2) != 2) goto bad; nencode = ((space[0]&0xff)<<8) | (space[1]&0xff); if(read(f, space, 4*nencode) != 4*nencode) goto bad; s = space; for(i=0; i<nencode; i++) { l = (long)(s[0] & 0xff) << 24; l |= (s[1] & 0xff) << 16; l |= (s[2] & 0xff) << 8; l |= s[3] & 0xff; encode[i] = (Bits)l; s += 4; } l = read(f, space, sizeof(space)); if(l == sizeof(space)) goto noroom; is = space + (sizeof(space) - l); memmove(is, space, l); s = space; c = *is++ & 0xff; sp = -1; i = 0;loop: if(s > is) goto noroom; if(c < 0) { close(f); while(sp < 128*128) spacep[++sp] = s; *s = 0x80; /* fence */ return; } p = (c>>3) & 0xf; *s++ = c; *s++ = *is++ & 0xff; if(p <= 0) i = (*is++ & 0xff)*128; if(p <= 1) { if(!(*is & 0x80)) i = i/128*128 + (*is++ & 0xff); if(i <= sp) { fprint(2, "the dict isnt sorted or \n"); fprint(2, "memmove didn't work\n"); goto bad; } while(sp < i) spacep[++sp] = s-2; } ls = lasts; lasts = s; for(p-=2; p>0; p--) *s++ = *ls++; for(;;) { if(is >= space+sizeof(space)) { c = -1; break; } c = *is++ & 0xff; if(c & 0x80) break; *s++ = c; } *s = 0; goto loop;bad: fprint(2, "trouble reading %s\n", file); exits("read");noroom: fprint(2, "not enough space for dictionary\n"); exits("space");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -