bool THomonymInflector::FindInForms(const THomonymGrammems& forms, const TGramBitSet& grammems, TGramBitSet& resgram) { using NInfl::DefaultFeatures; using NInfl::TFeature; if (forms.HasForms()) { for (THomonymGrammems::TFormIter it = forms.IterForms(); it.Ok(); ++it) if (it->HasAll(grammems)) { resgram = *it; return true; } } else if (forms.IsIndeclinable() && DefaultFeatures().BitSet(TFeature::Case, TFeature::Number).HasAll(grammems)) { resgram = grammems; return true; } return false; }
SWordHomonymNum CMultiWordCreator::AddMultiWordInt(CWordSequence* ws, bool takeOnwership, const TGramBitSet& newPos, const CWordsPair& searchAreaWP) { SWordHomonymNum wh = ws->GetMainWord(); Wtroka stmp; SWordHomonymNum newWH; CWord* pNewWord = GetWordForMultiWord(*ws, stmp, newWH); pNewWord->m_SourceWords.SetPair(ws->FirstWord(), ws->LastWord()); TGramBitSet art_grammems; // output grammems of article Wtroka article_title; TKeyWordType article_type = NULL; if (ws->HasGztArticle()) { const TGztArticle& gzt_article = ws->GetGztArticle(); article_title = gzt_article.GetTitle(); article_type = gzt_article.GetType(); const NGzt::TMessage* lemma = gzt_article.GetLemmaInfo(); if (lemma != NULL) art_grammems = gzt_article.GetLemmaOutputGrammems(*lemma); } else if (ws->HasAuxArticle()) { const article_t* pArt = GlobalDictsHolder->GetAuxArticle(ws->GetAuxArticleIndex()); art_grammems = pArt->get_new_pos(); article_title = pArt->get_title(); article_type = pArt->get_kw_type(); } THomonymGrammems newGram; if (!ws->GetGrammems().Empty()) { newGram = ws->GetGrammems(); if (!newGram.HasForms() && wh.IsValid()) newGram.SetPOS(m_Words[wh].Grammems.GetPOS()); } else if (wh.IsValid() && HasToAddGrammemsFromMainWord(*ws)) newGram = m_Words[wh].Grammems; MergeGrammems(newGram, art_grammems, newPos); THomonymPtr pNewHom; if (pNewWord->IsMultiWord() && (pNewWord->GetSourcePair().Size() != 1 || !wh.IsValid())) { newWH.m_HomNum = FindOrMakeMultiwordHomonym(*ws, *pNewWord, article_type, newGram, pNewHom); YASSERT(newWH.IsValid()); } if (pNewHom.Get() == NULL) { if (!pNewWord->IsMultiWord()) { if (wh.IsValid()) newWH = wh; else { // just take the first homonym newWH.m_bOriginalWord = true; newWH.m_WordNum = pNewWord->GetSourcePair().FirstWord(); newWH.m_HomNum = pNewWord->IterHomonyms().GetID(); } } YASSERT(newWH.IsValid()); //часто бывает ситуация, когда мы вынуждены клонировать абсолютно одинаковые //омонимы, различающиеся только приписанными статьями из aux_dic, //в случае с geo_thesaurus.cxx это чревато порождением огромного количества омонимов //(боле 50 для "Петров"), тогда если статьи не отличаются друг от друга полем СОСТАВ //приписываемыми граммемами, ЧР и KWType, то мы омонимы не клонируем а дополнительные статьи //записываем в CHomonym::m_KWtype2Articles. Это происходит в CWord::PutArticleIndex. //если мы считаем, что найденные статьи для одного и того же омонима ничем не отличаются, //то главное слово для неотличающихся стаей у ws одно и то же и ему приписана //первая попавшаяся среди неразличимы статья //например статьи "_петрова_2" и "_петрова_3" для нас одинаковы (отличаются только ГЕО_ЧАСТЬ //а это неважно для парсера) и незачем плодить омонимы bool bCloneAnyway = (!newGram.Empty() && !(m_Words[newWH].Grammems == newGram)) || !GlobalDictsHolder->BuiltinKWTypes().IsGeo(article_type); if (ws->HasAuxArticle()) newWH.m_HomNum = m_Words.GetWord(newWH).PutAuxArticle(newWH.m_HomNum, ws->GetAuxArticleIndex(), bCloneAnyway); else newWH.m_HomNum = m_Words.GetWord(newWH).PutGztArticle(newWH.m_HomNum, ws->GetGztArticle(), bCloneAnyway); } YASSERT(newWH.IsValid()); AddFoundArticle(article_type, article_title, newWH, searchAreaWP); CHomonym& h = m_Words[newWH]; h.SetSourceWordSequence(ws); if (!newGram.Empty()) h.SetGrammems(newGram); if (takeOnwership) { if (!ws->HasLemmas()) NormalizeMultiWordHomonym(pNewWord, &h); m_wordSequences.push_back(ws); } return newWH; }