Ejemplo n.º 1
0
bool RequiresSpace(const Wtroka& w1, const Wtroka& w2)
{
#define SHIFT(i) (ULL(1)<<(i))

    if(w1.length() == 1) {
        if (NUnicode::CharHasType(w1[0],
            SHIFT(Ps_START) | SHIFT(Ps_SINGLE_QUOTE) | SHIFT(Pi_SINGLE_QUOTE) |
            SHIFT(Ps_QUOTE) | SHIFT(Pi_QUOTE)))
          return false;
    }

    if(w2.length() == 1) {
          if (NUnicode::CharHasType(w2[0],
                  SHIFT(Pe_END) | SHIFT(Po_TERMINAL) | SHIFT(Pe_SINGLE_QUOTE) | SHIFT(Pf_SINGLE_QUOTE) |
                  SHIFT(Pe_QUOTE) | SHIFT(Pf_QUOTE)))
                return false;
    }

#undef SHIFT
    return true;
}
Ejemplo n.º 2
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;
}