Ejemplo n.º 1
0
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());
	
}
Ejemplo n.º 2
0
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;
                }
    }
}