@ -77,7 +77,7 @@ NounDeclencion WStringToNounDeclencion(std::wstring str)
}
}
if ( str = = L " FIRST_A_IFORM_ANIMATE " )
if ( str = = L " FIRST_A_IFORM_ANIMATE " )
{
{
return FIRST_A_IFORM_ IN ANIMATE;
return FIRST_A_IFORM_ ANIMATE;
}
}
if ( str = = L " FIRST_A_UFORM_INANIMATE " )
if ( str = = L " FIRST_A_UFORM_INANIMATE " )
{
{
@ -274,6 +274,11 @@ bool NounSpecialPluralFormIsInDictionary(std::wstring nounNominativePlural)
{
{
return true ;
return true ;
}
}
if ( ! noun . haveSingleForm & & noun . nominativeForm = = nounNominativePlural )
{
return true ;
}
}
}
return false ;
return false ;
@ -301,6 +306,11 @@ NounRecord GetNounRecordFromDictionary_BySpecialPluralForm(std::wstring nounNomi
{
{
return noun ;
return noun ;
}
}
if ( ! noun . haveSingleForm & & noun . nominativeForm = = nounNominativePlural )
{
return noun ;
}
}
}
return { } ;
return { } ;
@ -339,6 +349,26 @@ bool charIsVowel(wchar_t c)
}
}
bool charIsMissingVowelSoftenerConsolant ( wchar_t c )
{
//This test belongs to missing vowel case.
//лев -> львы (because л, then е replaced by soft sign)
//немец -> немцы (because not л, the е is not replaced, just missing)
std : : wstring consolants = L " л " ;
for ( wchar_t ic : consolants )
{
if ( c = = ic )
{
return true ;
}
}
return false ;
}
std : : set < NounEndingDivision > getPossibleNounEndingDivisionSet ( std : : wstring noun )
std : : set < NounEndingDivision > getPossibleNounEndingDivisionSet ( std : : wstring noun )
{
{
std : : set < NounEndingDivision > result ;
std : : set < NounEndingDivision > result ;
@ -354,6 +384,7 @@ std::set<NounEndingDivision> getPossibleNounEndingDivisionSet(std::wstring noun)
if ( charIsConsolant ( nounBase [ nounBase . size ( ) - 1 ] ) | | nounBase [ nounBase . size ( ) - 1 ] = = L ' ь ' | | nounBase [ nounBase . size ( ) - 1 ] = = L ' ъ ' )
if ( charIsConsolant ( nounBase [ nounBase . size ( ) - 1 ] ) | | nounBase [ nounBase . size ( ) - 1 ] = = L ' ь ' | | nounBase [ nounBase . size ( ) - 1 ] = = L ' ъ ' )
{
{
result . insert ( { nounBase , ending , NounEndingDivision : : DC_COMMON } ) ;
result . insert ( { nounBase , ending , NounEndingDivision : : DC_COMMON } ) ;
result . insert ( { nounBase , ending , NounEndingDivision : : DC_SPECIAL_PLURAL_FORM } ) ;
}
}
//Check missed vowel (simple case)
//Check missed vowel (simple case)
@ -362,11 +393,22 @@ std::set<NounEndingDivision> getPossibleNounEndingDivisionSet(std::wstring noun)
result . insert ( { nounBase , ending , NounEndingDivision : : DC_LOST_VOWEL_O } ) ;
result . insert ( { nounBase , ending , NounEndingDivision : : DC_LOST_VOWEL_O } ) ;
}
}
if ( charIsConsolant ( nounBase [ nounBase . size ( ) - 1 ] ) & & nounBase [ nounBase . size ( ) - 2 ] = = L ' ь ' )
if ( charIsConsolant ( nounBase [ nounBase . size ( ) - 1 ] ) & & nounBase [ nounBase . size ( ) - 2 ] = = L ' ь ' & & charIsMissingVowelSoftenerConsolant ( nounBase [ nounBase . size ( ) - 3 ] ) )
{
{
result . insert ( { nounBase , ending , NounEndingDivision : : DC_LOST_VOWEL_E } ) ;
result . insert ( { nounBase , ending , NounEndingDivision : : DC_LOST_VOWEL_E } ) ;
}
}
if ( charIsConsolant ( nounBase [ nounBase . size ( ) - 1 ] ) & & charIsConsolant ( nounBase [ nounBase . size ( ) - 2 ] ) & & ! charIsMissingVowelSoftenerConsolant ( nounBase [ nounBase . size ( ) - 2 ] ) )
{
result . insert ( { nounBase , ending , NounEndingDivision : : DC_LOST_VOWEL_E } ) ;
}
if ( ending = = L " а " | | ending = = L " я " )
{
result . insert ( { nounBase , ending , NounEndingDivision : : DC_SPECIAL_PLURAL_A } ) ;
}
}
}
}
}
@ -452,51 +494,93 @@ bool charIsUFormConsolant(wchar_t c)
}
}
bool FirstAIFormSingularCondition ( const NounRecord & nounRecord ) //Same for both animate and inanimate
bool AIFormEndingIsCorrect ( const NounRecord & nounRecord )
{
{
return nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) & & nounRecord . haveSingleForm | |
( GetLastChar ( nounRecord ) = = L ' и ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) & & ! nounRecord . haveSingleForm ;
}
bool FirstAIFormInanimateSingularCondition ( const NounRecord & nounRecord )
{
return nounRecord . haveSingleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
}
bool FirstAIFormAnimateSingularCondition ( const NounRecord & nounRecord )
{
return nounRecord . haveSingleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
}
}
bool FirstAIFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool FirstAIFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & (
( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' и ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) )
) ;
}
}
bool FirstAIFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool FirstAIFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & (
( GetLastChar ( nounRecord ) = = L ' а ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' и ' & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) )
) ;
}
}
bool FirstAUForm SingularCondition( const NounRecord & nounRecord ) //Same for both animate and inanimate
bool FirstAUForm Inanimate SingularCondition( const NounRecord & nounRecord )
{
{
return nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return nounRecord . haveSingleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
}
}
bool FirstAUFormAnimateSingularCondition ( const NounRecord & nounRecord )
{
return nounRecord . haveSingleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
}
bool FirstAUFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool FirstAUFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & (
( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' ы ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) )
) ;
}
}
bool FirstAUFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool FirstAUFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & (
( GetLastChar ( nounRecord ) = = L ' а ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' ы ' & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) )
) ;
}
}
bool FirstYaForm SingularCondition( const NounRecord & nounRecord ) //Same for both animate and inanimate
bool FirstYaForm Inanimate SingularCondition( const NounRecord & nounRecord )
{
{
return nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' я ' ) ;
return nounRecord . haveSingleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' я ' ) ;
}
bool FirstYaFormAnimateSingularCondition ( const NounRecord & nounRecord )
{
return nounRecord . haveSingleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' я ' ) ;
}
}
bool FirstYaFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool FirstYaFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & ( GetLastChar ( nounRecord ) = = L ' я ' ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeInanimate & & (
( GetLastChar ( nounRecord ) = = L ' я ' ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' и ' )
) ;
}
}
bool FirstYaFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool FirstYaFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & ( GetLastChar ( nounRecord ) = = L ' я ' ) ;
return nounRecord . haveMultipleForm & & nounRecord . canBeAnimate & & (
( GetLastChar ( nounRecord ) = = L ' я ' ) | |
! nounRecord . haveSingleForm & & ( GetLastChar ( nounRecord ) = = L ' и ' )
) ;
}
}
@ -509,7 +593,11 @@ bool SecondMaleIFormInanimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleIFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleIFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & charIsIFormConsolant ( GetLastChar ( nounRecord ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & (
charIsIFormConsolant ( GetLastChar ( nounRecord ) ) | |
! nounRecord . haveSingleForm & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
@ -520,7 +608,10 @@ bool SecondMaleIFormAnimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleIFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleIFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & charIsIFormConsolant ( GetLastChar ( nounRecord ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & (
charIsIFormConsolant ( GetLastChar ( nounRecord ) ) | |
! nounRecord . haveSingleForm & & charIsIFormConsolant ( GetPrevLastChar ( nounRecord ) ) & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
@ -531,7 +622,10 @@ bool SecondMaleUFormInanimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleUFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleUFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & charIsUFormConsolant ( GetLastChar ( nounRecord ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & (
charIsUFormConsolant ( GetLastChar ( nounRecord ) ) | |
! nounRecord . haveSingleForm & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) & & GetLastChar ( nounRecord ) = = L ' ы '
) ;
}
}
@ -542,7 +636,10 @@ bool SecondMaleUFormAnimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleUFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleUFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & charIsUFormConsolant ( GetLastChar ( nounRecord ) ) ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & (
charIsUFormConsolant ( GetLastChar ( nounRecord ) ) | |
! nounRecord . haveSingleForm & & charIsUFormConsolant ( GetPrevLastChar ( nounRecord ) ) & & GetLastChar ( nounRecord ) = = L ' ы '
) ;
}
}
@ -553,7 +650,10 @@ bool SecondMaleSSFormInanimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleSSFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleSSFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & GetLastChar ( nounRecord ) = = L ' ь ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeInanimate & & (
GetLastChar ( nounRecord ) = = L ' ь ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
@ -564,7 +664,10 @@ bool SecondMaleSSFormAnimateSingularCondition(const NounRecord& nounRecord)
bool SecondMaleSSFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool SecondMaleSSFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & GetLastChar ( nounRecord ) = = L ' ь ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_MALE & & nounRecord . canBeAnimate & & (
GetLastChar ( nounRecord ) = = L ' ь ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
bool SecondNeutralEFormSingularCondition ( const NounRecord & nounRecord )
bool SecondNeutralEFormSingularCondition ( const NounRecord & nounRecord )
@ -574,7 +677,10 @@ bool SecondNeutralEFormSingularCondition(const NounRecord& nounRecord)
bool SecondNeutralEFormPluralCondition ( const NounRecord & nounRecord )
bool SecondNeutralEFormPluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_NEUTRAL & & GetLastChar ( nounRecord ) = = L ' е ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_NEUTRAL & & (
GetLastChar ( nounRecord ) = = L ' е ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' я '
) ;
}
}
bool SecondNeutralOFormSingularCondition ( const NounRecord & nounRecord )
bool SecondNeutralOFormSingularCondition ( const NounRecord & nounRecord )
@ -584,22 +690,37 @@ bool SecondNeutralOFormSingularCondition(const NounRecord& nounRecord)
bool SecondNeutralOFormPluralCondition ( const NounRecord & nounRecord )
bool SecondNeutralOFormPluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_NEUTRAL & & GetLastChar ( nounRecord ) = = L ' о ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_NEUTRAL & & (
GetLastChar ( nounRecord ) = = L ' о ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' а '
) ;
}
}
bool ThirdFormSingularCondition ( const NounRecord & nounRecord ) //Same for both animate and inanimate
bool ThirdForm Inanimate SingularCondition( const NounRecord & nounRecord )
{
{
return nounRecord . haveSingleForm & & nounRecord . gender = = NG_FEMALE & & GetLastChar( nounRecord ) = = L ' ь ' ;
return nounRecord . haveSingleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord. canBeInanimate & & GetLastChar( nounRecord ) = = L ' ь ' ;
}
}
bool ThirdFormAnimateSingularCondition ( const NounRecord & nounRecord )
{
return nounRecord . haveSingleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord . canBeAnimate & & GetLastChar ( nounRecord ) = = L ' ь ' ;
}
bool ThirdFormInanimatePluralCondition ( const NounRecord & nounRecord )
bool ThirdFormInanimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord . canBeInanimate & & GetLastChar ( nounRecord ) = = L ' ь ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord . canBeInanimate & & (
GetLastChar ( nounRecord ) = = L ' ь ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
bool ThirdFormAnimatePluralCondition ( const NounRecord & nounRecord )
bool ThirdFormAnimatePluralCondition ( const NounRecord & nounRecord )
{
{
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord . canBeAnimate & & GetLastChar ( nounRecord ) = = L ' ь ' ;
return nounRecord . haveMultipleForm & & nounRecord . gender = = NG_FEMALE & & nounRecord . canBeAnimate & & (
GetLastChar ( nounRecord ) = = L ' ь ' | |
! nounRecord . haveSingleForm & & GetLastChar ( nounRecord ) = = L ' и '
) ;
}
}
@ -608,18 +729,18 @@ std::map<std::pair<NounDeclencion, NounCount>, std::function < bool(const NounRe
void SetupDeclentionMap ( )
void SetupDeclentionMap ( )
{
{
DeclentionConditionMap [ { FIRST_A_IFORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAIForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAIForm Inanimate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAIForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAIForm Animate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstAIFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstAIFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstAIFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_IFORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstAIFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAUForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAUForm Inanimate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAUForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstAUForm Animate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstAUFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstAUFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstAUFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_A_UFORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstAUFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstYaForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( FirstYaForm Inanimate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstYaForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( FirstYaForm Animate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstYaFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_INANIMATE , NC_PLURAL } ] = std : : bind ( FirstYaFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstYaFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { FIRST_YA_FORM_ANIMATE , NC_PLURAL } ] = std : : bind ( FirstYaFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
@ -645,8 +766,8 @@ void SetupDeclentionMap()
DeclentionConditionMap [ { SECOND_NEUTRAL_O_FORM , NC_PLURAL } ] = std : : bind ( SecondNeutralOFormPluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { SECOND_NEUTRAL_O_FORM , NC_PLURAL } ] = std : : bind ( SecondNeutralOFormPluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( ThirdForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_INANIMATE , NC_SINGULAR } ] = std : : bind ( ThirdForm Inanimate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( ThirdForm SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_ANIMATE , NC_SINGULAR } ] = std : : bind ( ThirdForm Animate SingularCondition, std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_INANIMATE , NC_PLURAL } ] = std : : bind ( ThirdFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_INANIMATE , NC_PLURAL } ] = std : : bind ( ThirdFormInanimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_ANIMATE , NC_PLURAL } ] = std : : bind ( ThirdFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
DeclentionConditionMap [ { THIRD_FORM_ANIMATE , NC_PLURAL } ] = std : : bind ( ThirdFormAnimatePluralCondition , std : : placeholders : : _1 ) ;
@ -686,17 +807,17 @@ bool NounScructIsAlreadyInArray(const NounStruct& nounStruct, const std::vector<
bool IsDeclencionSecondType ( NounDeclencion nounDeclention )
bool IsDeclencionSecondType ( NounDeclencion nounDeclention )
{
{
switch ( nounDeclention )
switch ( nounDeclention )
{
{
case SECOND_MALE_IFORM_INANIMATE :
case SECOND_MALE_IFORM_INANIMATE :
case SECOND_MALE_IFORM_ANIMATE :
case SECOND_MALE_IFORM_ANIMATE :
case SECOND_MALE_UFORM_INANIMATE :
case SECOND_MALE_UFORM_INANIMATE :
case SECOND_MALE_UFORM_ANIMATE :
case SECOND_MALE_UFORM_ANIMATE :
case SECOND_MALE_SSFORM_INANIMATE :
case SECOND_MALE_SSFORM_INANIMATE :
case SECOND_MALE_SSFORM_ANIMATE :
case SECOND_MALE_SSFORM_ANIMATE :
return true ;
return true ;
break ;
break ;
default :
default :
return false ;
return false ;
break ;
break ;
}
}
}
}
@ -704,18 +825,18 @@ bool IsDeclencionSecondType(NounDeclencion nounDeclention)
bool IsDeclencionAnimated ( NounDeclencion nounDeclention )
bool IsDeclencionAnimated ( NounDeclencion nounDeclention )
{
{
switch ( nounDeclention )
switch ( nounDeclention )
{
{
case FIRST_A_IFORM_ANIMATE :
case FIRST_A_IFORM_ANIMATE :
case FIRST_A_UFORM_ANIMATE :
case FIRST_A_UFORM_ANIMATE :
case FIRST_YA_FORM_ANIMATE :
case FIRST_YA_FORM_ANIMATE :
case SECOND_MALE_IFORM_ANIMATE :
case SECOND_MALE_IFORM_ANIMATE :
case SECOND_MALE_UFORM_ANIMATE :
case SECOND_MALE_UFORM_ANIMATE :
case SECOND_MALE_SSFORM_ANIMATE :
case SECOND_MALE_SSFORM_ANIMATE :
case THIRD_FORM_ANIMATE :
case THIRD_FORM_ANIMATE :
return true ;
return true ;
break ;
break ;
default :
default :
return false ;
return false ;
break ;
break ;
}
}
}
}
@ -735,6 +856,107 @@ bool LostVowelETest(NounTuple nounTuple, NounRecord nounRecord)
return nounRecord . haveStandardMultipleFormWithMissingLastVowel ;
return nounRecord . haveStandardMultipleFormWithMissingLastVowel ;
}
}
std : : map < NounEndingDivision : : DivisionCase , std : : function < std : : wstring ( std : : wstring ) > > DivisionCaseNounModificatorMap ;
std : : map < NounEndingDivision : : DivisionCase , std : : function < std : : wstring ( std : : wstring ) > > DivisionCaseEndingModificatorMap ;
std : : map < NounEndingDivision : : DivisionCase , std : : function < bool ( NounTuple ) > > DivisionCaseNounTupleFilterMap ;
std : : map < NounEndingDivision : : DivisionCase , std : : function < bool ( NounTuple , NounRecord ) > > DivisionCaseNounTupleRecordFilterMap ;
void FillDivisionCaseMaps ( )
{
DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_COMMON ] = [ ] ( std : : wstring s ) { return s ; } ;
DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_LOST_VOWEL_O ] = [ ] ( std : : wstring s )
{
return std : : wstring ( s . begin ( ) , s . end ( ) - 2 ) + L " o " + s [ s . size ( ) - 1 ] ;
} ;
DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_LOST_VOWEL_E ] = [ ] ( std : : wstring s )
{
if ( s [ s . size ( ) - 2 ] = = L ' ь ' )
{
return std : : wstring ( s . begin ( ) , s . end ( ) - 2 ) + L " е " + s [ s . size ( ) - 1 ] ;
}
else
{
return std : : wstring ( s . begin ( ) , s . end ( ) - 1 ) + L " е " + s [ s . size ( ) - 1 ] ;
}
} ;
DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_A ] = DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_COMMON ] ;
DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_FORM ] = DivisionCaseNounModificatorMap [ NounEndingDivision : : DC_COMMON ] ;
DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_COMMON ] = [ ] ( std : : wstring s ) { return s ; } ;
DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_LOST_VOWEL_O ] = DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_COMMON ] ;
DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_LOST_VOWEL_E ] = DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_COMMON ] ;
DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_A ] = [ ] ( std : : wstring s )
{
if ( s = = L " а " ) return L " ы " ;
if ( s = = L " я " ) return L " и " ;
std : : cout < < " Error in DivisionCaseEndingModificatorMap[NounEndingDivision::DC_SPECIAL_PLURAL_A] " < < std : : endl ;
return L " " ;
} ;
DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_FORM ] = DivisionCaseEndingModificatorMap [ NounEndingDivision : : DC_COMMON ] ;
DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_COMMON ] = [ ] ( NounTuple t ) { return true ; } ;
DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_LOST_VOWEL_O ] = [ ] ( NounTuple t )
{
return ( std : : get < 1 > ( t ) = = NC_PLURAL ) | |
( ( std : : get < 2 > ( t ) ! = NGC_P1_NOMINATIVE ) & &
( ! ( std : : get < 2 > ( t ) = = NGC_P4_ACCUSATIVE & & ! IsDeclencionAnimated ( std : : get < 0 > ( t ) ) ) ) ) ;
} ;
DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_LOST_VOWEL_E ] = DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_LOST_VOWEL_O ] ;
DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_A ] = [ ] ( NounTuple t )
{
return ( std : : get < 1 > ( t ) = = NC_PLURAL ) & &
( ( std : : get < 2 > ( t ) = = NGC_P1_NOMINATIVE ) | |
( ( std : : get < 2 > ( t ) = = NGC_P4_ACCUSATIVE & & ! IsDeclencionAnimated ( std : : get < 0 > ( t ) ) ) ) ) ;
} ;
DivisionCaseNounTupleFilterMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_FORM ] = [ ] ( NounTuple t )
{
return ( std : : get < 1 > ( t ) = = NC_PLURAL ) ;
} ;
DivisionCaseNounTupleRecordFilterMap [ NounEndingDivision : : DC_COMMON ] = [ ] ( NounTuple t , NounRecord r )
{
return ( r . haveStandardMultipleForm | | std : : get < 1 > ( t ) = = NC_SINGULAR ) & & StandardTest ( t , r ) ;
} ;
DivisionCaseNounTupleRecordFilterMap [ NounEndingDivision : : DC_LOST_VOWEL_O ] = [ ] ( NounTuple t , NounRecord r )
{
return LostVowelOTest ( t , r ) & & StandardTest ( t , r ) ;
} ;
DivisionCaseNounTupleRecordFilterMap [ NounEndingDivision : : DC_LOST_VOWEL_E ] = [ ] ( NounTuple t , NounRecord r )
{
return LostVowelETest ( t , r ) & & StandardTest ( t , r ) ;
} ;
DivisionCaseNounTupleRecordFilterMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_A ] = [ ] ( NounTuple t , NounRecord r )
{
return r . haveAlternativeMultipleFormEnding & & StandardTest ( t , r ) ;
} ;
DivisionCaseNounTupleRecordFilterMap [ NounEndingDivision : : DC_SPECIAL_PLURAL_FORM ] = [ ] ( NounTuple t , NounRecord r )
{
return r . specialMultipleForm ! = L " " & & StandardTest ( t , r ) ;
} ;
}
std : : vector < NounStruct > RecognizeNoun ( std : : wstring noun )
std : : vector < NounStruct > RecognizeNoun ( std : : wstring noun )
@ -750,91 +972,48 @@ std::vector<NounStruct> RecognizeNoun(std::wstring noun)
std : : wstring nounEnding = nounEndingDivision . ending ;
std : : wstring nounEnding = nounEndingDivision . ending ;
NounEndingDivision : : DivisionCase dc = nounEndingDivision . divisionCase ;
NounEndingDivision : : DivisionCase dc = nounEndingDivision . divisionCase ;
std : : wstring modifiedNounBase = DivisionCaseNounModificatorMap [ dc ] ( nounBase ) ;
std : : wstring modifiedNounEnding = DivisionCaseEndingModificatorMap [ dc ] ( nounEnding ) ;
if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_O )
std : : vector < NounTuple > possibleTupleArr = GetPossibleNounTupleArr ( modifiedNounEnding ) ;
{
nounBase . insert ( nounBase . begin ( ) + nounBase . size ( ) - 1 , L ' о ' ) ;
}
if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_E )
{
nounBase [ nounBase . size ( ) - 2 ] = L ' е ' ;
}
std : : vector < NounTuple > possibleTupleArr = GetPossibleNounTupleArr ( nounEnding ) ;
//Standard check
//Standard check
for ( NounTuple nounTuple : possibleTupleArr )
for ( NounTuple nounTuple : possibleTupleArr )
{
{
bool animated = IsDeclencionAnimated ( std : : get < 0 > ( nounTuple ) ) ;
bool additionalTest = true ;
if ( DivisionCaseNounTupleFilterMap [ dc ] ( nounTuple ) )
if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_O )
{
additionalTest = ( std : : get < 1 > ( nounTuple ) = = NC_PLURAL ) | |
( ( std : : get < 0 > ( nounTuple ) ! = NGC_P1_NOMINATIVE ) & &
( ! ( std : : get < 0 > ( nounTuple ) = = NGC_P4_ACCUSATIVE & & ! animated ) ) ) ;
}
if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_E )
{
additionalTest = ( std : : get < 1 > ( nounTuple ) = = NC_PLURAL ) | |
( ( std : : get < 0 > ( nounTuple ) ! = NGC_P1_NOMINATIVE ) & &
( ! ( std : : get < 0 > ( nounTuple ) = = NGC_P4_ACCUSATIVE & & ! animated ) ) ) ;
}
if ( ! additionalTest )
{
continue ;
}
std : : wstring nounNominaviteSingular = GetNounNoninative ( nounBase , std : : get < 0 > ( nounTuple ) , NC_SINGULAR ) ;
if ( NounIsInDictionary ( nounNominaviteSingular ) )
{
{
NounRecord nounRecord = GetNounRecordFromDictionary ( nounNominaviteSingular ) ;
std : : wstring nounNominaviteSingular = GetNounNoninative ( modifiedNounBase , std : : get < 0 > ( nounTuple ) , NC_SINGULAR ) ;
bool secondAdditionalTest = true ;
if ( NounIsInDictionary ( nounNominaviteSingular ) )
if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_O )
{
secondAdditionalTest = LostVowelOTest ( nounTuple , nounRecord ) & & StandardTest ( nounTuple , nounRecord ) ;
}
else if ( dc = = NounEndingDivision : : DC_LOST_VOWEL_E )
{
secondAdditionalTest = LostVowelETest ( nounTuple , nounRecord ) & & StandardTest ( nounTuple , nounRecord ) ;
}
else
{
secondAdditionalTest = ( nounRecord . haveStandardMultipleForm | | std : : get < 1 > ( nounTuple ) = = NC_SINGULAR ) & & StandardTest ( nounTuple , nounRecord ) ;
}
if ( secondAdditionalTest )
{
{
result. push_back ( { std : : get < 2 > ( nounTuple ) , std : : get < 1 > ( nounTuple ) , animated , nounRecord } ) ;
NounRecord nounRecord = GetNounRecordFromDictionary ( nounNominaviteSingular ) ;
//Check for additional form
if ( DivisionCaseNounTupleRecordFilterMap [ dc ] ( nounTuple , nounRecord ) )
if ( IsDeclencionSecondType ( std : : get < 0 > ( nounTuple ) ) )
{
{
if ( std : : get < 1 > ( nounTuple ) = = NC_SINGULAR & & nounRecord . haveAlternativeMultipleFormEnding )
result . push_back ( { std : : get < 2 > ( nounTuple ) , std : : get < 1 > ( nounTuple ) , IsDeclencionAnimated ( std : : get < 0 > ( nounTuple ) ) , nounRecord } ) ;
{
//Add additional form!
result . push_back ( { NGC_P1_NOMINATIVE , NC_PLURAL , animated , nounRecord } ) ;
if ( nounRecord . canBeInanimate )
{
result . push_back ( { NGC_P4_ACCUSATIVE , NC_PLURAL , animated , nounRecord } ) ;
}
}
}
}
}
}
std : : wstring nounNominavitePlural = GetNounNoninative ( nounBase , std : : get < 0 > ( nounTuple ) , NC_PLURAL ) ;
if ( NounSpecialPluralFormIsInDictionary ( nounNominavitePlural ) )
{
NounRecord nounRecord = GetNounRecordFromDictionary_BySpecialPluralForm ( nounNominavitePlural ) ;
if ( DivisionCaseNounTupleRecordFilterMap [ dc ] ( nounTuple , nounRecord ) )
{
result . push_back ( { std : : get < 2 > ( nounTuple ) , std : : get < 1 > ( nounTuple ) , IsDeclencionAnimated ( std : : get < 0 > ( nounTuple ) ) , nounRecord } ) ;
}
}
}
}
}
}
/*
//Special plural form check
//Special plural form check
for ( auto nounTuple : possibleTupleArr )
for ( auto nounTuple : possibleTupleArr )
{
{
@ -869,7 +1048,7 @@ std::vector<NounStruct> RecognizeNoun(std::wstring noun)
}
}
}
}
}
} */