void CSentence::InitClauseType(CClause& clause) { clause.m_vectorTypes.clear(); vector <SClauseType> WeakTypes; // bHasStrongRoot is true if there is a word whose all homonyms are clause roots // if no such a word exists, then we should add weak clause types to CClause::m_vectorTypes bool bHasStrongRoot = false; for(int j = clause.m_iFirstWord; j <= clause.m_iLastWord;j++ ) { EClauseType AuxVerbClauseType; bool bHasAuxVerb = false; // pass all auxiliary verbs if (!m_Words[j].m_MainVerbs.empty()) continue; // if the current word has an auxiliary verb, then take the type information from // the auxiliary verb, which can be used if the main verb is not predicative (for example, German participle 2) int AuxVerbWordNo = FindFirstAuxVerb(j); if (AuxVerbWordNo != -1) { { int z = FindFirstAuxVerb(AuxVerbWordNo); if (z != -1) AuxVerbWordNo = z; } bHasAuxVerb = true; AuxVerbClauseType = GetClauseTypeByAncodePattern(m_Words[AuxVerbWordNo].m_Homonyms[0]); }; const CSynWord& W = m_Words[j]; bHasStrongRoot = bHasStrongRoot || AllHomonymsArePredicates(W); for(int k = 0; k < W.m_Homonyms.size(); k++) { const CSynHomonym& H = W.m_Homonyms[k]; SClauseType type; type.m_Type = GetClauseTypeByAncodePattern(H); type.m_Root.m_WordNo = j; type.m_Root.m_HomonymNo = k; if ( GetOpt()->GetGramTab()->IsStrongClauseRoot(H.m_iPoses) && (type.m_Type != UnknownPartOfSpeech) ) clause.m_vectorTypes.push_back(type); else { if ( bHasAuxVerb && (AuxVerbClauseType != UnknownPartOfSpeech) && ( (GetOpt()->m_Language != morphRussian) || (type.m_Type != COMPARATIVE_T) ) ) { // if the main part of an analytical verb form is not finite // then take the clause type from the auxiliary verb type.m_Type = AuxVerbClauseType; clause.m_vectorTypes.push_back(type); } else if (type.m_Type != UnknownPartOfSpeech) WeakTypes.push_back(type); }; }; }; // if there is no strong roots or strong roots have homonyms then add weak roots if (clause.m_vectorTypes.empty() || !bHasStrongRoot) clause.m_vectorTypes.insert(clause.m_vectorTypes.end(), WeakTypes.begin(),WeakTypes.end()); }
int CSentence::CheckIfBracketIsAClauseBorder(int WordNo, int& iStartSearch) { const CSynWord& pWord = m_Words[WordNo]; if( !m_bFirstInPairFound ) { const char* open_brck = strchr (OpenBracket, pWord.m_strWord[0]); if(open_brck != 0) { char close_brck[2]; close_brck[0] = CloseBracket[open_brck-OpenBracket]; close_brck[1] = 0; CWordVector::const_iterator word = microsoft_find_if(m_Words.begin() + WordNo + 1,m_Words.end(),CWord_eq(close_brck)); if( word != m_Words.end()) { long Distance = (word - m_Words.begin()) - WordNo; /* если в скобка стоит более одного слова или слово, которое стоит в скобках - неомонимичный предикат, тогда будем считать эту открывающую скобку началом клаузы */ if ( (Distance > 2 ) || AllHomonymsArePredicates(m_Words[WordNo+1]) ) { iStartSearch = WordNo+1; m_bFirstInPairFound = true; return WordNo-1; } else { iStartSearch = (word - m_Words.begin()) + 1; if ( iStartSearch == m_Words.size() ) --iStartSearch; return -1; } } else { iStartSearch = WordNo+1; return -1; } } } else { const char* close_brck = strchr (CloseBracket, pWord.m_strWord[0]); if(close_brck != 0) { // вышли за скобки m_bFirstInPairFound = false; // закрывающую скобку, которая стоит перед концом предложения будем игнорировать, // поскольку конец клаузы придет вместе с концом предложения. Иначе возникнет клауза, которая // состоит только из конца предложения (Знака препинания). // Пример: "я шел (мама)." if ( (WordNo+2 == m_Words.size()) && m_Words[WordNo+1].HasDes(OPun) ) { iStartSearch = WordNo+1; return -1; }; // искать надо после скобок iStartSearch = WordNo+1; return WordNo; } } iStartSearch = WordNo+1; return -1; }
/* 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; } } }