void CPrimitiveGroup::SetActiveSymbol(int iS) { CGroup::SetActiveSymbol(iS); for (CWord::SHomIt it = m_pWord->IterHomonyms(); it.Ok32(); ++it) if (it->HasTerminalSymbol(iS)) m_ActiveHomonyms |= (1 << it.GetID()); ResetGrammems(); }
bool CAnalyticFormBuilder::CheckAnalyticalVerbForm(int iVWrd, int iSWrd) { int VerbHomNo; yvector<int> AnalyticHom; bool b_AddAuxVerbHom; if (!IsAnalyticalVerbForm(iVWrd, iSWrd, VerbHomNo, AnalyticHom, b_AddAuxVerbHom)) return false; if (AnalyticHom.size() == 0) return false; CWord& _Be = m_Words.GetWord(m_ClauseWords.at(iVWrd)); CWord& _Predik = m_Words.GetWord(m_ClauseWords.at(iSWrd)); //nim: в версии Диалинга у потенциального предиката (второй компоненты аналитической формы) //удалялись все омонимы, которые не могли образовать настоящую аналитическую форму, //например, для "хорошо" удалялись омонимы "Н" и "ЧАСТ". //в текущей версии покамест оставляем все омонимы. :nim for (size_t j = 0; j < AnalyticHom.size(); j++) { ChangeGrammemsAsAnalyticForm(_Predik.GetRusHomonym(AnalyticHom[j]), _Be.GetRusHomonym(VerbHomNo)); } if (b_AddAuxVerbHom) { THomonymPtr pAuxHom = _Be.GetRusHomonym(VerbHomNo).Clone(); pAuxHom->Grammems.Add(gAuxVerb); _Be.AddRusHomonym(pAuxHom); VerbHomNo = _Be.HasPOSi(gAuxVerb); } else _Be.GetRusHomonym(VerbHomNo).Grammems.Add(gAuxVerb); //удаляются омонимы не AuxVerb //так для слф. "были" будет убит омоним "быль" //пример: "были спровоцированы скандалы" yvector<int> HomsToDel; for (CWord::SHomIt it = _Be.IterHomonyms(); it.Ok(); ++it) if (!it->HasGrammem(gAuxVerb)) HomsToDel.push_back(it.GetID()); YASSERT(HomsToDel.size() < _Be.GetRusHomonymsCount()); for (size_t i = 0; i < HomsToDel.size(); ++i) _Be.DeleteHomonym(HomsToDel[i]); //так как если вызывается из фрагментации и с синтаксисом, то //уже все символы были построены, а мы удаляем омоним с приписанными терминалами _Be.UniteHomonymsTerminalSymbols(); for (size_t j = 0; j < AnalyticHom.size(); j++) _Predik.GetRusHomonym(AnalyticHom[j]).SetAnalyticMainVerbHom(&(_Be.GetRusHomonym(VerbHomNo))); return true; }
static bool FindBestHomonym(const CWord& word, TWtringBuf lemma, TKeyWordType kwtype, THomonymGrammems grammems, int& homId) { // search if we already have a multiword homonym with such text bool found = false; bool foundSameKwType = false; for (CWord::SHomIt it = word.IterHomonyms(); it.Ok(); ++it) if (it->CHomonymBase::GetLemma() == lemma) { if (it->HasKWType(kwtype, KW_DICT)) { if (it->Grammems == grammems) { homId = it.GetID(); // prefer homonyms with same kwtype and same grammems return true; } else if (!foundSameKwType) { homId = it.GetID(); // prefer homonyms with same kwtype found = true; foundSameKwType = true; } } else if (!found) { homId = it.GetID(); // otherwise, return the first one having @lemma text found = true; } } return found; }
//check an agreement between aux. verbs and predicates of analitical form. bool CAnalyticFormBuilder::IsAnalyticalVerbForm(int iVerbWrd, int iSWrd, int& VerbHomNo, yvector<int>& AnalyticHom, bool& b_AddAuxVerbHom) { b_AddAuxVerbHom = false; AnalyticHom.clear(); const CWord& _Be = m_Words.GetWord(m_ClauseWords.at(iVerbWrd)); const CWord& _Predik = m_Words.GetWord(m_ClauseWords.at(iSWrd)); //с предикативными значениями "много" и "мало" анал. форм не строить : DIALING //с предикативными значениями "много" и "мало" анал. форм строится, но клонируется омоним для вспомогательного глагола //if ( ( m_Words[iSWrd].FindLemma("МНОГО") || m_Words[iSWrd].FindLemma("МАЛО") ) && ... ) if (_Predik.HasPOS(gNumeral) && _Predik.HasPOS(gPraedic)) b_AddAuxVerbHom = true; //14.07.04: отсутствие синтаксиса порождает заплатку: //если у потенциального предиката есть омоним Noun, то добавить омоним AuxVerb для вспомогательного глагола, //в противном случае, просто изменить часть речи на AuxVerb. if (_Predik.HasMorphNoun()) b_AddAuxVerbHom = true; //masks used later (to avoid constructing them repeatedly in loop) const TGramBitSet Verb_Infinitive(gVerb, gInfinitive), Infinitive_Imperfect(gInfinitive, gImperfect), Person3_Singular(gPerson3, gSingular), Infinitive_Gerund(gInfinitive, gGerund); for (CWord::SHomIt it = _Be.IterHomonyms(); it.Ok(); ++it) { VerbHomNo = it.GetID(); const CHomonym& VerbHom = _Be.GetRusHomonym(VerbHomNo); if (VerbHom.Lemma == kByt || (VerbHom.Lemma == kStat && VerbHom.HasAnyOfPOS(Verb_Infinitive))) { for (CWord::SHomIt it_predik = _Predik.IterHomonyms(); it_predik.Ok(); ++it_predik) { int j = it_predik.GetID(); const CHomonym& ShortFormHom = _Predik.GetRusHomonym(j); if (ShortFormHom.Grammems.HasAll(Infinitive_Imperfect) && (VerbHom.IsFutureTense() || VerbHom.Lemma == kStat)) AnalyticHom.push_back(j); else if ((ShortFormHom.HasGrammem(gPraedic)) && (VerbHom.HasGrammem(gNeuter) || (VerbHom.IsFutureTense() && VerbHom.Grammems.HasAll(Person3_Singular)))) AnalyticHom.push_back(j); else if (ShortFormHom.HasGrammem(gComparative) && ShortFormHom.IsFullAdjective()) AnalyticHom.push_back(j); else if (ShortFormHom.IsShortAdjectiveOrParticiple()) { // "была", "стал", "был", "было" ... if ((VerbHom.HasGrammem(gSingular) && VerbHom.IsPastTense() && ShortFormHom.HasGrammem(gSingular) && (VerbHom.Grammems.All() & ShortFormHom.Grammems.All()).HasAny(NSpike::AllGenders)) || (VerbHom.HasGrammem(gPlural) && ShortFormHom.HasGrammem(gPlural)) || (!VerbHom.IsPastTense() && VerbHom.HasGrammem(gSingular) && ShortFormHom.HasGrammem(gSingular)) || VerbHom.Grammems.HasAny(Infinitive_Gerund)) AnalyticHom.push_back(j); } } return AnalyticHom.size() > 0; } } return false; }