01 CTask *trie_task=Fs; 02 class CTrie { 03 U8 *str; 04 U8 *front_declension;//Optionalaly used 05 U8 *back_declension;//Optionalaly used 06 U8 *translation; 07 I64 flags; 08 CTrie *branches[26]; 09 CTrie *next; 10 }; 11 CTrie root; 12 MemSet(&root,0,sizeof(CTrie)); 13 CTrie *TrieGet(U8 *name,CTrie *of=&root) { 14 ent: 15 if(!of) return NULL; 16 if(!*name) { 17 while(!of->str) { 18 of=of->next; 19 if(!of) return NULL; 20 } 21 return of; 22 } 23 if('A'<=ToUpper(*name)<='Z') { 24 of=of->branches[ToUpper(*name)-'A']; 25 name++; 26 goto ent; 27 } 28 return NULL; 29 } 30 CTrie *TrieExists(U8 *name,I64 flags) { 31 CTrie *t=TrieGet(name),*ret=t; 32 while(t) { 33 if(t->flags==flags) 34 return t; 35 t=t->next; 36 } 37 return NULL; 38 } 39 CTrie *TrieAdd(U8 *name,I64 flags=0,U8 *translation=NULL) { 40 I64 idx; 41 CTrie *new=CAlloc(sizeof(CTrie),trie_task),*to=&root,**ins_at=&to->next,*new2; 42 if(translation) new->translation=StrNew(translation,trie_task); 43 new->str=StrNew(name,trie_task); 44 new->flags=flags; 45 while(*name) { 46 if('A'<=(idx=ToUpper(*name))<='Z') { 47 idx-='A'; 48 if(to->branches[idx]) { 49 to=to->branches[idx]; 50 } else { 51 new2=CAlloc(sizeof(CTrie),trie_task); 52 to->branches[idx]=new2; 53 to=new2; 54 } 55 ins_at=&to->next; 56 name++; 57 } else if(*name) 58 throw('InvChr'); 59 } 60 while(ins_at[0]) 61 ins_at=&ins_at[0]->next; 62 *ins_at=new; 63 return new; 64 };