예제 #1
0
void CMultiWordCreator::GetFoundWordsInPeriod(const SArtPointer& artP, yvector<SWordHomonymNum>& foundWords,
                                              const CWordsPair& wp) const
{
    foundWords.clear();

    //сначала пытаемся найти среди KwType, которые уже искались на всем предложении, те, которые
    //входят в наш отрезок

    if (artP.HasKWType()) {
        ymap<TKeyWordType, yvector<SWordHomonymNum> >::const_iterator it = m_KW2Words.find(artP.GetKWType());
        if (it != m_KW2Words.end()) {
            const yvector<SWordHomonymNum>& whs = it->second;
            for (size_t i = 0; i < whs.size(); i++) {
                CWord& w = m_Words.GetWord(whs[i]);
                if (wp.Includes(w.GetSourcePair()))
                    foundWords.push_back(whs[i]);
            }
        }
    }

    if (!foundWords.empty())
        return;

    //пытаемся найти среди StrType, которые уже искались на всем предложении, те, которые
    //входят в наш отрезок
    if (artP.HasStrType()) {
        ymap<Wtroka, yvector<SWordHomonymNum> >::const_iterator it = m_Title2Words.find(artP.GetStrType());
        if (it != m_Title2Words.end()) {
            const yvector<SWordHomonymNum>& whs = it->second;
            for (size_t i = 0; i < whs.size(); ++i) {
                CWord& w = m_Words.GetWord(whs[i]);
                if (wp.Includes(w.GetSourcePair()))
                    foundWords.push_back(whs[i]);
            }
        }
    }

    if (!foundWords.empty())
        return;

    //теперь проходим по запомненным отрезкам, для которых хранятся все найденные MultiWords
    ymap<CWordsPair, yvector<SWordHomonymNum> >::const_iterator it = m_FoundWordsByPeriod.find(wp);
    if (it != m_FoundWordsByPeriod.end()) {
        const yvector<SWordHomonymNum>& whs = it->second;
        for (size_t i = 0; i < whs.size(); i++) {
            const CHomonym& h = m_Words[whs[i]];
            if (h.HasArticle(artP, KW_DICT))
                foundWords.push_back(whs[i]);
        }
    }
}
예제 #2
0
//выдает абсолютный адрес найденной ситуации цитирования
CWordsPair CQuotesFinder::GetWordIndexOfQuoteSituation(const SValenciesValues& VerbCommunic, int SentNo) const
{
    CWordsPair PairToSearch;
    PairToSearch.SetPair(-1,-1);
    const CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);
    if (VerbCommunic.m_NodeWH.IsValid()) {
        // если валидна вершина,берем координаты веришины
        PairToSearch = pSentPrc->m_Words.GetWord(VerbCommunic.m_NodeWH).GetSourcePair();
    } else {
        // иначе  берем координаты первой валентности
        if (VerbCommunic.m_values.empty() || !VerbCommunic.m_values[0].m_Value.IsValid())
            return CWordsPair();
        PairToSearch = pSentPrc->m_Words.GetWord(VerbCommunic.m_values[0].m_Value).GetSourcePair();
    };
    return PairToSearch;
};
예제 #3
0
// он сказал : "У меня было право - я исполнял обязанности премьера" .
// он сказал : " У меня было право - я исполнял обязанности премьера" .
bool CQuotesFinder::TryDirectSpeechWithColon(const SValenciesValues& VerbCommunic, int SentNo)
{
    if (!VerbCommunic.m_NodeWH.IsValid())
        return false;

    CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);

    const CWordsPair PairToSearch = GetWordIndexOfQuoteSituation(VerbCommunic, SentNo);
    if (PairToSearch.FirstWord() == -1) return false;

    const_clause_it min_it =  GetSentPrc(SentNo)->GetClauseStructureOrBuilt().GetMinimalClauseThatContains(PairToSearch);

    const CClauseVariant& ClauseVariant = pSentPrc->GetClauseStructureOrBuilt();
    if (min_it == ClauseVariant.GetEndClause())
        return false;

    const CClause* pEnclosedClause = ClauseVariant.GetIncludedClauseR(min_it);
    CWordsPair QuoteValuePair;
    if (pEnclosedClause && pEnclosedClause->FirstWord() != 0) {
        const Wtroka& WordStr = pSentPrc->getWordRus(pEnclosedClause->FirstWord() - 1)->GetText();
        if (WordStr != COLON &&
            (WordStr != Wtroka::FromAscii("\"") || pEnclosedClause->FirstWord() < 2 ||
             pSentPrc->getWordRus(pEnclosedClause->FirstWord() - 2)->GetText() != COLON))
            return false;

        QuoteValuePair = *pEnclosedClause;
    } else {
        int LastWord = (**min_it).LastWord();
        const Wtroka& WordStr = pSentPrc->getWordRus(LastWord)->GetText();
        if (WordStr != COLON &&
            (WordStr != Wtroka::FromAscii("\"") || LastWord < 1 ||
             pSentPrc->getWordRus(LastWord - 1)->GetText() != COLON))
            return false;

        if (LastWord + 1 == (int)pSentPrc->getWordsCount())
            return false;
        QuoteValuePair = CWordsPair(LastWord+1, (int)pSentPrc->getWordsCount() - 1);
    }
    yvector<SFactAddress> FioInQuotes;
    AddFiosFromPeriod(SentNo, QuoteValuePair, FioInQuotes);
    return AddQuoteFact(VerbCommunic, pSentPrc, pSentPrc->ToString(QuoteValuePair), FioInQuotes, SLeadInfo());

}
예제 #4
0
void CMultiWordCreator::AddFoundArticle(TKeyWordType article_type, const Wtroka& article_title,
                                        const SWordHomonymNum& word, const CWordsPair& searchAreaWP)
{
    if (searchAreaWP.IsValid()) {
        m_FoundWordsByPeriod[searchAreaWP].push_back(word);
        return;
    }

    //m_Words[word].Lock();
    if (article_type != NULL)
        m_KW2Words[article_type].push_back(word);

    m_Title2Words[article_title].push_back(word);
};
예제 #5
0
void CQuotesFinder::AddFiosFromPeriod(int SentNo, const CWordsPair& Pair, yvector<SFactAddress>& FioInQuotes)
{
    CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);
    yvector<SWordHomonymNum>* fioWHs = pSentPrc->GetMultiWordCreator().GetFoundWords(GlobalDictsHolder->BuiltinKWTypes().Fio, KW_DICT);
    if (fioWHs)
        for (size_t i=0; i < fioWHs->size(); i++) {
            const CHomonym& pHom =  pSentPrc->m_Words[(*fioWHs)[i] ];
            if (Pair.Includes(*pHom.GetSourceWordSequence())) {
                SFactAddress A;
                A.m_HomNum = (*fioWHs)[i].m_HomNum;
                A.m_WordNum = (*fioWHs)[i].m_WordNum;
                A.m_bOriginalWord = (*fioWHs)[i].m_bOriginalWord;
                A.m_iSentNum = SentNo;
                FioInQuotes.push_back(A);
            }
        }
}
예제 #6
0
// обычно функция возвращает clause->ToString(),
// если в клаузе есть открывающая кавычка, а нет закрывающей, тогда  функция добавляет к результату
// все слова до закрывающей кавычки
Wtroka CQuotesFinder::FindRightQuoteIfHas(const CWordsPair& PeriodToPrint, int SentNo,
                                          const CWordsPair& GroupToExclude, yvector<SFactAddress>& FioInQuotes)
{
    FioInQuotes.clear();
    CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);
    yset<int> QuoteWords;
    Wtroka ClauseStr;
    static const Wtroka COMMA = Wtroka::FromAscii(",");
    for (int i = PeriodToPrint.FirstWord(); i <=  PeriodToPrint.LastWord(); i++) {
        const CWord& w = pSentPrc->m_Words.GetOriginalWord(i);
        if (!GroupToExclude.Contains(i) &&
            !(GroupToExclude.Contains(i - 1) && w.GetText() == COMMA) &&
            !(GroupToExclude.Contains(i + 1) && w.GetText() == COMMA)) {
            ClauseStr += w.GetOriginalText() + ' ';
            QuoteWords.insert(i);
        }
    }

    size_t index = ClauseStr.find('"');
    if (index != Wtroka::npos && ClauseStr.rfind('"') == index) {
        yset<int> AddQuoteWords;
        Wtroka Add;
        // если только одна кавычка, то пойдем искать вторую кавычку
        int i;
        for (i = PeriodToPrint.LastWord()+1; i < (int)pSentPrc->getWordsCount(); i++) {
            const CWord& w = pSentPrc->m_Words.GetOriginalWord(i);
            if (!GroupToExclude.Contains(i)) {
                Add += w.GetOriginalText() + ' ';
                AddQuoteWords.insert(i);
            }
            if (w.HasCloseQuote())
                break;
        }
        if (i != (int)pSentPrc->getWordsCount()) {
            ClauseStr += ' ';
            ClauseStr += Add;
            QuoteWords.insert(AddQuoteWords.begin(), AddQuoteWords.end());
        }

    }

    AddFios(SentNo, QuoteWords, FioInQuotes);

    return ClauseStr;
};
예제 #7
0
// проверяет, содержит ли ситуация VerbCommunic прямую речь в качестве актанта-клаузы, примеры:
// "Я счастлив", - сказал Петя.
// "Я счастлив. Я очень счастлив", - сказал Петя.
// "Я счаcтлив, - сказал Петя. - Я очень счастлив!"
bool CQuotesFinder::TryDirectSpeechWithDashes(const SValenciesValues& VerbCommunic, int SentNo)
{
    if (!VerbCommunic.m_NodeWH.IsValid())
        return false;

    CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);

    const CWordsPair PairToSearch = GetWordIndexOfQuoteSituation(VerbCommunic, SentNo);
    if (PairToSearch.FirstWord() == -1) return false;

    int EndDirectSpeech = PairToSearch.FirstWord();

    {
        bool bFound = false;
        // ищем тире  на расстоянии 5 слов от глагола
        for (int i=EndDirectSpeech-1;  i>0 && EndDirectSpeech-i<5; i--) {
            if (pSentPrc->getWordRus(i)->IsDash()) {
                EndDirectSpeech = i;
                bFound = true;
                break;
            }
        }

        if (!bFound)
            return false;
    }

    EndDirectSpeech--;
    if (EndDirectSpeech < 0 ||!pSentPrc->getWordRus(EndDirectSpeech)->IsComma())
        return false;

    EndDirectSpeech--;
    bool bHasCloseQuote = true;
    if (EndDirectSpeech < 0 ||!pSentPrc->getWordRus(EndDirectSpeech)->HasCloseQuote()) {
        bHasCloseQuote = false;
        EndDirectSpeech ++;
    }

    yvector<SFactAddress> FioInQuotes;
    Wtroka QuoteStr;
    SLeadInfo LeadInfo;
    LeadInfo.m_iFirstSent = SentNo;
    LeadInfo.m_iLastSent = SentNo;

    if (FindOpenQuoteInThisSentence(SentNo, EndDirectSpeech, QuoteStr, FioInQuotes)) {
    } else {
        // ищем открывающую кавычку в другом предложении
        int StartSentNo = FindBeginQuote(SentNo);
        if (StartSentNo == -1)
            return false;
        LeadInfo.m_iFirstSent = StartSentNo;
        for (int i=StartSentNo; i+1<=SentNo; i++) {
            CSentenceRusProcessor* pSnt = GetSentPrc(i);
            QuoteStr += pSnt->ToString();
            QuoteStr += ' ';
            AddFiosFromPeriod(i, CWordsPair(0, (int)pSnt->getWordsCount() - 1),FioInQuotes);
        }
        LeadInfo.m_iLastSent = SentNo;
        CWordsPair p(0, EndDirectSpeech);
        QuoteStr += pSentPrc->ToString(p);
        AddFiosFromPeriod(SentNo, p, FioInQuotes);
    }

    if (!bHasCloseQuote) {
        // берем клаузу
        const_clause_it min_it = GetSentPrc(SentNo)->GetClauseStructureOrBuilt().GetMinimalClauseThatContains(PairToSearch);
        const CClauseVariant& ClauseVariant = pSentPrc->GetClauseStructureOrBuilt();
        if (min_it == ClauseVariant.GetEndClause())
            return false;

        // проверяем, что клауза с  ситуацией в предложении последняя
        if ((**min_it).LastWord()+1 == (int)pSentPrc->getWordsCount()) {
            // ищет закрывающую кавычку в следующем предложении
            if (!FindCloseQuoteInNextSentences(SentNo+1, 0, QuoteStr, FioInQuotes, LeadInfo))
                return false;
        } else if (!FindCloseQuoteInNextSentences(SentNo, (**min_it).LastWord(), QuoteStr, FioInQuotes, LeadInfo))
            return false;
    }

    return AddQuoteFact(VerbCommunic, pSentPrc, QuoteStr, FioInQuotes, LeadInfo);
}
예제 #8
0
// проверяет, содержит ли ситуация VerbCommunic косвенную речь в качестве актанта-клаузы. Примеры:
// "Петров сказал, что мы уходим в Яндекс."
// По словам Сергея Крапина , я уехал
// Она призналась , что "придумали проект наружной рекламы , но притормозили его , не захотев оказаться" .
bool CQuotesFinder::TryIndirectSpeech(const SValenciesValues& VerbCommunic, int SentNo)
{
    CWordsPair PairToSearch = GetWordIndexOfQuoteSituation(VerbCommunic, SentNo);
    if (PairToSearch.FirstWord() == -1) return false;

    const_clause_it min_it = GetSentPrc(SentNo)->GetClauseStructureOrBuilt().GetMinimalClauseThatContains(PairToSearch);
    CSentenceRusProcessor* pSentPrc = GetSentPrc(SentNo);
    const CClauseVariant& ClauseVariant = pSentPrc->GetClauseStructureOrBuilt();
    if (min_it == ClauseVariant.GetEndClause())
        return false;

    // пропускаем непервые клаузы, которые заканчиваются на тире, поскольку, это может быть только прямая речь.
    if ((**min_it).FirstWord() != 0 && pSentPrc->getWordRus((**min_it).LastWord())->GetText() == Wtroka::FromAscii("-"))
        return false;

    // вычисляем союз по названию статьи, например, из "_глагол_со_чтобы" получаем "чтобы"
    Wtroka strValencySubConj;
    {
        DECLARE_STATIC_RUS_WORD(kChto, "что");
        DECLARE_STATIC_RUS_WORD(kChtoby, "чтобы");
        Wtroka t = VerbCommunic.m_pArt->get_title();
        if (t.length() > 4 && t[t.length() - 4] == '_' && t.has_suffix(kChto))
            strValencySubConj = kChto;
        else if (t.length() > 6 && t[t.length() - 6] == '_' && t.has_suffix(kChtoby))
            strValencySubConj = kChtoby;
    }
    // если справа  стоит клауза со "что"
    if (!strValencySubConj.empty()) {
        yvector<const CClause*> SubClauses;
        ClauseVariant.GetIncludedClauses(min_it, SubClauses);
        std::sort(SubClauses.begin(), SubClauses.end(), LessBySize);
        {
            // берем первую справа
            const_clause_it next_it;
            ClauseVariant.GetNeighbourClauseR(min_it, next_it);
            if (next_it != ClauseVariant.GetEndClause())
                SubClauses.push_back(*next_it);
        }
        // берем вложенную клаузу справа (это лучший вариант)
        {
            const CClause* pSubClause = ClauseVariant.GetIncludedClauseR(min_it);
            if (pSubClause) SubClauses.push_back(pSubClause);
        }

        for (int i=SubClauses.size()-1; i >=0; i--) {
            const CClause* pSubClause = SubClauses[i];
            if (pSubClause->FromRight(PairToSearch))
                for (int ConjNo=0; ConjNo < pSubClause->GetConjsCount(); ConjNo++) {
                    const CHomonym& Conj = pSubClause->GetConj(ConjNo);
                    const article_t* piConjArt = GlobalDictsHolder->GetAuxArticle(Conj, CONJ_DICT);
                    if (piConjArt->get_title().substr(0, strValencySubConj.length()) == strValencySubConj) {
                        yvector<SFactAddress> FioInQuotes;
                        Wtroka QuoteStr = FindRightQuoteIfHas(*pSubClause, SentNo, CWordsPair(), FioInQuotes);
                        if (AddQuoteFact(VerbCommunic, pSentPrc, QuoteStr, FioInQuotes, SLeadInfo()))
                            return true;
                    }
                };
        }
    }

    // если клауза является вводной
    DECLARE_STATIC_RUS_WORD(kPo_slovam_Ivanova, "по_словам_иванова");
    DECLARE_STATIC_RUS_WORD(kKak, "как");
    if  ((VerbCommunic.m_pArt->get_title() == kPo_slovam_Ivanova &&  (*min_it)->HasType(Parenth)) ||
    // или использована с союзом "как", например, "как рассказал Петров, мы уже ушли"
         (pSentPrc->getWordRus((*min_it)->FirstWord())->FindLemma(kKak) && ClauseVariant.GetIncludedClauseL(min_it) == 0)) {
        // если вводная калуза стоит на первом месте и в предложении нет других клауз, тогда берем
        // все предложение начиная от конца вводной клаузы до
        if ((**min_it).FirstWord() == 0) {
            yvector<SFactAddress> FioInQuotes;
            Wtroka QuoteStr = FindRightQuoteIfHas(CWordsPair((**min_it).LastWord(), pSentPrc->getWordsCount() - 1),
                                                  SentNo, **min_it, FioInQuotes);
            if (AddQuoteFact(VerbCommunic, pSentPrc, QuoteStr, FioInQuotes, SLeadInfo()))
                return true;

        };
        // берем главную клаузу
        const CClause* pMainClause = ClauseVariant.GetMainClause(min_it);
        if (!pMainClause) {
            const_clause_it next_it;
            ClauseVariant.GetNeighbourClauseR(min_it, next_it);
            if (next_it != ClauseVariant.GetEndClause())
                pMainClause = *next_it;

        }
        if (pMainClause) {
            // печатаем главную клаузу без вложенной
            yvector<SFactAddress> FioInQuotes;
            Wtroka QuoteStr = FindRightQuoteIfHas(*pMainClause, SentNo, **min_it, FioInQuotes);
            if (AddQuoteFact(VerbCommunic, pSentPrc, QuoteStr,FioInQuotes, SLeadInfo()))
                return true;
        }
    }

    return false;
}