void CRusSentence::BuildDash(int iClauseNum, int iWrdAfter, bool bCopul) { SClauseType type; CClause& pClause = GetClause(iClauseNum); if (bCopul) { pClause.ChangeAllClauseTypesToOneType(SClauseType(COPUL_T, -1,-1)); return; } if ( m_Words[iWrdAfter].IsInOborot() ) return; if (pClause.IsInTermin(iWrdAfter)) return; if (IsBetweenGraphematicalPairDescriptors(iWrdAfter)) return; int DashWordNo = iWrdAfter + 1; m_Words.insert(m_Words.begin() + DashWordNo, CreateDash(this)); RecalculateIndicesAfterInsertingWord(DashWordNo); pClause.ChangeAllClauseTypesToOneType(SClauseType(DASH_T, DashWordNo, 0) ); }
bool CRusSentence::RuleForParticiples(int iClauseNum) { CClause* pAbstClause = &GetClause(iClauseNum); int iWord = pAbstClause->m_iFirstWord; if ( IsEnclosedClause (iClauseNum) ) return false; if ( pAbstClause->HasUnambiguousStrongRootWithoutWeakHomonyms()) return false; int iParticipleType; if( (iParticipleType = pAbstClause->FindType(PARTICIPLE_T)) == -1 ) return false; assert(!pAbstClause->m_vectorTypes[iParticipleType].m_Root.IsEmpty()); CSynWord& pParticiple = m_Words[pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo]; int iPart = pParticiple.GetHomonymByPOS(PARTICIPLE); if( iPart == -1 ) return false; //пытаемся найти слева int iPrev = FindNounFromTheLeftOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart)); //пытаемся найти слева подходящее сущ.(тогда причастие после определяемого слова) if ( ( m_Words[iWord].m_SubordinateConjNo == -1 ) && ( (pAbstClause->m_iFirstWord != pAbstClause->m_iLastWord ) || ( (iWord+1<m_Words.size()) && (m_Words[iWord+1].m_SubordinateConjNo != -1 ) ) ) && (iPrev != -1) && ( pAbstClause->m_iLastWord+1 == m_Words.size() // проверка правой границы (должен быть знак препинания) || m_Words[pAbstClause->m_iLastWord+1].HasDes(OPun) ) ) { /* Поскольку мы собираемся вкладывать клаузу, нам приходится удалять все вершины клаузы, кроме найденного причастия и все омонимы причастия */ // уничтожаем другие вершины клаузы int k = 0; for( ; k < pAbstClause->m_vectorTypes.size() ; k++) { if(iParticipleType == k) continue; if(k < iParticipleType) iParticipleType--; int WordNo = pAbstClause->m_vectorTypes[k].m_Root.m_WordNo; // не будем удалять омоним, если он единственный у слова if (pAbstClause->GetWords()[WordNo].GetHomonymsCount() > 1) pAbstClause->DeleteHomonym(pAbstClause->m_vectorTypes[k].m_Root.m_WordNo, pAbstClause->m_vectorTypes[k].m_Root.m_HomonymNo); else pAbstClause->DeleteClauseType( k ); k--; } // заново надо найти омоними причастия, поскольку мы в предыдущем цикле удалили некоторые омонимы iPart = pParticiple.GetHomonymByPOS(PARTICIPLE); int PartWordNo = pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo; // уничтожаем омонимы причастия (прилагательное или существительное), for(k = 0 ; k < pParticiple.GetHomonymsCount() ; k++) { if(iPart == k) continue; if(k < iPart) iPart--; pAbstClause->DeleteHomonym(PartWordNo, k); k--; } return EncloseClauseAsWord(iClauseNum, iPrev); } else // пытаемся найти справа (причастие не отделено запятой) if( FindNounFromTheRightOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart) ) ) { // тогда нужно удалить клаузный вариант причастия, а если вариант только один, тогда // нужно его отконвертировать в пустыху if(pAbstClause->m_vectorTypes.size() == 1) { assert (pAbstClause->m_vectorTypes[0].m_Type == PARTICIPLE_T); pAbstClause->ChangeAllClauseTypesToOneType( SClauseType(UnknownSyntaxElement,-1,-1) ); } else { assert( iParticipleType >= 0); pAbstClause->DeleteClauseType( iParticipleType ); } } return false; }