Beispiel #1
0
CGerSyntaxOpt :: CGerSyntaxOpt (MorphLanguageEnum langua) : CSyntaxOpt(langua)
{
	m_SimilarNPGroupType = GetSyntaxGroupOrRegister("NP_SIMIL");
	m_PluralMask = _QM(gPlural);
	m_SingularMask = _QM(gSingular);
	m_IndeclinableMask = 0;
	m_GenNounGroupType =  gGEN_NOUN;
	m_PrepNounGroupType=    gPREP_NOUN;
	m_DirObjGroupType=  gDIR_OBJ;
	m_NPGroupType=  gNOUN_GR;
	m_NounAdjGroupType=  gNOUN_ADJ;
	m_NameGroupType = gFAMILIE_GROUP;
	m_OborotGroupType = gOBOROTS;
	m_WWWGroupType = gWEB_ADDR;
	m_KEYBGroupType = gKEYB;
	m_SubjRelation = gSUBJ;
	m_RusParenthesis = UnknownPartOfSpeech;
	m_Preposition = gPRP;
	m_Conjunction = gKON;


	m_DisruptConjRelation = gDISRUPT_CONJ_RELATION;
	m_DisruptConjGroupType = gDISKONT_KONJ;
	m_InfintiveClauseType = INFINITIVSATZ_T;


	for (size_t i=0; i < gSyntaxGroupTypesCount; i++)
		m_SyntaxGroupTypes.push_back(gSyntaxGroupTypes[i]);

	m_pAdjPrp = new StringVector;
}
Beispiel #2
0
bool CRusSentence::IsAdjDeclination (const CSynHomonym& H) const
{
	if (!H.IsMorphNoun()) return false;
	if (H.m_strLemma.length() < 3)  return false;
	if (H.m_lPradigmID == -1) return false;
	string suffix = H.m_strLemma.substr(H.m_strLemma.length()-2);
	bool bMasc = (suffix == "»…") ||  (suffix == "џ…");
	bool bFem = (suffix == "јя") ||  (suffix == "яя");
	if (!bMasc && !bFem) return false;

	CFormInfo Info;
	GetOpt()->GetLemmatizer()->CreateParadigmFromID(H.m_lPradigmID, Info);
	for (long k=0; k < Info.GetCount(); k++)
	{
		string Ancode = Info.GetAncode(k);
		QWORD  g = GetRusGramTab()->GetAllGrammems(Ancode.c_str());
		if (  g & _QM(rSingular) )
			if ( g & _QM(rGenitiv) )
			{
				string Form = Info.GetWordForm(k);
				int l = Form.length();
				if (l < 3) return false;
				if (bMasc)
					return		(Form.substr(l-3) == "≈√ќ")
							||	(Form.substr(l-3) == "ќ√ќ");
				else
					return		(Form.substr(l-2) == "ќ…")
							||	(Form.substr(l-2) == "≈…");
			};
	};
	return false;		
};
Beispiel #3
0
bool CEngSynthes::try_pronoun_node(int node_no)
{
	if(E.m_Nodes[node_no].IsAbstract() || !node_is_pronoun(node_no)) return false;
	if(E.m_Nodes[node_no].m_Words.size() != 1) return false;
	CEngSemWord &EngWord = E.m_Nodes[node_no].m_Words[0];


	bool is_norm  = false;
	int rel = get_in_rel(node_no);
	if (rel != -1)
	  if (E.m_Nodes[E.m_Relations[rel].m_SourceNodeNo].m_NodeType == MNA)
		rel = get_in_rel(E.m_Relations[rel].m_SourceNodeNo);

	//  если местоимение - подлежащее или стоит в именительном падеже, то это номинатив,
	// иначе его нужно преобразовать в объектную форму.
	if (rel != -1 && is_subj_rel(rel))	is_norm = true;
	if (EngWord.HasOneGrammem(eNominative))	is_norm = true;
	
	
	if (lemma_is_demonstrative_pronoun (EngWord.m_Lemma))
	{
		long ParadigmId = helper.GetParadigmIdByLemma(morphEnglish, EngWord.m_Lemma,  ePN_ADJ);
		// создаем множественное число 
		if (ParadigmId != -1)
			if  (E.m_Nodes[node_no].GetGrammemsRich() & _QM(eSingular) )
		     EngWord.m_Word = helper.create_form_by_id(ParadigmId, _QM(eSingular));
			else
			 EngWord.m_Word = helper.create_form_by_id(ParadigmId, _QM(ePlural));
	}
	else
	if (!is_norm)
	{
		long ParadigmId = helper.GetParadigmIdByLemma(morphEnglish, EngWord.m_Lemma, ePN);
		// не у всех местоимений есть объектная форма
		if (ParadigmId != -1)
		 EngWord.m_Word = helper.create_form_by_id(ParadigmId, _QM(eObjectCase));
	};

	if ( EngWord.HasOneGrammem(ePossessive) )
		set_possessive(EngWord);

	if(EngWord.m_Word == "i") EngWord.m_Word= "I";


	Res(node_no).m_Article = ZeroArticle;
	Res(node_no).m_WordForms.push_back(EngWord.m_Word);

	// sons are here
	vector<long > rels;
	get_out_rels(node_no, rels);
	for(int i = 0; i < rels.size(); i++){
		translate_node(E.m_Relations[rels[i]].m_TargetNodeNo);
	}	

	handle_rel_operators(node_no);
	return true;
}
Beispiel #4
0
bool MixedGleiche (const CAgramtabLine* noun, const CAgramtabLine* adj) 
{	
    if (	((adj->m_Grammems & _QM(gAdjektiveMitUnbestimmte)) == 0) 
		&&	((adj->m_Grammems & _QM(gPossessiv)) == 0) 	
		)
		return false;

	return     GenderNumberCaseGerman(noun, adj);
};
Beispiel #5
0
void CEngSemStructure::CorrectNodeNumByRelNum()
{
	for( int i=0; i<m_Relations.size(); i++ )
	{
		int iSrc = m_Nodes[m_Relations[i].m_SourceNodeNo].m_ClauseNo;
		int iTrg = m_Nodes[m_Relations[i].m_TargetNodeNo].m_ClauseNo;
		if( iSrc != iTrg )
			continue;
		if( !m_Relations[i].m_bInterpreted )
			continue;

		int iNode1,iNode2;
		if( m_Relations[i].m_bReverseRel )
		{
			iNode1 = m_Relations[i].m_TargetNodeNo;
			iNode2 = m_Relations[i].m_SourceNodeNo;
		}
		else
		{
			iNode1 = m_Relations[i].m_SourceNodeNo;
			iNode2 = m_Relations[i].m_TargetNodeNo;
		}

		CEngSemNode& Node1 = m_Nodes[iNode1];
		CEngSemNode& Node2 = m_Nodes[iNode2];

		if( Node2.GetType()!=NoneRoss && Node2.GetUnitNo()!=ErrUnitNo &&
			GetRossHolder(Node2.GetType())->HasFieldValue("RESTR","ед",Node2.GetUnitNo()) )
		{
			if( Node1.m_MainWordNo!=-1 && Node1.m_Words[Node1.m_MainWordNo].m_Lemma=="many" )
			{
				CEngSemNode newNode;
				CreateSimpleEnglNodeByOldNode("much",newNode,0,false,Node1);
				m_Nodes[iNode1] = newNode;
			}
		}
		else
		{
			if( m_Nodes[iNode2].m_MainWordNo == -1 )
				continue;
			CEngSemWord &word = m_Nodes[iNode2].m_Words[m_Nodes[iNode2].m_MainWordNo];

			if( IsGramFet(m_Relations[i],"NP_sg") )
			{
				word.SetFormGrammems((word.GetFormGrammems() & ~eAllNumbers) | _QM(eSingular));
				continue;
			}
			if( IsGramFet(m_Relations[i],"NP_pl") )
			{
				word.SetFormGrammems((word.GetFormGrammems() & ~eAllNumbers) | _QM(ePlural));
				continue;
			}
		}
	}
}
Beispiel #6
0
/*
Функция вставляет узел "сам" или "один" и проводит отношения ASPECT к нему для всех потециальных подлежащих. Если ни одного отношения не удалось провести, 
 тогда возвращаем ложь.
 Между подлежащим и узлом сам проверяется согласование.
*/
bool CRusSemStructure::InsertSAMNode(long ClauseNo, CRusSemNode& SamNode)
{
  /*
    если ничего вставлять не надо, выйдем с истиной 
  */
  if (SamNode.m_Words.size() == 0) return true;

  long SamNodeNo = InsertNode (SamNode);
  bool bResult = false;

  for (long i=0; i < m_Nodes.size(); i++)
   if ( IsInClause(i, ClauseNo) )
   {
	   CRelSet R = GetIncomingRelations(i, false);
	   for (long l=0; l < R.m_RelsCount; l++)
		if ( m_Relations[R.m_Rels[l]].m_SyntacticRelation == "подл" )
			// проверяем согласование по числу/роду
		  if (    (   (   (_QM(rPlural) | _QM(rSingular))
			            & SamNode.GetGrammems()
			            & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems()
					  )> 0
				  )
               && ( ( (   rAllGenders 
			          & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems()
					  & SamNode.GetGrammems() ) > 0
			         )
			      || (
			          (  rAllGenders 
			          & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems())  == 0
			        )
				  )
			 )
		  {	
			AddRelation(CRusSemRelation(CValency("ASPECT", A_C), m_Relations[R.m_Rels[l]].m_SourceNodeNo,    SamNodeNo,   ""));			
			// оно должно быть реверсивным, чтобы не отличаться от простых 
			// наречий, чтобы занять правильное место в англ. предложении.
			m_Relations[m_Relations.size()-1].m_bReverseRel = true;
			m_DopRelations.push_back(CRusSemRelation(CValency("THESAME", A_C),  SamNodeNo,  m_Relations[R.m_Rels[l]].m_TargetNodeNo,  "анафора"));			
			bResult = true;
		  }
         else    
		  {
			 // удаляем субъектную стрелку, которая не  согласовалась со словом "САМ"
			 EraseRelation(R.m_Rels[l]); 
			 // получаем новый набор выходящих отношений
			 R = GetIncomingRelations(i, false);
			 l=-1;
		  };
	};
		  
 return bResult;	
};
Beispiel #7
0
// строит по русским граммемам набор английских граммем, содержащий только граммемы числа
void TransferPersonGrammems (const CSemNode& RusNode,  CEngSemWord& EngWord)
{
	EngWord.SetFormGrammems(EngWord.GetFormGrammems() & ~eAllPersons);

	if (RusNode.GetGrammems() & _QM( rFirstPerson) )
		EngWord.AddFormGrammem( eFirstPerson);
	else
	if (RusNode.GetGrammems() & _QM( rSecondPerson) )
		EngWord.AddFormGrammem( eSecondPerson);
	else
	   if (RusNode.GetGrammems() & _QM( rThirdPerson) )
		EngWord.AddFormGrammem( eThirdPerson);
};
Beispiel #8
0
void TransferGrammems (const CSemNode& RusNode, CEngSemNode& EngNode, string CallingFunc)
{
	TransferTimeGrammems(RusNode, EngNode, CallingFunc);
	if (EngNode.m_MainWordNo != -1)
	{
	  TransferNumberGrammems(RusNode, EngNode.m_Words[EngNode.m_MainWordNo]);
	  TransferPersonGrammems (RusNode, EngNode.m_Words[EngNode.m_MainWordNo]);
  
	};
	// установка сравнительной  степени
	if(RusNode.GetGrammems() & _QM( rComparative))
		EngNode.AddOneGrammemRich(eComparativ);

	// установка превосходной степени
	if(RusNode.GetGrammems() & _QM( rSuperlative))
		EngNode.AddOneGrammemRich(eSupremum);

   // установка одушевленности 
	if (RusNode.HasOneGrammem( rAnimative)  && !RusNode.HasOneGrammem( rNonAnimative))
			EngNode.AddOneGrammemRich( eAnimative);
	else
		if (!RusNode.HasOneGrammem( rAnimative)  && RusNode.HasOneGrammem( rNonAnimative))
			EngNode.DeleteGrammemsRich( _QM( eAnimative)  );

   if ( RusNode.GetGrammems() & ( _QM( rSurName) |  _QM( rName) | _QM( rPatronymic)) )
   {
	   EngNode.AddOneGrammemRich( eProper);
	  
   };
   if ( RusNode.HasOneGrammem(rToponym) )
   {
	   EngNode.AddOneGrammemRich( eGeographics );
	  
   };

   EngNode.DeleteGrammemsRich( eAllGenders );

   if (RusNode.HasOneGrammem(rMasculinum) )
		EngNode.AddOneGrammemRich(eMasculinum);
		else
			if (RusNode.HasOneGrammem(rFeminum) )
			EngNode.AddOneGrammemRich( eFeminum);

   


	
   if ( RusNode.HasPOS(PRONOUN) )// если это русское местоимение
	  {

		// установка падежа 
		  EngNode.DeleteGrammemsRich(  _QM(eNominative) |  _QM(eObjectCase) );
		if (RusNode.HasOneGrammem(rNominativ) )
			EngNode.AddOneGrammemRich( eNominative);
		else
			 EngNode.m_Words[EngNode.m_MainWordNo].AddFormGrammem( eObjectCase);

	  };

};
Beispiel #9
0
// функция, которая дает ограничения на валентность для однородного ряда
// именных групп.
void CRusSemStructure::GetMNAPattern(size_t NodeNo, long& Poses, QWORD& Grammems) const
{
	Grammems = 0;
	Poses = 0;

	long LastNodeNo  = FindRightClosestNode(NodeNo);

	if ( LastNodeNo == -1)  return;

	Grammems = m_Nodes[LastNodeNo].GetGrammems() & rAllCases;

    if ( HasRichPOS  (LastNodeNo, ADV) || m_Nodes[LastNodeNo].HasSomePrep() )
	{
		// нужно, чтобы собрать "раз в году, по вечерам"
		Grammems = 0;
		Poses = (1<<ADV);
	}
    else
	 if ( HasRichPOS (LastNodeNo, INFINITIVE) )
		Poses = (1<<INFINITIVE);
	 else
		if (m_Nodes[LastNodeNo].m_bCompAdj)
		{
		  Poses = (1<<ADJ_FULL);
		  Grammems |= _QM(rComparative); 
		}
		else
		  Poses = (1<<NOUN);

	// нужно, чтобы собрать "раз в году, 9 мая"
	if ( m_Nodes[LastNodeNo].IsTimeRossNode() )
		Poses |= (1<<ADV);
};
Beispiel #10
0
/*
Выдает по парадигме прилагательного наречие, которое совпадает с краткой формой среднего рода
этого прилагательного, например: 
	"красивый" (ПРИЛ) -> "красиво" (НАР)
	"лучше" (ПРИЛ) -> "хорошо" (НАР)
*/
UINT CSemanticsHolder::GetAdverbWith_O_ByAdjective (UINT AdjParadigmId, string AdjWordForm)
{
	string AdvLemma;	

	CFormInfo Paradigm;
	try {
		if (!GetRusLemmatizer()->CreateParadigmFromID(AdjParadigmId, Paradigm))
			return -1;
	}
	catch (...) {
		return -1;
	};


	// ищем краткое прилагательное среднего рода
	long k=0;
	for (; k < Paradigm.GetCount(); k++)
	{
		string Form = Paradigm.GetWordForm(k);
		string AnCode = Paradigm.GetAncode(k);
		QWORD Grammems;
        BYTE POS;
        GetRusGramTab()->ProcessPOSAndGrammems(AnCode.c_str(), POS, Grammems );

        if (( Grammems & _QM(rNeutrum)) && POS==ADJ_SHORT)
					break;
	};
	if (k == Paradigm.GetCount()) return -1;

	AdvLemma = Paradigm.GetWordForm(k);

	return GetFirstParadigmId(morphRussian, AdvLemma,  (1<<ADV));
};
Beispiel #11
0
bool SoloGleiche (const CAgramtabLine* noun, const CAgramtabLine* adj) 
{	
    if ((adj->m_Grammems & _QM(gAdjektiveOhneArtikel)) == 0) 
		return false;

	return     GenderNumberCaseGerman(noun, adj);
};
Beispiel #12
0
bool WeakGleiche (const CAgramtabLine* noun, const CAgramtabLine* adj) 
{	
    if ((adj->m_Grammems & _QM(gAdjektiveMitBestimmte)) == 0) 
		return false;

	return     GenderNumberCaseGerman(noun, adj);
};
Beispiel #13
0
bool CRusSemStructure :: IsLocNode(size_t NodeNo) const 
{
  const CRusSemNode& N = m_Nodes[NodeNo];

  bool Result =      N.IsTrueLocNode() 
				||  (    (N.m_Colloc.m_Type  == ThesType)
					 && (N.m_Colloc.GetThesInterp().m_ThesaurusId  == LocThes)
			       )
                   ||  (N.HasGrammems(_QM(rToponym) )
			       )
;
  if (     Result
	    && (N.GetType() == LocRoss) 
	    && GetRossHolder(LocRoss)->HasCX(N.GetUnitNo(),  "ЧАСТЬ_ТЕЛА", "D_SF")
		&& !N.HasSomePrep()
     )
  return false; 


  if (     N.HasSomePrep()
	 	&& HasLocPrepInBegining(NodeNo)
		&& (N.m_SemCategory == scObject)
	 )
	 return true;

  if (     N.HasPOS(ADV) // где, далеко
	    && (N.GetType()   != NoneRoss)
	)
		if ( GetRossHolder(N.GetType())->HasCX(N.GetUnitNo(),  "LOK", "D_SEM_REL") )	 
			return true;

  return Result;
};
Beispiel #14
0
// "this", "that", "one"
// Эти местоимения имеют множественную форму ("these", "those", "ones")
bool CEngSynthes::lemma_is_demonstrative_pronoun (string Lemma) const
{
  try
  {
	vector<CFormInfo> ParadigmCollection; 
	E.m_pData->GetEngLemmatizer()->CreateParadigmCollection(true, Lemma, false, false, ParadigmCollection);

	for(int i = 0; i < ParadigmCollection.size(); i++)
	{
		string AnCode = ParadigmCollection[i].GetAncode(0);

		if( E.m_pData->GetEngGramTab()->GetPartOfSpeech(AnCode.c_str()) == ePN_ADJ) 
		{
			QWORD g;
			bool bRes = E.m_pData->GetEngGramTab()->GetGrammems(AnCode.c_str(), g);
			assert (bRes);
			if( g & _QM(eDemonstrativePronoun)) 
			     return  true;
		}
	}
  }
  catch(...)
  {
  }
	return false;
};
Beispiel #15
0
bool CRusSentence::find_subj_and_predic_noun_with_dash(CMorphVariant& synVariant)
{
	bool found_dash = false;
	int subj = -1, predk = -1;
	int subj_noun = -1, subj_verb = -1, predk_noun = -1, predk_verb = -1;

	for(int UnitNo = synVariant.m_vectorGroups.get_main_word(0) ; UnitNo < synVariant.m_SynUnits.size(); UnitNo = synVariant.m_vectorGroups.get_next_main_word(UnitNo))
	{
		const CSynUnit& U = synVariant.m_SynUnits[UnitNo];
		if ( U.m_Type == EClause )
			continue; 

		const CSynWord& W = m_Words[U.m_SentPeriod.m_iFirstWord];
		const CSynHomonym& H = W.m_Homonyms[U.m_iHomonymNum];

		if( W.m_bDash )
		{
			found_dash = true;
			continue;
		};

		size_t GroupNo = synVariant.m_vectorGroups.get_maximal_group_no(UnitNo);
		QWORD Grammems = H.m_iGrammems;
		if (GroupNo != -1)
			Grammems = synVariant.m_vectorGroups.GetGroups()[GroupNo].GetGrammems();


		if	(		(		Grammems & _QM(rNominativ)
						&&	H.IsSynNoun()
					)
                    ||	 H.HasPos(INFINITIVE )
			)
		{
			if(!found_dash)
				subj_noun = UnitNo;
			else 
				if(predk_noun == -1)					
					predk_noun = UnitNo;
		};
	}

	synVariant.ResetSubj();
	synVariant.m_iPredk = -1;

	if	((subj_noun != -1)  &&  (predk_noun != -1)) 
	{
		synVariant.m_Subjects.push_back (subj_noun);
		synVariant.m_iPredk = predk_noun;
	}
	else
		if ((subj_verb != -1)  &&  (predk_verb != -1))
		{
			synVariant.m_Subjects.push_back( subj_verb) ;
			synVariant.m_iPredk = predk_verb;
		}
		else
				return false;

	return true;
}
Beispiel #16
0
bool CRusSentence::CheckCoordinationOfNounAndParticiple(const CSynHomonym& Participle, const CClause* pClause, size_t NounWordNo, size_t NounHomonymNo) const
{
	const CSynHomonym& Noun  = m_Words[NounWordNo].GetSynHomonym(NounHomonymNo);
	
	// мальчик, ушедший домой, пришел
	if(	 GetRusGramTab()->GleicheGenderNumberCase(Noun.m_CommonGramCode.c_str(), Noun.GetGramCodes().c_str(), Participle.GetGramCodes().c_str()) )
		return true;

	// мальчик и девочка, ушедшие домой, пришли
	CSVI Dummy;
	if (	(pClause->IsInThisGroup(NounWordNo, SIMILAR_NOUN_GROUPS, Dummy) != NULL)
		&&  GetRusGramTab()->GleicheCase(Participle.GetGramCodes().c_str(), Noun.GetGramCodes().c_str())
	   )
	   return true;

	//Два дома ,построенных на холме, постепенно разрушались.
	const CGroup*  pNumerNounGroup =  pClause->IsInThisGroup(NounWordNo, NUMERAL_NOUN, Dummy);
	if (	( pNumerNounGroup != NULL) 
		&&  ( pNumerNounGroup->GetGrammems() & _QM(rNominativ) )
		&&  ( Participle.HasGrammem(rGenitiv) )
		&&  ( Participle.HasGrammem(rPlural) )
	   )
	   return true;
					 
	return false;
};
Beispiel #17
0
// Правила для "черная и белая ракетки; черные шкаф и стул"
bool CRusFormatCaller::format_for_plural_noun_adj(CGroup& G)
{
	const CGroup& AdjMaxGrp = get_maximal_group(G.m_iFirstWord);
	size_t adj_main_word = get_main_word_in_group(AdjMaxGrp);
	const CSynPlmLine& Adj = sent[adj_main_word];

	
	size_t noun_main_word = get_next_main_word(adj_main_word);
	if (noun_main_word == sent.size()) return false;
	const CSynPlmLine& Noun = sent[noun_main_word];
	const CGroup& NounMaxGrp = get_maximal_group(noun_main_word);

	if (!Adj.GetGramcodes() || !Noun.GetGramcodes()) return false; 

	bool bCase1 = 
		(		(AdjMaxGrp.m_GroupType == SIMILAR_ADJS)
			&&	(Noun.GetGrammems() & _QM(rPlural)) 
			&&  Noun.is_morph_noun( ) 
			&&  (NounMaxGrp.size() == 1)
			&&	GetGramTab()->GleicheCase(Adj.GetGramcodes(), Noun.GetGramcodes())
		);

	bool bCase2 = 
		(
				(NounMaxGrp.m_GroupType == SIMILAR_NOUN_GROUPS)
			&&	Noun.is_morph_noun( ) 
			&&	(Adj.GetGrammems() & _QM(rPlural)) 
			&&	(Noun.GetGrammems() & _QM(rSingular))
			&&	AdjMaxGrp.size() == 1
			&&	is_morph_adj(Adj)
			&&	GetGramTab()->GleicheCase(Adj.GetGramcodes(),Noun.GetGramcodes())
		);
		
	if (bCase1 || bCase2)
	{
		G.m_GroupType = NOUN_ADJ;
		G.m_iFirstWord = AdjMaxGrp.m_iFirstWord;
		G.m_iLastWord = NounMaxGrp.m_iLastWord;
		G.m_MainGroup = NounMaxGrp;
		G.SetGrammems( NounMaxGrp.GetGrammems() );
		create_syn_rel(G, noun_main_word, adj_main_word, NOUN_ADJ);
		return true;
	}
	
	return false;		
};
Beispiel #18
0
bool CGerFormatCaller::format_for_genit_NP (CGroup& G)
{
	const CGroup& MainGroup = get_maximal_group(G.m_iFirstWord);
	int i = get_main_word_in_group(MainGroup);
	if (!is_morph_noun(sent[i])) return false;

	if (MainGroup.m_iLastWord+1 == sent.size()) return false;

	const CGroup& GenitGroup = get_maximal_group(MainGroup.m_iLastWord+1);
	int j = get_main_word_in_group(GenitGroup);
	//if ( (GenitGroup.GetGrammems() & gAllCases) != _QM(gGenitiv) ) return false;
	if ( !(GenitGroup.GetGrammems() & _QM(gGenitiv)) ) return false;

	if	(		!is_morph_noun(sent[j]) 
			&&	!sent[j].HasFlag(fl_adjective_as_noun)
		) 
	{
		return false;
	};

	if ( (GenitGroup.GetGrammems() & gAllCases) != _QM(gGenitiv) ) 
	{
		if	(		(GenitGroup.m_GroupType != gDET_ADJ_NOMEN) 
				&&	(GenitGroup.m_GroupType != gADJ_NOMEN) 
			)
			return false;

		if	(		(GenitGroup.size() == 2)
				&&	IstZahlWort(sent[GenitGroup.m_iFirstWord])
			)
			return false;
	};
	
	
	
	G.m_GroupType = gGENIT_NP;
	G.m_MainGroup = MainGroup;
	G.m_iLastWord = GenitGroup.m_iLastWord;
	G.SetGrammems( MainGroup.GetGrammems() );
	create_syn_rel(G, i, j,  gGENIT_NP);
	

	return true;
};
Beispiel #19
0
/*
 проверяет согласование, когда сказуемое  - личная форма глагола
 SubjGroupFirstWordNo - первое слово субъектной группы
 SubjWordNo - главное слово субъектной группы (результат)
*/
bool CRusSentence::check_verb_subj_coordination(const CMorphVariant& synVariant, int predk, int SubjGroupFirstWordNo, int& SubjWordNo) const
{
	const CSynUnit& PredUnit = synVariant.m_SynUnits[predk];
	const CSynHomonym& PredHom = m_Words[PredUnit.m_SentPeriod.m_iFirstWord].m_Homonyms[PredUnit.m_iHomonymNum];

    int gr_num = synVariant.m_vectorGroups.get_maximal_group_no(SubjGroupFirstWordNo);
    int main_word = (gr_num == -1) ? SubjGroupFirstWordNo : synVariant.m_vectorGroups.GetGroups()[gr_num].m_MainWordNo;
	const CSynUnit& SubjUnit = synVariant.m_SynUnits[main_word];
	const CSynHomonym& SubjHom = m_Words[SubjUnit.m_SentPeriod.m_iFirstWord].m_Homonyms[SubjUnit.m_iHomonymNum];


	if(    GetOpt()->GetGramTab()->GleicheSubjectPredicate(SubjHom.m_GramCodes.c_str(), PredUnit.m_GramCodes.c_str() )	
		|| gleiche_subj_pred_for_numerals_as_nouns(synVariant, predk, main_word ) 
	  )
	{
		SubjWordNo = main_word;
		return true;
	}
	else
	{
		if( gr_num != -1 )
			if(	!(		(PredHom.m_iGrammems & _QM(rImperative) )
					||	(PredHom.m_iGrammems  & ( _QM(rFirstPerson) | _QM(rSecondPerson)))
				 )
			  )
			{
					if( GleicheSubjPredForNumeralAndSimilar(synVariant,  predk, gr_num) )
					{
						SubjWordNo = main_word;				
						return true;
					}
					//nim : "все четыре мальчика ушли"
					int MinimalGroupNo = synVariant.m_vectorGroups.get_minimal_group(main_word);

					if( GleicheSubjPredForNumeralAndSimilar(synVariant, predk,  MinimalGroupNo) )
					{
						SubjWordNo = main_word;				
						return true;

					}								
			}
	}
	return false;
};
Beispiel #20
0
bool GenderNumberGerman(const CAgramtabLine* l1, const CAgramtabLine* l2)
{
		
	return 		((gAllNumbers & l1->m_Grammems & l2->m_Grammems) > 0)
			&&	(    	( (l1->m_Grammems & l2->m_Grammems & _QM(gPlural) ) > 0 )
					||	((gAllGenders & l1->m_Grammems & l2->m_Grammems) > 0)
				);

	
}
Beispiel #21
0
char* CAgramtab :: grammems_to_str (QWORD grammems, char* out_buf) const
{
	out_buf[0] = 0;
	size_t GrammemsCount = GetGrammemsCount();
	for (int i = GrammemsCount-1; i >=0; i--)
	 if (_QM(i) & grammems)
	 {
		 strcat (out_buf, GetGrammemStr(i));
		 strcat (out_buf, ",");
	 };	 
	return out_buf;
};
Beispiel #22
0
bool SubjectPredicateGerman(const CAgramtabLine* subj_l, const CAgramtabLine* verb_l)
{
    const QWORD& subj = subj_l->m_Grammems;
    const QWORD& verb = verb_l->m_Grammems;

	if(    !( subj & _QM(gNominativ)) 
	  )
	return false;

	if(  verb & _QM(gImperativ)  )  // otherwise "Dienste" is a subject in "die Dienste leistet"
	return false;
	


	QWORD Persons12 = _QM(gErstePerson) | _QM(gZweitePerson);
	QWORD gAllNumbers1 = ( _QM(gPlural) | _QM(gSingular) );
	if (		( subj & Persons12)
			||	(verb & Persons12)
		)
	{
		return		((gAllNumbers & subj & verb)>0) 
				&&	((Persons12 & subj & verb) > 0);
	}
	else
		return (gAllNumbers & subj & verb) > 0;

	return false;
}
Beispiel #23
0
/*
this function finds a word "zu" which is followed by infinitive, then it moves "zu" to the infinitive.
and deletes all Person, Number  and Tense information and adds grammem gZuVerbForm.
So it makes "zu machen" morphologically equal to "einzugehen".
*/
void BuildZuForms(CGerSentence &C)
{
	// first we should search for an anomalous perfect construction, since it is very  special
	for (int WordNo=0; WordNo+1<C.m_Words.size(); WordNo++)
	{
		if (!C.m_Words[WordNo].IsWordUpper("ZU")) continue;
		CSynWord& W = C.m_Words[WordNo+1];
		if (W.m_Register != LowLow) continue;
		int InfinitiveHomonymNo = W.GetHomonymByPOSandGrammem(gVER, gInfinitiv);
		if (InfinitiveHomonymNo == -1) continue;

		//  all infinitives terminate with "N"
		assert(W.m_strUpperWord[W.m_strUpperWord.length()-1] == 'N');

		if (W.m_Homonyms.size() > 1)
		{
			/*
			 In ambigious cases  an infinitive should be at the end of the sentence, or it must be followed by
			 a comma, a similar conjunction or an auxiliary verb.
			 Otherwise we cannot safely convert it to  "compound" infinitive. For example,
				"zu meinen alten Büchern"
			 Here  "meinen" can be an infinitive, but the program pass it.
			*/
			if	(		(WordNo+2 < C.m_Words.size())
					&&	(GetAuxVerbHomonym(C.m_Words[WordNo+2]) == -1)
                    &&	!C.m_Words[WordNo+2].HasDes(OPun)
					&&	!C.m_Words[WordNo+2].m_bSimilarConj
				)
				continue;
		};

		W.SetAllOtherHomsDel(InfinitiveHomonymNo);
		W.DeleteMarkedHomonymsBeforeClauses();
		W.m_strWord =  "zu-"+W.m_strWord;

		QWORD g = (gAllVerbClasses & W.m_Homonyms[0].m_iGrammems) |  _QM(gZuVerbForm);
		if (!C.GetGerGramTab()->GetGramCodeByGrammemsAndPartofSpeechIfCan(gVER, g, W.m_Homonyms[0].m_GramCodes))
		{
			string debug = C.GetOpt()->GetGramTab()->GrammemsToStr(g);
			ErrorMessage("Cannot find Gramtab line  for "+ debug);
		};
		C.InitHomonymMorphInfo(W.m_Homonyms[0]);
		

		C.MarkWordAsDeleted(WordNo);
	};


};
Beispiel #24
0
string ConvertToPlural(const CAgramtab* pGramTab,  const string& s)
{
	assert ((s.length() % 2) == 0);
	string Result;
	for (size_t i=0; i < s.length();i+=2)
	{
		const CAgramtabLine* L =   pGramTab->GetLine(pGramTab->s2i(s.c_str()+i));
		if (!L) continue;
		if (L->m_Grammems & _QM(gPlural) ) 
		{
			Result += s[i];
			Result += s[i+1];
			
		}
		else
			if (L->m_Grammems & _QM(gSingular) ) 
			{
				QWORD q = (L->m_Grammems & ~_QM(gSingular)) | _QM(gPlural);
				Result += pGramTab->GetAllPossibleAncodes(L->m_PartOfSpeech, q);
			};
	};
	return Result;

};
Beispiel #25
0
bool CAgramtab :: ProcessPOSAndGrammems (const char* line_in_gramtab, BYTE& PartOfSpeech, QWORD& grammems)  const
{
	if (strlen(line_in_gramtab) > 300) return false;

	StringTokenizer tok(line_in_gramtab," ,\t\r\n");
	const char* strPos = tok();
	if  (!strPos) 
	{
		//printf ("unknown pos");		
		return false;
	};
		

	//  getting the part of speech
	if( strcmp("*", strPos) )
	{
		PartOfSpeech = GetTagFromStr(*this, strPos);
		if (PartOfSpeech == UnknownPartOfSpeech)
			return false;
	}
	else
		PartOfSpeech = UnknownPartOfSpeech;

	
	//  getting grammems
	grammems = 0; 
	while ( tok() )
	{
		
		size_t Count = GetGrammemsCount();
		const char* grm = tok.val();
		

		size_t  i = 0;
		for (; i < Count; i++)
			if (!strcmp(grm, GetGrammemStr(i)) )
			{
				grammems |=  _QM(i);
				break;
			};

		if  (i == Count) 
			return false;
	};

	return true;
};
Beispiel #26
0
bool CAncodePattern::DeleteAncodesByGrammemIfCan(BYTE Grammem)
{
    string GramCodes;
    for (int j=0; j < m_GramCodes.length(); j+=2) 
	    if (m_GramCodes[j] != '?')
	    {
		    QWORD Grammems;
		    GetGramTab()->GetGrammems ( m_GramCodes.c_str() + j, Grammems);
		    if (   (Grammems & _QM(Grammem)) == 0 )
			      GramCodes += string(m_GramCodes.c_str() + j, 2);
	    }
    if (GramCodes.empty())
        return false;
    m_GramCodes = GramCodes;
    InitAncodePattern();
    return true;
}
Beispiel #27
0
// returns the end point of the graphematical descriptors
int CLemWord::ProcessGraphematicalDescriptors(const char* LineStr)
{
	size_t MorphSignPos = GetMorphSignPosition(LineStr);
	if (MorphSignPos == -1)
		MorphSignPos = strlen(LineStr);

    m_GraDescrs = parse_gra_descriptors(string (LineStr, MorphSignPos).c_str(), m_UnparsedGraphemDescriptorsStr);

	m_bSpace =			HasDes(OSpc) 
					||	HasDes(OEOLN) 
					||	((BYTE)m_strWord[0] == StupidSymbol1)
					||	( ((BYTE)m_strWord[0] == '_') && (m_strWord.length() == 1));

    

	if (HasDes (OUpLw))
		m_Register = UpLow;
	else
	if (HasDes (OUp))
		m_Register = UpUp;
	else
	if (HasDes (OLw))
		m_Register = LowLow;		
	else
		m_Register = AnyRegister;		

	m_bComma = (m_strWord.length() == 1)  && (m_strWord[0] == ',');	
	m_bDash = (m_strWord.length() == 1)  && (m_strWord[0] == '-');	

	bool bRomanNumber = is_roman_number(m_strWord.c_str(), m_strWord.length() );
	size_t hyphen_occur = m_strWord.find("-");
	if ((hyphen_occur != string::npos) && (hyphen_occur!=0))
	{
		// "ѕавла I-го" 
		// "I-го" - одно слово
		bRomanNumber = is_roman_number(m_strWord.c_str(), hyphen_occur);
	};
	if (bRomanNumber)
        m_GraDescrs |= _QM(ORoman);

    m_bWord  = !bRomanNumber && (HasDes(ORLE) || HasDes(OLLE)); 

	return (int)MorphSignPos;

}
Beispiel #28
0
bool CGerFormatCaller::format_for_genit_in_preposition(CGroup& G)
{
	const CGroup& GenitGroup = get_maximal_group(G.m_iFirstWord);
	int i = get_main_word_in_group(GenitGroup);
	if (!is_morph_noun(sent[i])) return false;

	if (GenitGroup.m_iLastWord+1 == sent.size()) return false;
	if ( (GenitGroup.GetGrammems() & gAllCases) != _QM(gGenitiv) )  return false;

	const CGroup& MainGroup = get_maximal_group(GenitGroup.m_iLastWord+1);
	int j = get_main_word_in_group(MainGroup);
	if	(!is_morph_noun(sent[j]) ) 	return false;

	G.m_GroupType = gGENIT_PRE;
	G.m_MainGroup = MainGroup;
	G.m_iLastWord = MainGroup.m_iLastWord;
	G.SetGrammems( MainGroup.GetGrammems() );
	create_syn_rel(G, j, i,  gGENIT_NP);
	return true;
};
Beispiel #29
0
void CClause::BuildSynVariantsRecursive(vector<CBuildingUnit>::iterator pUnit, CMorphVariant& synVariant)
{
	int StartWordNo = pUnit->m_WordNo;
	int CountOfTypes =  pUnit->m_HomonymsCount;

	assert (CountOfTypes > 0);		
	for (int i = 0; i < CountOfTypes; i++)
	{
		if (!(pUnit->m_BestHomonyms & _QM(i))) continue;

		int NextWordNo;
		if (pUnit->m_ChildClauseNo != -1) 
			NextWordNo = AddUnitAsClause(pUnit, i, *this, synVariant);
		else
			NextWordNo = AddUnitAsWord(pUnit, i, *this, synVariant);

		if (i > pUnit->m_MaxUsedHomonymNo) 
			pUnit->m_MaxUsedHomonymNo = i;

		if (NextWordNo > m_iLastWord)
		{
			if (IsGoodVariant(synVariant)) 
				if (!IsTwoPotentialPredikatesInOneClause(synVariant)) 
						m_SynVariants.push_back(synVariant);
		}
		else
			BuildSynVariantsRecursive(pUnit+1,  synVariant);


		if (m_SynVariants.size() >= MorphVarMaxCount) return;

		synVariant.PopHomonymNum();


	}
}
Beispiel #30
0
bool CRusFormatCaller::format_for_noun_groups (CGroup& G)
{
	const CGroup& FirstChild = get_maximal_group(G.m_iFirstWord);
	if (FirstChild.m_iFirstWord != G.m_iFirstWord) return false;
	int i =  get_main_word_in_group(FirstChild);
	if (!is_left_noun_modifier (Wi)) return false;
	if( Wi.is_lemma("КОТОРЫЙ") )
	  		return false;
	string debug_str;
	bool bFound_VSE = false; //слово "всe" начинает группу
	bool bFoundParticiple = false; //нашли дст., пе, причастие
	bool bAdjShouldBeInNominativOrGenitiv = false; //чтобы собрать "две красивых девочки"
	//gleiche_for_small_numbers
	int NounGroupNo;

	if(		Wi.get_upper_word()
		&&	!strcmp(Wi.get_upper_word(), "ВСЕ")
		&&    Wi.is_lemma("ВЕСЬ")
		&&	(get_maximal_group_size(i) == 1)
		)
	bFound_VSE = true;

	if	(		Wi.has_grammem(rActiveVoice)
			&&	Wi.has_grammem(rTransitive)
            &&  Wi.HasPOS(PARTICIPLE) 
		)
		bFoundParticiple = true;

  

  
	if ((G.m_iFirstWord+1) >= sent.size()) return false;

	// собираем группу "сам себя"
	int j;
	if (    Wi.is_lemma( "САМ") )
	{
		G.m_iLastWord = get_maximal_group(G.m_iFirstWord).m_iLastWord + 1; 
		if (G.m_iLastWord < sent.size())
		{
			NounGroupNo = get_maximal_group_no(G.m_iLastWord);		
            j = (NounGroupNo == -1 ) ? G.m_iLastWord : GetGroups()[NounGroupNo].m_MainWordNo;
			if (   Wj.is_lemma("СЕБЯ") 
				|| Wj.is_lemma("ТЫ") 
				|| Wj.is_lemma("Я") 
				|| Wj.is_lemma("МЫ")  // "сами мы не местные"
				)
				if ((Wi.GetGrammems() & Wj.GetGrammems() & rAllCases) > 0)
				{
					i = j;
					G.SetGrammems (Wi.GetGrammems() & Wj.GetGrammems() & (rAllCases | rAllGenders));
					goto CreateGroup;
				};
		};
	};
	   

	// нахождение последовательности П1 ... Пn С, где Пi - прилагательное или группа прилагательных,
	// а С - ИГ.
	// Согласование по падежу, числу и роду будет проверяться в другом цикле.
	G.SetGrammems ( Wi.GetGrammems() );
	for (	G.m_iLastWord = get_maximal_group(G.m_iFirstWord).m_iLastWord + 1; 
			G.m_iLastWord < sent.size(); 
			G.m_iLastWord  = get_maximal_group(G.m_iLastWord).m_iLastWord + 1 
		)
	{

			int i_gr = get_maximal_group_no(G.m_iLastWord);		
            i = (i_gr == -1) ? G.m_iLastWord:GetGroups()[i_gr].m_MainWordNo;

			if( Wi.is_lemma("КОТОРЫЙ") )
	  			return false;

			if( i_gr != -1 ) 
			{
				G.SetGrammems (G.GetGrammems() &  GetGroups()[i_gr].GetGrammems());
			}
			else
			{
				G.SetGrammems( G.GetGrammems() & Wi.GetGrammems() );
				if( GetGramTab()->IsSimpleParticle(Wi.get_lemma(), Wi.GetPoses()) && (i > G.m_iFirstWord) )			
					continue;
				
			}

			if ( !is_left_noun_modifier (Wi)) break;

			if	(		Wi.has_grammem(rActiveVoice) 
					&&	Wi.has_grammem(rTransitive) 
					&&	Wi.HasPOS(PARTICIPLE) 
				)
				bFoundParticiple = true;
		
	}; //  end of for by  "G.m_iLastWord"


	if (G.m_iLastWord < sent.size())
		G.m_iLastWord = get_maximal_group(G.m_iLastWord).m_iLastWord;

	/*
		если дошли до конца или в конце не стоит существительного 
		тогда пробуем собрать группу "все это" ("это" - не является синтаксическим cуществительным)
			или группу "все лишнее"
	*/
	if (G.m_iLastWord >= sent.size() || !Wi.is_syn_noun())
	{
		//  если самое первое слово ИГ было "всe"
		if( bFound_VSE )
		{
			// возвращаемся на одно слово назад
			G.m_iLastWord--;	
			if( G.size() != 2 )
				return false;
			i = G.m_iLastWord;
			if( ( get_maximal_group_size(i) == 1) && GetGramTab()->IsSimpleParticle(Wi.get_lemma(), Wi.GetPoses()) )
				G.m_iLastWord++;

			if (G.m_iLastWord >= sent.size()) return false;

			if( get_maximal_group_size(G.m_iLastWord) > 1)
				return false;

			if( sent[G.m_iLastWord].m_UnitType != EWord)
				return false;

			i = get_main_word(G.m_iLastWord);			
		
			if( !is_left_noun_modifier (Wi) )	 
				return false;

			if( !is_left_noun_modifier (Wi) )	 
				return false;
		}
		else
			return false;
	}



	if( bFoundParticiple )
		if( (Wi.GetGrammems() & _QM(rAccusativ)) && (G.GetGrammems() & _QM(rAccusativ)) )
			return false;
  

	// Берем группу, которая могла быть построена на найденном существительном,
	// группа может прийти из тезауруса или ЧИСЛ-СУЩ, например: "первые пять человек",

	size_t FirstWordOfNounGroup;  
	NounGroupNo = get_maximal_group_no(i);
	if( NounGroupNo != -1)
	{
		FirstWordOfNounGroup = GetGroups()[NounGroupNo].m_iFirstWord;
		G.SetGrammems ( GetGroups()[NounGroupNo].GetGrammems() );
	}
	else
	{
		FirstWordOfNounGroup = i;
		G.SetGrammems( Wi.GetGrammems() );
	};

	if( G.m_iFirstWord > 0 )
	{
		QWORD dummy;
		//gleiche_for_plural_numbers(i, G.m_iFirstWord - 1, false, dummy, bAdjShouldBeInNominativOrGenitiv, is_small_number_group(G.m_iFirstWord - 1));		  
	}

	if ( sent[G.m_iFirstWord].HasFlag(fl_digit) && sent[G.m_iFirstWord].HasPOS(NUMERAL_P) && sent[FirstWordOfNounGroup].HasFlag(fl_ile) ) // "вызвать 5 API"
		return false;

	// Согласование по падежу, числу и роду проверяться здесь.
	for (j = G.m_iFirstWord; j <  FirstWordOfNounGroup; j = get_maximal_group(j).m_iLastWord + 1)
	{
		const CGroup& LastHost = get_maximal_group(j);
		int  MainWordNo = LastHost.m_MainWordNo;

		if( (LastHost.size() == 1) && GetGramTab()->IsSimpleParticle(Wj.get_lemma(), Wj.GetPoses()) )				
				continue;



		if ( !bAdjShouldBeInNominativOrGenitiv )
		{
			//  проверяем согласование между прилагательным и существительным
			QWORD CommonGrams = GetGramTab()->GleicheGenderNumberCase(Wi.m_type_gram_code, Wi.m_gramcodes, sent[MainWordNo].m_gramcodes); 
			if (!CommonGrams)
				if	(		NounGroupNo != -1 
						&& GetGroups()[NounGroupNo].m_GroupType == NUMERAL_NOUN
						&& (sent[MainWordNo].GetGrammems() &  G.GetGrammems() & rAllNumbers)					
						&& (sent[MainWordNo].GetGrammems() &  G.GetGrammems() & rAllCases)
					) 
					CommonGrams = sent[MainWordNo].GetGrammems();
				else
					return false;
				


			//  если главный элемент в ПРИЛ_СУЩ является однородным рядом, тогда нужно проверить, что
			//  данное прилагательное согласовано со всеми членами однородного ряда по падежу (по числу и роду может быть не согласовано)
			//  иначе вся фразы "Советской гавани, он" покрывается одним ПРИЛ_СУЩ 
			if (NounGroupNo != -1)
				if (GetGroups()[NounGroupNo].m_GroupType == SIMILAR_NOUN_GROUPS)
					if ( (Wi.GetGrammems() & GetGroups()[NounGroupNo].GetGrammems() & rAllCases) == 0)
						return false;

			G.SetGrammems( G.GetGrammems() & CommonGrams);
		}
		else
		{
			if	(			(			!(sent[MainWordNo].GetGrammems() &  _QM(rGenitiv))	
									&&	!(sent[MainWordNo].GetGrammems() &  _QM(rNominativ)) 
							)
						||	!(	sent[MainWordNo].GetGrammems() &  _QM(rPlural)) 
					
				)
					return false;				

			G.SetGrammems(G.GetGrammems() & sent[MainWordNo].GetGrammems());
		};

		
	}  // end of cycle by "j"

	if( bAdjShouldBeInNominativOrGenitiv )
		if( NounGroupNo == -1 )
			G.SetGrammems( Wi.GetGrammems());
		else
			G.SetGrammems( GetGroups()[NounGroupNo].GetGrammems() );


	debug_str = GetGramTab()->GrammemsToStr(G.GetGrammems());
	debug_str = GetGramTab()->GrammemsToStr(W2.GetGrammems());

	G.m_Cause = "ИГ, согласованная по роду, числу и падежу";

	if (is_morph_pronoun(Wi)) return false; 


CreateGroup:

	if ((G.GetGrammems() & rAllNumbers) == _QM(rSingular))
		change_words_in_group_grammems(G, G.GetGrammems(), (rAllNumbers | rAllGenders | rAllCases));  
	else
		change_words_in_group_grammems(G, G.GetGrammems(), (rAllNumbers | rAllCases));  

	G.m_MainGroup =  get_maximal_group(i);
	debug_str = GetGramTab()->GrammemsToStr(W2.GetGrammems());
	G.m_iLastWord = G.m_MainGroup.m_iLastWord;
	G.m_GroupType = NOUN_ADJ;
	debug_str = GetGramTab()->GrammemsToStr(G.GetGrammems());
  
    {
        size_t k  = G.m_iFirstWord; 
        size_t last = get_maximal_group(G.m_iLastWord).m_iFirstWord;
        while (k < last)
        {	
            const CGroup& H = get_maximal_group(k);
            create_syn_rel(G, i, H.m_MainWordNo, NOUN_ADJ);           		
            k += H.size();
        }

    }

	return true;
};