Пример #1
0
bool CRusSentence::RuleForSubClauseWithCoordiantion(int iClauseNum)
{
	const CClause* pAbstClause = &GetClause(iClauseNum);
	int iWord = pAbstClause->m_iFirstWord;

	if(		pAbstClause->HasType(INP_T)  
		||  (pAbstClause->m_vectorTypes.size() == 0)
		)
		return false;


	//  берем следующую клаузу, которая должна быть с сочинительным союзом
	int iNext = GetMaxClauseByFirstWord(m_Clauses[iClauseNum].m_iLastWord+1);
	if(iNext == -1)
		return false;


	const CClause* pAbstClause1 = &GetClause(iNext);



    int type = pAbstClause1->FindCommonType(*pAbstClause);
    switch (type)
    {
        case INP_T  :

        case -1     :       return false;

        case PARTICIPLE_T:
                            if	(!CheckCoordinarionBetweenClauseRoots(GenderNumberCaseRussian, iClauseNum, iNext))
                                return false;
                            break;

        case ADVERB_PARTICIPLE_T:  break;// do noting

        default:
      	            if  (        ClauseHasSubjPredik(GetClause(iNext)) // если вторая  клаузы  имеет подлежащее, тогда  согласование искать не надо
                            ||  !CheckCoordinarionBetweenClauseRoots(FiniteFormCoordRussian, iClauseNum, iNext)
                        )
                         //  проверка на неоднозначность границы
                            if(GetMinClauseByLastWord(m_Clauses[iClauseNum].m_iLastWord) !=  GetMaxClauseByLastWord(m_Clauses[iClauseNum].m_iLastWord))
                                return false;
                    /*
                        если  во вставляемой  клаузе  вершина омонимична, то мы должны делать следующее:
                        1. Либо удалить все непрeдикатные омонимы, оставив только прeдикаты, поскольку  пустыха не может быть вложена;
                        2. Либо не обрабатывать эти случаи совсем, поскольку  позже с непредикатными омонимами может что-нибудь хорошее
                        произойти
                        Мы предпочитаем второе решение, хотя это фактически использование старого определения пустыхи, что не очень 
                        идеологично. Когда-нибудь нужно будет поменять. Сокирко 31.10.02
                    */
                    if (!pAbstClause1->HasUnambiguousStrongRootWithoutWeakHomonyms())
                        return false;
                    break;
    }
	
	if( pAbstClause1->size() < 2 )
		return false;

	int iFirstWord = pAbstClause1->m_iFirstWord;
	bool bCoordConj =  
								(		(GetWords()[iFirstWord].m_strWord[0] == ',') 
									&&	m_Words[iFirstWord+1].m_bSimilarConj
								)
						||		m_Words[iFirstWord].m_bSimilarConj;
					
	if (!bCoordConj) 
		return false;

	return EncloseClauseAsWord(iNext, iClauseNum);
}
Пример #2
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;
}