bool CAnalyticFormBuilder::HasDeclinableSynNounInInstrumentalis(const CWord& _W) const { for (CWord::SHomIt it = _W.IterHomonyms(); it.Ok(); ++it) if (IsSynNoun(*it) && it->HasGrammem(gInstrumental) && !it->HasGrammem(gNominative)) return true; return false; }
bool CAnalyticFormBuilder::HasInfinitive(const CWord& W) { for (CWord::SHomIt it = W.IterHomonyms(); it.Ok(); ++it) if (it->HasGrammem(gInfinitive)) return true; return false; }
bool CAnalyticFormBuilder::HasCompar(const CWord& W) { for (CWord::SHomIt it = W.IterHomonyms(); it.Ok(); ++it) if (it->IsFullAdjective() && it->HasGrammem(gComparative)) return true; return false; }
bool CAnalyticFormBuilder::HasPredik(const CWord& W) { for (CWord::SHomIt it = W.IterHomonyms(); it.Ok(); ++it) if (!it->Grammems.IsIndeclinable()) // "бух","спасибо" не строятся с анал. формами if (it->HasGrammem(gPraedic)) return true; return false; }
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; }
bool CAnalyticFormBuilder::HasAnalyticalBe(const CWord& _W) const { //NB! в настоящем варианте парсера нет словаря оборотов, поэтому проверка слова на оборот временно отключена // если мы попали на оборот(например, "может быть"), тогда не будем строить здесь анал. форму. //if (_W.IsInOborot()) return false; // "быто" предсказывается как "быть" //if (_W.m_bPredicted) return false; //NB! пока предсказание отсутствует в парсере //if ( _W.HasPOS(UnknownPOS) ) return false; if (_W.HasUnknownPOS()) return false; for (CWord::SHomIt it = _W.IterHomonyms(); it.Ok(); ++it) { bool is_verb = it->IsPersonalVerb(); if (is_verb && !it->IsPresentTense() && it->Lemma == kByt) return true; if ((is_verb || it->HasGrammem(gInfinitive)) && it->Lemma == kStat) return true; } return false; }
/* building of verb analytical forms: auxiliary can be "byt'" (to be) or "stat'" (to become) [translit] */ void CAnalyticFormBuilder::BuildAnalyticalVerbForms() { //auxiliary verb number in chain of wordforms - the first part of an.f. int iBe = -1; //vector of potential predicates for second part CAnalyticalFormVars v_AnalyticalFormVars; BuildAnalyticalVerbFormsZaplata2(); for (size_t WordNo = 0; WordNo < m_ClauseWords.size(); WordNo++) { const CWord& _Form = m_Words.GetWord(m_ClauseWords.at(WordNo)); if (!_Form.IsAnalyticVerbForm()) { if (!m_ClauseWords.at(WordNo).m_bOriginalWord) continue; const Wtroka& s_lem = _Form.IterHomonyms()->Lemma; //looking for verbs "to be" or "to become" if (HasAnalyticalBe(_Form) && iBe == -1) { iBe = WordNo; continue; } if (HasInfinitive(_Form)) { v_AnalyticalFormVars.push_back(SAnalyticalFormVariant(WordNo, _Form.GetRusHomonymsCount(), SAnalyticalFormVariant::Infinitive, s_lem, AllHomonymsArePredicates(_Form))); continue; } if (HasPredik(_Form)) { v_AnalyticalFormVars.push_back(SAnalyticalFormVariant(WordNo, _Form.GetRusHomonymsCount(), SAnalyticalFormVariant::Predikative, s_lem, AllHomonymsArePredicates(_Form))); continue; } if (HasShortParticipleOrAdj(_Form)) { v_AnalyticalFormVars.push_back(SAnalyticalFormVariant(WordNo, _Form.GetRusHomonymsCount(), SAnalyticalFormVariant::Short_Form, s_lem, AllHomonymsArePredicates(_Form))); continue; } //looking for comparative form if (HasCompar(_Form)) v_AnalyticalFormVars.push_back(SAnalyticalFormVariant(WordNo, _Form.GetRusHomonymsCount(), SAnalyticalFormVariant::Comp_Adj, s_lem, AllHomonymsArePredicates(_Form))); } } if (iBe != -1 && v_AnalyticalFormVars.size() > 0) { { //правило для цепочки {"быть"(буд.), предикатив (омонимичный), инфинитив (нс)}, тогда строим ан.ф. с инфинитивом //"Мальчик будет горько плакать" int DummyHomNo; bool bDummyAuxVHom; yvector<int> dummyVector; if ((2 == v_AnalyticalFormVars.size()) && (iBe < v_AnalyticalFormVars[0].iWordNum) && !v_AnalyticalFormVars[0].bAllHomPredik && SAnalyticalFormVariant::Predikative == v_AnalyticalFormVars[0].ePos && SAnalyticalFormVariant::Infinitive == v_AnalyticalFormVars[1].ePos && IsAnalyticalVerbForm(iBe, v_AnalyticalFormVars[0].iWordNum, DummyHomNo, dummyVector, bDummyAuxVHom) && IsAnalyticalVerbForm(iBe, v_AnalyticalFormVars[1].iWordNum, DummyHomNo, dummyVector, bDummyAuxVHom) ) { bool bFoundChain = true; for (int mm = 0; mm < iBe; mm++) { const CWord& _Form = m_Words.GetWord(m_ClauseWords.at(mm)); for (CWord::SHomIt it = _Form.IterHomonyms(); it.Ok(); ++it) if (it->HasGrammem(gDative)) bFoundChain = false; } if (bFoundChain) // удаляем вариант омонимичного предикатива, если есть вариант будущего времени v_AnalyticalFormVars.erase(v_AnalyticalFormVars.begin()); } // конец подслучая "Мальчик будет горько плакать" }; //проверить на возможное вхождение компоненты аналитической формы в синтаксическую группу: //"был о нем" //CheckGroupsForAnalyticalVerbForms(v_AnalyticalFormVars, PrCl); : DIALING //в текущей версии синтаксиса именных групп покамест нет if (0 == v_AnalyticalFormVars.size()) return; /*разбираем случай "он был больше учителем, чем шофером", где не надо строить аналитическую форму со сравн. степенью, хотя, в принципе, ей ничего не мешает. Формально: Если у нас только одна гипотеза ("сравн. степени"), если после нее стоит существительное в творительном падеже, тогда анал. форму строит не надо. Сокирко. 3 мая 2001 */ if (v_AnalyticalFormVars.size() == 1) if (SAnalyticalFormVariant::Comp_Adj == v_AnalyticalFormVars[0].ePos) if (CheckComparativeZAPLATAForAnalyticalForm(v_AnalyticalFormVars[0].iWordNum)) return; //установить порядок на гипотезах (см. operator<); std::sort(v_AnalyticalFormVars.begin(), v_AnalyticalFormVars.end()); for (size_t k = 0; k < v_AnalyticalFormVars.size(); k++) if (CheckAnalyticalVerbForm(iBe, v_AnalyticalFormVars[k].iWordNum)) { //Stroka n_str = m_Words[iBe].m_strWord; //n_str = n_str + "-" + m_Words[v_AnalyticalFormVars[k].iWordNum].m_strWord; //m_Words[v_AnalyticalFormVars[k].iWordNum].SetWordStr(n_str); //m_Words[v_AnalyticalFormVars[k].iWordNum].m_bAnalyticalForm = true; break; } } }