bool CWord::TryToPredictPatronymic() { THomonymPtr pHom = PredictAsPatronymic(); if (pHom.Get() != NULL) { pHom->SetNameType(Patronomyc); AddHomonym(pHom, false); return true; } return false; }
THomonymPtr CWord::PredictAsPatronymic() { THomonymBaseVector out; if (TMorph::PredictHomonyms(m_txt, out)) for (size_t i = 0; i < out.size(); ++i) { THomonymPtr pH = dynamic_cast<CHomonym*>(out[i].Get()); if (pH.Get() != NULL && pH->HasGrammem(gPatr)) return pH; } return NULL; }
int CWord::PutGztArticle(int iH, const TGztArticle& gzt_article, bool bClone) { CHomonym& h = GetRusHomonym(iH); bool has_aux_kw = h.HasAuxArticle(KW_DICT); if (!has_aux_kw && !h.HasGztArticle()) { h.PutGztArticle(gzt_article); return iH; } else if (bClone || has_aux_kw || h.GetGztArticle().GetType() != gzt_article.GetType()) { THomonymPtr pNewHom = h.Clone(); pNewHom->PutGztArticle(gzt_article); return AddRusHomonym(pNewHom); } else { YASSERT(h.HasGztArticle() && h.GetGztArticle().GetType() == gzt_article.GetType()); h.m_ExtraGztArticles.insert(gzt_article); return iH; } }
int CWord::PutAuxArticle(int iH, const SDictIndex& dicIndex, bool bCloneAnyWay) { CHomonym& h = GetRusHomonym(iH); bool has_gzt = dicIndex.m_DicType == KW_DICT && h.HasGztArticle(); if (has_gzt || h.m_DicIndexes[dicIndex.m_DicType] != -1) { TKeyWordType kwType = GlobalGramInfo->GetAuxKWType(dicIndex); if (!bCloneAnyWay && !has_gzt && GlobalGramInfo->HasArticle(h, SArtPointer(kwType), KW_DICT)) { h.m_KWtype2Articles[kwType].push_back(dicIndex); return iH; } else { THomonymPtr pNewHom = h.Clone(); pNewHom->PutAuxArticle(dicIndex); return AddRusHomonym(pNewHom); } } else { h.PutAuxArticle(dicIndex); return iH; } }
// return found (or newly made) homonym id static int FindOrMakeMultiwordHomonym(const CWordSequence& ws, CWord& word, TKeyWordType kwtype, THomonymGrammems grammems, THomonymPtr& res) { // use the content of CWordSequence.m_Lemmas as new homonym lemma Wtroka str = ws.GetLemma(); if (!str) str = word.GetLowerText(); TMorph::ToLower(str); int homId = -1; // search if we already have a multiword homonym with such text if (!FindBestHomonym(word, str, kwtype, grammems, homId)) { // create new homonym, if there is no ready one res = new CHomonym(TMorph::GetMainLanguage(), str); if (ws.HasAuxArticle()) res->PutAuxArticle(ws.GetAuxArticleIndex()); else res->PutGztArticle(ws.GetGztArticle()); homId = word.AddRusHomonym(res); } return homId; }
//if we already tried to predict then return what we predicted bool CWord::PredictAsSurname() { int iH = HasMorphNounWithGrammems_i(TGramBitSet(gSurname)); if (iH != -1) return !GetRusHomonym(iH).IsDictionary(); yvector<TSurnamePredictor::TPredictedSurname> out; if (!TMorph::PredictSurname(GetLowerText(), out)) return false; THomonymPtr pFirstHomonym = m_Homonyms[IterHomonyms().GetID()]; bool bFound = IsDictionary(); for (size_t i = 0; i < out.size(); i++) { TGrammarBunch forms; ToGrammarBunch(out[i].StemGrammar, out[i].FlexGrammars, forms); Wtroka lemma = out[i].Lemma; if (i == 0 && !bFound) pFirstHomonym->Init(lemma, forms, pFirstHomonym->IsDictionary()); else { THomonymPtr pClonedHomonym = pFirstHomonym->Clone(); pClonedHomonym->Init(lemma, forms, false); AddHomonym(pClonedHomonym, false); } } return true; }
THomonymPtr CHomonym::Clone() const { THomonymPtr pRes = new CHomonym(Lang); CopyTo(pRes.Get()); return pRes; }
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; }