/
bear
/
aot
Обзор
Документация
Войти
/
bear
/
aot
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Source/seman/Transfer/TranslateToEnglish.cpp
811 строк
21 KB
sokirko74
use exception in load dicitonaries
02 дек 2021, 11:25
02 дек 2021, 11:25
0d44bb9
Код
Авторство
О чём код?
#include "StdAfx.h" #include "EngSemStructure.h" #include "EngSynthes.h" bool CEngSemStructure::init_helper() { helper.text_kind = translate_helper::TEXT_HUD; helper.SetData(RusStr.m_pData); helper.init_private_lists(); return true; } void CEngSemStructure::CreateEngClauses() { m_Clauses.clear(); long EngClauseCount = 0; for (int i = 0; i < m_Nodes.size(); i++) { assert(m_Nodes[i].m_ClauseNo != -1); if (m_Nodes[i].m_ClauseNo + 1 > EngClauseCount) EngClauseCount = m_Nodes[i].m_ClauseNo + 1; } m_Clauses.resize(EngClauseCount); for (int i = 0; i < m_Clauses.size(); i++) { m_Clauses[i].Copy(RusStr.GetSemClause(i)); }; } void CEngSemStructure::IndexSemFets() { for (long NodeNo = 0; NodeNo < m_Nodes.size(); NodeNo++) { CSemPattern P; m_Nodes[NodeNo].m_NodeSemFets.clear(); // загружаем SF из словарной статьи if (m_Nodes[NodeNo].GetUnitNo() != ErrUnitNo) { P.InitSemPattern(GetRossHolder(m_Nodes[NodeNo].GetType()), m_Nodes[NodeNo].GetUnitNo(), 0, 0); if (P.LoadSemFromDict()) m_Nodes[NodeNo].m_NodeSemFets = GetIndexedSemFets(P, false, true); }; // если в словарной статье нет SF, тогда // загружаем SF их тезауруса if (m_Nodes[NodeNo].m_NodeSemFets.size() == 0) if (m_Nodes[NodeNo].RusNode != -1) InitThesSemFet(m_Nodes[NodeNo], RusStr.GetNode(m_Nodes[NodeNo].RusNode)); // если в тезаурусе нет SF, тогда // загружаем SF из русского узла if (m_Nodes[NodeNo].m_NodeSemFets.empty() && (m_Nodes[NodeNo].RusNode != -1) ) { const CSemNode& N = RusStr.GetNode(m_Nodes[NodeNo].RusNode); for (long i = 0; i < N.m_NodeSemFets.size(); i++) P.m_ActantSemFets.push_back(GetSemFetStr(N.m_NodeSemFets[i])); m_Nodes[NodeNo].m_NodeSemFets = GetIndexedSemFets(P, false, true); }; // добавочные статьи можно смело игнорировать }; }; void CEngSemStructure::TranslateActants(int iEngNode, int iClause) { std::vector<long> outRels; GetOutcomingRelations(iEngNode, outRels); for (int i = 0; i < outRels.size(); i++) { CSemRelation& semRel = m_Relations[outRels[i]]; if (m_Nodes[semRel.m_SourceNodeNo].m_ClauseNo != iClause) return; TranslateOneActant(outRels[i], iEngNode); if (m_Nodes[semRel.m_TargetNodeNo].m_bReached) continue; m_Nodes[semRel.m_TargetNodeNo].m_bReached = true; TranslateActants(semRel.m_TargetNodeNo, iClause); } } std::string CEngSemStructure::BuildSentence() { std::string sent; try { CEngSynthes EngSynthes(*this); sent = EngSynthes.BuildSentence(); } catch (exception& e) { return std::string(e.what()); } catch (...) { return "Unknown error in Synthes"; } return sent; } bool CEngSemStructure::Init() { try { m_Nodes.clear(); m_Relations.clear(); m_Nodes.clear(); m_Relations.clear(); m_LexFuncts.clear(); if (m_SemRelToGramCortegeMap.size() == 0) { FillSemRelToGramCortegeMap(); FillSemRelEquivs(); } init_helper(); } catch (...) { return false; } return true; } bool CEngSemStructure::WasInterpreted(long RusNodeNo) const { return find(m_InterpretedRusNodes.begin(), m_InterpretedRusNodes.end(), RusNodeNo) != m_InterpretedRusNodes.end(); } void CEngSemStructure::SetInterpreted(long RusNodeNo) { m_InterpretedRusNodes.push_back(RusNodeNo); } long CEngSemStructure::GetClauseFirstWordNo(long ClauseNo) const { long MinWordNo = 10000; for (long i = 0; i < m_Nodes.size(); i++) if (m_Nodes[i].m_ClauseNo == ClauseNo) if (m_Nodes[i].IsWordContainer()) if (m_Nodes[i].GetMinWordNo() < MinWordNo) MinWordNo = m_Nodes[i].GetMinWordNo(); return MinWordNo; } long CEngSemStructure::GetClauseLastWordNo(long ClauseNo) const { long MaxWordNo = 0; for (long i = 0; i < m_Nodes.size(); i++) if (m_Nodes[i].m_ClauseNo == ClauseNo) if (m_Nodes[i].IsWordContainer()) if (MaxWordNo < m_Nodes[i].GetMaxWordNo()) MaxWordNo = m_Nodes[i].GetMaxWordNo(); return MaxWordNo; } std::string CEngSemStructure::GetMorphologyOfNode(long NodeNo) const { if (m_Nodes[NodeNo].m_MainWordNo == -1) return GetNodeLemStr(NodeNo); const CEngSemWord& W = m_Nodes[NodeNo].m_Words[m_Nodes[NodeNo].m_MainWordNo]; std::string POS = " "; if (W.m_Poses != 0) { part_of_speech_t pos = GetOnePOS(W.m_Poses); if (pos != UnknownPOS) POS = std::string(m_pData->GetEngGramTab()->GetPartOfSpeechStr(pos)); }; std::string Result = Format("%s = %s %s", GetNodeLemStr(NodeNo).c_str(), POS.c_str(), m_pData->GetEngGramTab()->GrammemsToStr(W.GetAllGrammems()).c_str() ); if (W.GetTense() != zero_tn) { Result += std::string("\nTense = ") + std::string(W.m_bMorphologicalPassiveForm ? "PassiveForm " : "Active ") + GetTenseString(W.GetTense()) + std::string("\n"); }; if (W.m_TenseHistory.size() > 1) { Result += "\nTense History\n"; for (int i = 0; i < W.m_TenseHistory.size(); i++) { Result += GetTenseString(W.m_TenseHistory[i].m_Tense); Result += "\t"; Result += W.m_TenseHistory[i].m_Maker; Result += "\n"; }; }; if (W.m_bDoNotChangeForm) { Result += " DoNotChangeForm \n"; }; if (m_Nodes[NodeNo].GetArticle() != UnknownArticle) { Result += "\nArticle = " + ArticleStringByType(m_Nodes[NodeNo].GetArticle()) + "\n"; Result += "ArticleHistory = " + m_Nodes[NodeNo].GetArticleCauseHistory(); }; Result += "\nNotUseTo = " + std::string(m_Nodes[NodeNo].m_bNotUseTo ? "yes" : "no") + "\n"; return Result; }; void CEngSemStructure::AssertValidGraph() { CSemanticStructure::AssertValidGraph(); // проверка правильности всех WordNo for (int i = 0; i < m_Nodes.size(); i++) { int iMainWordNo = m_Nodes[i].m_MainWordNo; if (iMainWordNo == -1) continue; int iWordNo = m_Nodes[i].m_Words[iMainWordNo].m_WordNo; assert(iWordNo != -1); } // проверка всех ClauseNo for (int i = 0; i < m_Nodes.size(); i++) { assert((m_Nodes[i].m_ClauseNo != -1) && (m_Nodes[i].m_ClauseNo < m_Clauses.size())); }; }; void CEngSemStructure::InitSyntaxRelations() { for (long i = 0; i < m_Relations.size(); i++) if (IsSubjPattern(m_Relations[i])) m_Relations[i].m_SyntacticRelation = "subj"; else if (IsObjPattern(m_Relations[i]) && m_Relations[i].m_SyntacticRelation != "indir_obj") m_Relations[i].m_SyntacticRelation = "obj"; }; void CEngSemStructure::SetPositionOfChildrenByGrammems(long NodeNo, uint64_t Grammems, std::string Position) { std::vector<long> outRels; GetOutcomingRelations(NodeNo, outRels); for (int i = 0; i < outRels.size(); i++) { CSemRelation& semRel = m_Relations[outRels[i]]; if (m_Nodes[semRel.m_TargetNodeNo].GetGrammemsRich() & Grammems) { semRel.m_Position = Position; semRel.m_PosType = FromAlgorithmPosType; }; }; }; /* пример: статья "the...the" Ищем межклаузные стрелки с союзом, идем в статью, если там есть поле вида POSi = g : p, где i=1,2, g - анг. граммемы, p - позиция. Берем i-ый актант союза, ищем все его актанты, у которых есть граммемы g, проставляем им позицию p. */ void CEngSemStructure::SetPositionsFromConj() { for (long i = 0; i < m_Relations.size(); i++) { const CSynRealization& syn = m_Relations[i].m_SynReal; const CRossInterp& conj = syn.m_Conj; if (conj.m_DictType == EngObor) { for (long LeafId = 0; LeafId < 2; LeafId++) { std::vector<TCortege> Corteges; GetRossHolder(EngObor)->GetFieldValues("POS", conj.m_UnitNo, Corteges, 1, 0); for (long j = 0; j < Corteges.size(); j++) { TCortege C = Corteges[j]; if ((C.m_DomItemNos[0] == -1) || (C.m_DomItemNos[1] == -1) ) continue; std::string GrammemsStr = GetRossHolder(EngObor)->GetDomItemStrInner(C.m_DomItemNos[0]); GrammemsStr = "NOUN " + GrammemsStr; part_of_speech_t POS; grammems_mask_t Grammems; bool b = m_pData->GetEngGramTab()->ProcessPOSAndGrammemsIfCan(GrammemsStr.c_str(), &POS, &Grammems); if (!b) continue; std::string Position = GetRossHolder(EngObor)->GetDomItemStrInner(C.m_DomItemNos[1]); long NodeNo = (LeafId == 0) ? m_Relations[i].m_SourceNodeNo : m_Relations[i].m_TargetNodeNo; SetPositionOfChildrenByGrammems(NodeNo, Grammems, Position); }; } }; }; } /* Ищем отношение ЭЛЕКТ_ИГ типа ЭЛЕКТ(one, boy) и переводим его в английскую конструкцию one of the boy. Для этого надо числительное сделать хозяином именной группы. */ void CEngSemStructure::SetSelectiveRelations() { for (long RelNo = 0; RelNo < m_Relations.size(); RelNo++) if (m_Relations[RelNo].m_SyntacticRelation == _R("ЭЛЕКТ_ИГ")) { MoveIncomingRelations(m_Relations[RelNo].m_SourceNodeNo, m_Relations[RelNo].m_TargetNodeNo); MoveIncomingDopRelations(m_Relations[RelNo].m_SourceNodeNo, m_Relations[RelNo].m_TargetNodeNo); m_Nodes[m_Relations[RelNo].m_SourceNodeNo].m_SynReal.m_Preps = m_Nodes[m_Relations[RelNo].m_TargetNodeNo].m_SynReal.m_Preps; ReverseRelation(RelNo); SetSimpleEngPrep("of", -1, RelNo); m_Relations[RelNo].m_Position = ">>"; }; }; /* Если у глагола выражено более двух валентностей (суб, об и еще что-то) и у одной валентности есть придаточное определительное, а у другой нет, тогда валентность без определительного должна идти до валнтности с определительной. Например, I give the box which you like to you - плохо а лучше I give to you the box which you like */ void CEngSemStructure::SetLongRelations() { for (int NodeNo = 0; NodeNo < m_Nodes.size(); NodeNo++) { if (m_Nodes[NodeNo].m_NodeType == MNA) continue; if (IsAuxVerb(NodeNo)) continue; std::vector<long> outRels; GetOutcomingRelations(NodeNo, outRels); std::vector<int> ClauseRelNos; std::vector<int> InnerRelNos; for (int i = 0; i < outRels.size(); i++) if (!m_Relations[outRels[i]].m_bReverseRel && !IsRelBetweenClauses(m_Relations[outRels[i]]) ) if (IsSubj(m_Relations[outRels[i]])) { outRels.erase(outRels.begin() + i); i--; } else { std::vector<long> Rels; GetRelations(m_Relations[outRels[i]].m_TargetNodeNo, Rels); long j = 0; for (; j < Rels.size(); j++) if (IsRelBetweenClauses(m_Relations[Rels[j]])) break; if (j < Rels.size()) ClauseRelNos.push_back(outRels[i]); else InnerRelNos.push_back(outRels[i]); }; if ((ClauseRelNos.size() > 0) && (InnerRelNos.size() > 0) ) { for (int i = 0; i < ClauseRelNos.size(); i++) { m_Relations[ClauseRelNos[i]].m_Position = ">"; m_Relations[ClauseRelNos[i]].m_PosType = FromAlgorithmPosType; }; for (int i = 0; i < InnerRelNos.size(); i++) { m_Relations[InnerRelNos[i]].m_Position = ">>"; m_Relations[InnerRelNos[i]].m_PosType = FromAlgorithmPosType; }; } }; }; // непроинтерпретированный дательный падеж переводим предлогом to bool CEngSemStructure::TranslateCasesIfNeed(long NodeNo) { std::vector<long> Rels; GetIncomingRelations(NodeNo, Rels, false); if (Rels.size() != 0) return false; if (m_Nodes[NodeNo].m_SynReal.m_Preps.size() > 0) return false; if (m_Nodes[NodeNo].RusNode == -1) return false; const CSemNode& N = RusStr.GetNode(m_Nodes[NodeNo].RusNode); if (((N.GetGrammems() & rAllCases) != _QM(rDativ)) && ((N.GetGrammems() & rAllCases) != (_QM(rDativ) | _QM(rLocativ))) ) return false; SetSimpleEngPrep("to", NodeNo, -1); return true; }; std::string CEngSemStructure::GetInterfaceWordStr(const CSemNode* pNode, int WordNo) const { CEngSemNode& Node = *(CEngSemNode*)pNode; std::string L = Node.m_Words[WordNo].m_Word; if (Node.m_Words[WordNo].m_NumeralPrefix != "") L = Node.m_Words[WordNo].m_NumeralPrefix + "-" + L; if (!Node.m_Words[WordNo].m_PosleLog.m_PosleLog.empty()) { L += " ("; L += Node.m_Words[WordNo].m_PosleLog.m_PosleLog; L += ")"; } else if (Node.m_Words[WordNo].m_PosleLog.m_PosleLogPrep.m_DictType != NoneRoss) { L += " ("; L += GetRoss(Node.m_Words[WordNo].m_PosleLog.m_PosleLogPrep.m_DictType)->GetEntryStr(Node.m_Words[WordNo].m_PosleLog.m_PosleLogPrep.m_UnitNo); L += ")"; }; return L; }; void CEngSemStructure::GetColorAndWidthOfRelation(int RelNo, float& Width, std::string& Color) { if (m_Nodes[m_Relations[RelNo].m_SourceNodeNo].m_ClauseNo != m_Nodes[m_Relations[RelNo].m_TargetNodeNo].m_ClauseNo) { if (m_Relations[RelNo].m_bInterpreted) Color = "blue"; else Color = "darkcyan"; Width = 2; } else { if (m_Relations[RelNo].m_bInterpreted) Color = "red"; else Color = "darkgreen"; if (IsSubj(m_Relations[RelNo])) Width = 2; else Width = 1; } } bool CEngSemStructure::TranslateToEnglish() { try { Init(); CEnglishEquivMap mapRNodeToENode; m_SentenceMood = RusStr.m_SentenceMood; m_IndexedSemFets = RusStr.m_IndexedSemFets; m_bHasConjBut = RusStr.m_bHasConjBut; m_InterpretedRusNodes.clear(); // находим все английские эквиваленты FindEnglishEquivMain(mapRNodeToENode); ResetAllReachedFlags<CEngSemStructure>(*this); std::vector<long> Roots; RusStr.GetRoots(Roots); for (int i = 0; i < Roots.size(); i++) { SetInterpreted(Roots[i]); InterpretRusNodeAndItsChildren(mapRNodeToENode, Roots[i]); } MoveDopRelationsBack(*this); FilLexFunctRel(); PrintNodes(); CreateEngClauses(); PrintRelations(); //создаю строку для терминов, которые в русской структуре были //один словом. Такие термины интерпретируются либо полными аннглийским словарными статьями //из тезауруса, либо статьями-заглушками из АОСС. //В любом случае, у них должен не равен -1 СSemNode::m_TerminId. //Да.. аббревиатуры обрабатываются отдельно (translate_abbr_termin_node) for (int i = 0; i < m_Nodes.size(); i++) if ((m_Nodes[i].m_TerminId != -1) && !m_Nodes[i].m_ThesAbbrForm ) { const CThesaurus* Thes = helper.GetThes(m_Nodes[i].m_ThesaurusId); int TerminNo = Thes->GetTerminNoByTextEntryId(m_Nodes[i].m_TerminId); set_multiword_termin(i, &Thes->m_Termins[TerminNo], m_Nodes[i].m_ThesaurusId); } } catch (...) { ErrorMessage("An error occured on the interpretation"); return false; }; //* try { // Инициализируем перечень SF IndexSemFets(); // переводим актанты ResetAllReachedFlags<CEngSemStructure>(*this); m_InterpretedRusNodes.clear(); for (int ClauseNo = 0; ClauseNo < m_Clauses.size(); ClauseNo++) { std::vector<long> Roots; Roots.clear(); GetClauseRoots(ClauseNo, Roots); for (long i = 0; i < Roots.size(); i++) { m_Nodes[Roots[i]].m_bReached = true; TranslateActants(Roots[i], ClauseNo); } } } catch (...) { ErrorMessage("An error occured while translating valencies"); return false; }; try { // добавляем общие алгоритмы std::vector<long> algNodes; for (int i = 0; i < m_Nodes.size(); i++) RefineByNumeralMarks(i); for (int i = 0; i < m_Nodes.size(); i++) RefineSynRealMarks(i); for (int i = 0; i < m_Nodes.size(); i++) AddLexFuncNode(i); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyALG_AL1(algNodes[j]); for (int j = 0; j < m_Nodes.size(); j++) ApplyALG_AL3(j); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyNoRule(algNodes[j]); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyBeRule(algNodes[j]); for (int i = 0; i < m_Nodes.size(); i++) ApplyKeepRule(i); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyALG_it(algNodes[j]); //добавление словообразовательных граммем, AddFixedGrammemsToNode(); InitArticleField(); for (int i = 0; i < m_Nodes.size(); i++) ApplyComparativeRule(i); for (int i = 0; i < m_Nodes.size(); i++) ApplyAdjShortRule(i); PrintNodes(); for (int i = 0; i < m_Nodes.size(); i++) TranslateAdverbAdjectiveRule(i); PrintNodes(); PrintRelations(); for (int i = 0; i < m_Nodes.size(); i++) ApplyPredicativeRule(i); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyVerbToAdjRule(algNodes[j]); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ImpersonalVerb(algNodes[j]); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) InfinitiveAndIf(algNodes[j]); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyInvitatoryRule(algNodes[j]); GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyModalCopulRule(algNodes[j]); for (int i = 0; i < m_Nodes.size(); i++) ApplyTwoNegationsRule(i); //// // добавляем межклаузные алгоритмы GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) ApplyALG_compl_obj(algNodes[j]); TranslateClauseRels(); // после TranslateClauseRels приходится снова запускть InitArticleField из-за того, что // в TranslateClauseRels причастия обращаются в which-клаузу, которая влияет на артикль InitArticleField(); RefineEngCollocPreps(); RefineComparativeMNAwithPreps(); RefineUnknownRelsSynRel(); CorrectNodeNumByRelNum(); // "RUSETENSE" GetAlgNodes(algNodes); for (int j = 0; j < algNodes.size(); j++) { CEngSemNode& engNode = m_Nodes[algNodes[j]]; if (!engNode.IsWordContainer()) continue; if (engNode.RusNode == -1) continue; if (RusStr.GetNode(engNode.RusNode).IsTimeRossNode()) continue; EngVerbTenseEnum AVREM_Tense = handle_AVREM_field(algNodes[j], true, engNode.RusNode); if (AVREM_Tense != zero_tn) { engNode.m_Words[engNode.m_MainWordNo].SetTense(AVREM_Tense, _R("по полю RUSETENSE")); CorrectTenseByDictVerbFeatures(engNode); // "RESTR" "not_cont" } } // вопросительные предложения if (!HandleQuestionNode()) { for (long ClauseNo = 0; ClauseNo < m_Clauses.size(); ClauseNo++) { int iEngRoot = GetMainClauseRoot(ClauseNo); int iRusNode = m_Nodes[iEngRoot].RusNode; if (iRusNode == -1) continue; int iRusClau = RusStr.GetNode(iRusNode).m_ClauseNo; bool bIsQ = RusStr.IsQuestionClause(iRusClau); if (!bIsQ) continue; HandleQuestionClause(iEngRoot); } } } catch (...) { ErrorMessage("An error occured while applying algorithms"); return false; }; try { // ============== перводим тайм-группы ResetAllReachedFlags<CEngSemStructure>(*this); for (long i = 0; i < m_Nodes.size(); i++) // процедура удаляет узлы, поэтому нужно начать сначала if (translate_time_node(i)) i = -1; } catch (...) { ErrorMessage("An error occured while translating time-groups"); return false; }; //* // ============== переводим термины try { for (long i = 0; i < m_Nodes.size(); i++) // процедура удаляет узлы, поэтому нужно начать сначала if (translate_termin_node(i)) i = -1; for (int i = 0; i < m_Nodes.size(); i++) translate_abbr_termin_node(i); } catch (...) { ErrorMessage("An error occured while translating termins"); return false; }; // ============== переводим бинарным словарем примитивные узлы try { for (long i = 0; i < m_Nodes.size(); i++) translate_binary(i); } catch (...) { ErrorMessage("An error occured while browsing binary dictionary"); return false; }; //* try { //добавление словообразовательных граммем, для всех узлов (хотя //можно только для тех, которые недавно созданы) AddFixedGrammemsToNode(); ConvertClosedCollocToOpen(); CreateOneselfNodes(); for (long i = 0; i < m_Nodes.size(); i++) TranslateCasesIfNeed(i); InitSyntaxRelations(); SetPositionsFromConj(); HideCopul(); ReverseClauseRel(); // ApplySequenceOfTenseRule(); ApplyModalVerbTenseRule(); // "can" | "must" -> "be able"+(to) | "have"+(to) BuildAuxiliaryVerbs(); //Gri - удалим все позиции на связях, в которых я не уверен if (!IsConnected()) { for (int i = 0; i < m_Relations.size(); i++) { if (m_Relations[i].m_PosType != FromAlgorithmPosType) m_Relations[i].m_Position = ""; } } SetSelectiveRelations(); PrintRelations(); SetLongRelations(); } catch (...) { ErrorMessage("An error occured while applying post-algorithms"); return false; } PrintNodes(); AssertValidGraph(); return true; };