cst_item *item_last_daughter(const cst_item *i) { cst_item *p; for (p=item_daughter(i); item_next(p); p=item_next(p)); return p; }
cst_item *item_nth_daughter(const cst_item *i,int n) { int d; cst_item *p; for (d=0,p=item_daughter(i); p && (d < n); p=item_next(p),d++); return p; }
static const cst_val *word_numsyls(const cst_item *word) { cst_item *d; int c; for (c=0,d=item_daughter(item_as(word,"SylStructure")); d; d=item_next(d),c++); return val_int_n(c); }
static const cst_val *syl_onsetsize(const cst_item *syl) { cst_item *d; int c; for (c=0,d=item_daughter(item_as(syl,"SylStructure")); d; d=item_next(d),c++) { if (cst_streq("+",val_string(ph_vc(d)))) break; } return val_string_n(c); }
cst_utterance *russian_postlex_function(cst_utterance *u) { const cst_item *word,*seg; const char *answer,*name,*pair; for(word=relation_head(utt_relation(u,"Transcription"));word;word=item_next(word)) { if(item_feat_present(word,"no_pl")||item_feat_present(word,"no_vr")) continue; for(seg=item_daughter(word);seg;seg=item_next(seg)) { name=item_feat_string(seg,"name"); if(cst_member_string(name,unstressed_vowels)) { answer=val_string(cart_interpret(item_as(seg,"Segment"),&ru_vowel_reduction_cart)); if(!cst_streq(answer,"N")) item_set_string(seg,"name",answer); } else { if(cst_streq(name,"ii")&& cst_streq(ffeature_string(seg,"R:Segment.p.ph_csoft"),"-")&& !(cst_streq(item_feat_string(word,"name"),"и")&& cst_streq(ffeature_string(word,"gpos"),"content"))) { item_set_string(seg,"name","yy"); } } } } for(word=relation_tail(utt_relation(u,"Transcription"));word;word=item_prev(word)) { if(item_feat_present(word,"no_pl")) continue; for(seg=item_last_daughter(word);seg;seg=item_prev(seg)) { name=item_feat_string(seg,"name"); pair=russian_vpair(name); if(pair!=NULL) { answer=val_string(cart_interpret(item_as(seg,"Segment"),&ru_vpair_cart)); if(cst_streq(answer,"Y")) item_set_string(seg,"name",pair); } } } return u; }
static const cst_val *seg_onset_ctype(const cst_item *seg, const char *ctype) { const cst_item *s; const cst_phoneset *ps = item_phoneset(seg); for (s=item_daughter(item_parent(item_as(seg,"SylStructure"))); s; s=item_next(s)) { if (cst_streq("+",phone_feature_string(ps,item_feat_string(s,"name"), "vc"))) return VAL_STRING_0; if (cst_streq(ctype,phone_feature_string(ps,item_feat_string(s,"name"), "ctype"))) return VAL_STRING_1; } return VAL_STRING_0; }
cst_utterance *russian_lexical_insertion(cst_utterance *u) { cst_item *word; cst_relation *sylstructure,*seg,*syl,*sylvowel,*transcription; const cst_val *p; const char *phone_name; cst_val *phones; cst_item *ssword, *sssyl, *segitem, *sylitem, *seg_in_syl, *svsyl, *vowel_in_syl, *tword, *seg_in_word; cst_item *i,*tmp; int num_segs; int total_num_segs=0; syl = utt_relation_create(u,"Syllable"); sylstructure = utt_relation_create(u,"SylStructure"); seg = utt_relation_create(u,"Segment"); sylvowel = utt_relation_create(u,"SylVowel"); transcription = utt_relation_create(u,"Transcription"); for (word=relation_head(utt_relation(u,"Word"));word;word=item_next(word)) { phones=word_to_phones(word); if(!phones) continue; num_segs=val_length(phones); if((total_num_segs+num_segs)>max_num_segs) { delete_val(phones); break; } ssword = relation_append(sylstructure,word); tword = relation_append(transcription,word); for (sssyl=NULL,sylitem=NULL,p=phones; p; p=val_cdr(p)) { if (sylitem == NULL) { sylitem = relation_append(syl,NULL); sssyl = item_add_daughter(ssword,sylitem); } segitem = relation_append(seg,NULL); phone_name = val_string(val_car(p)); item_set_string(segitem,"name",phone_name); seg_in_syl = item_add_daughter(sssyl,segitem); seg_in_word = item_add_daughter(tword,segitem); if(is_vowel(phone_name)) { svsyl=relation_append(sylvowel,sylitem); vowel_in_syl=item_add_daughter(svsyl,segitem); } if (ru_syl_boundary(seg_in_syl,val_cdr(p))) { sylitem = NULL; if (sssyl) item_set_string(sssyl,"stress","0"); } } assign_stress(word); delete_val(phones); total_num_segs+=num_segs; } i=relation_head(utt_relation(u,"Word")); while(i) { tmp=item_next(i); if(item_as(i,"Transcription")==NULL) { delete_item(item_as(i,"Token")); delete_item(item_as(i,"Phrase")); delete_item(i); } i=tmp; } i=relation_head(utt_relation(u,"Phrase")); while(i) { tmp=item_next(i); if(item_daughter(i)==NULL) delete_item(i); i=tmp; } return u; }
static void assign_stress(cst_item *word) { int numsyls=ffeature_int(word,"word_numsyls"); const char *gpos=ffeature_string(word,"gpos"); const cst_item *word_in_phrase=item_as(word,"Phrase"); const cst_item *syls=item_as(word,"SylStructure"); const cst_item *syl=item_daughter(syls); const cst_item *transcription=item_as(word,"Transcription"); int stressed=FALSE; int n=item_feat_present(word,"stressed_syl_num")?item_feat_int(word,"stressed_syl_num"):0; const char *name=item_name(word); const char *pname=ffeature_string(word,"R:Phrase.p.name"); const char *nname=ffeature_string(word,"R:Phrase.n.name"); if(cst_streq(ffeature_string(word,"R:Token.p.name"),"по")&& (cst_streq(name,"моему")||cst_streq(name,"своему")||cst_streq(name,"твоему"))) { item_set_string(syl,"stress","1"); return; } else if((cst_streq(name,"не")||cst_streq(name,"ни"))&& (cst_streq(nname,"был")||cst_streq(nname,"были")||cst_streq(nname,"было"))) { item_set_string(syl,"stress","1"); return; } else if((cst_streq(name,"был")||cst_streq(name,"были")||cst_streq(name,"было"))&& (cst_streq(pname,"не")||cst_streq(pname,"ни"))) return; else if(cst_streq(gpos,"enc")&&item_prev(word_in_phrase)) return; else if(cst_streq(gpos,"proc")&&item_next(word_in_phrase)) return; if(!vowel_seg_between(item_daughter(transcription),item_last_daughter(transcription))) return; if(numsyls==1) { item_set_string(syl,"stress","1"); return; } for(;syl;syl=item_next(syl)) { if(is_stressed_vowel(item_feat_string(item_daughter(item_as(syl,"SylVowel")),"name"))) { item_set_string(syl,"stress","1"); stressed=TRUE; } } if(n==0) { if(stressed) return; n=val_int(cart_interpret(word,&ru_stress_cart)); if((numsyls+n) < 0) { if(numsyls <= 4) n=-2; else if(numsyls <= 6) n=-3; else n=-4; } } item_set_string(item_nth_daughter(syls,(numsyls+n)),"stress","1"); }