Skip to content

Commit

Permalink
Fix #35: declination of immutable words and pluralization of words en…
Browse files Browse the repository at this point in the history
…ding with 'г'
  • Loading branch information
wapmorgan committed Sep 18, 2018
1 parent a340adb commit e063500
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 58 deletions.
29 changes: 21 additions & 8 deletions src/Russian/NounDeclension.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,28 @@ class NounDeclension extends \morphos\BaseInflection implements Cases, Gender
];

protected static $immutableWords = [
'евро',
'пенни',
'песо',
'сентаво',
// валюты
'евро', 'пенни', 'песо', 'сентаво',

// на а
'боа', 'бра', 'фейхоа', 'амплуа', 'буржуа',
// на о
'манго', 'какао', 'кино', 'трюмо', 'пальто', 'бюро', 'танго', 'вето', 'бунгало', 'сабо', 'авокадо', 'депо',
// на у
'зебу', 'кенгуру', 'рагу', 'какаду', 'шоу',
// на е
'шимпанзе', 'конферансье', 'атташе', 'колье', 'резюме', 'пенсне', 'кашне', 'протеже', 'коммюнике', 'драже', 'суфле', 'пюре', 'купе', 'фойе', 'шоссе',
// на и
'такси', 'жалюзи', 'шасси', 'алиби', 'киви', 'иваси', 'регби', 'конфетти', 'колибри', 'жюри', 'пенальти', 'рефери', 'кольраби',
// на э
'каноэ', 'алоэ',
// на ю
'меню', 'парвеню', 'авеню', 'дежавю', 'инженю', 'барбекю', 'интервью',
];

/**
* Проверка, изменяемое ли слово.
* @param $word
* @param string $word Слово для проверки
* @param bool $animateness Признак одушевленности
* @return bool
*/
Expand All @@ -89,7 +102,7 @@ public static function isMutable($word, $animateness = false)

/**
* Определение рода существительного.
* @param $word
* @param string $word
* @return string
*/
public static function detectGender($word)
Expand Down Expand Up @@ -133,8 +146,8 @@ public static function getDeclension($word)

/**
* Получение слова во всех 6 падежах.
* @param $word
* @param bool $animateness
* @param string $word
* @param bool $animateness Признак одушевлённости
* @return array
*/
public static function getCases($word, $animateness = false)
Expand Down
2 changes: 1 addition & 1 deletion src/Russian/NounPluralization.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ protected static function declinateSubstative($word, $animateness)

$forms = [];

if ($last == 'ч' || in_array(S::slice($word, -2), ['чь', 'сь', 'ть', 'нь'], true)
if (in_array($last, ['ч', 'г'], false) || in_array(S::slice($word, -2), ['чь', 'сь', 'ть', 'нь'], true)
|| (self::isVowel($last) && in_array(S::slice($word, -2, -1), ['ч', 'к'], true))) { // before ч, чь, сь, ч+vowel, к+vowel
$forms[Cases::IMENIT] = $prefix.'и';
} elseif (in_array($last, ['н', 'ц', 'р', 'т'], true)) {
Expand Down
34 changes: 29 additions & 5 deletions src/Russian/RussianLanguage.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ trait RussianLanguage

/**
* Проверка гласной
* @param $char
* @return bool
*/
public static function isVowel($char)
{
Expand All @@ -80,6 +82,8 @@ public static function isVowel($char)

/**
* Проверка согласной
* @param $char
* @return bool
*/
public static function isConsonant($char)
{
Expand All @@ -96,6 +100,8 @@ public static function isSonorousConsonant($char)

/**
* Проверка глухости согласной
* @param $char
* @return bool
*/
public static function isDeafConsonant($char)
{
Expand All @@ -104,14 +110,18 @@ public static function isDeafConsonant($char)

/**
* Щипящая ли согласная
* @param $consonant
* @return bool
*/
public static function isHissingConsonant($consonant)
{
return in_array(S::lower($consonant), ['ж', 'ш', 'ч', 'щ'], true);
}

/**
*
* Проверка на велярность согласной
* @param string[1] $consonant
* @return bool
*/
protected static function isVelarConsonant($consonant)
{
Expand All @@ -120,6 +130,8 @@ protected static function isVelarConsonant($consonant)

/**
* Подсчет слогов
* @param $string
* @return bool|int
*/
public static function countSyllables($string)
{
Expand All @@ -128,6 +140,9 @@ public static function countSyllables($string)

/**
* Проверка парности согласной
*
* @param $consonant
* @return bool
*/
public static function isPaired($consonant)
{
Expand All @@ -137,6 +152,8 @@ public static function isPaired($consonant)

/**
* Проверка мягкости последней согласной
* @param $word
* @return bool
*/
public static function checkLastConsonantSoftness($word)
{
Expand Down Expand Up @@ -174,13 +191,20 @@ public static function choosePrepositionByFirstLetter($word, $prepositionWithVow

/**
* Выбор окончания в зависимости от мягкости
*
* @param $last
* @param $softLast
* @param $afterSoft
* @param $afterHard
*
* @return mixed
*/
public static function chooseVowelAfterConsonant($last, $soft_last, $after_soft, $after_hard)
public static function chooseVowelAfterConsonant($last, $softLast, $afterSoft, $afterHard)
{
if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*self::isVelarConsonant($last) ||*/ $soft_last) {
return $after_soft;
if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*self::isVelarConsonant($last) ||*/ $softLast) {
return $afterSoft;
} else {
return $after_hard;
return $afterHard;
}
}

Expand Down
91 changes: 47 additions & 44 deletions tests/Russian/NounDeclensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function wordsProvider()
['воскрешение', false, 2, ['воскрешение', 'воскрешения', 'воскрешению', 'воскрешение', 'воскрешением', 'воскрешении']],
['доллар', false, 2, ['доллар', 'доллара', 'доллару', 'доллар', 'долларом', 'долларе']],
['евро', false, 2, ['евро', 'евро', 'евро', 'евро', 'евро', 'евро']],
['колье', false, 2, ['колье', 'колье', 'колье', 'колье', 'колье', 'колье']],
['фунт', false, 2, ['фунт', 'фунта', 'фунту', 'фунт', 'фунтом', 'фунте']],
['человек', true, 2, ['человек', 'человека', 'человеку', 'человека', 'человеком', 'человеке']],
['год', false, 2, ['год', 'года', 'году', 'год', 'годом', 'годе']],
Expand All @@ -64,6 +65,7 @@ public function wordsProvider()
['дитя', false, 2, ['дитя', 'дитяти', 'дитяти', 'дитя', 'дитятей', 'дитяти']],
['путь', false, 2, ['путь', 'пути', 'пути', 'путь', 'путем', 'пути']],
['поселок', false, 2, ['поселок', 'поселка', 'поселку', 'поселок', 'поселком', 'поселке']],
['пирсинг', false, 2, ['пирсинг', 'пирсинга', 'пирсингу', 'пирсинг', 'пирсингом', 'пирсинге']],
// сущ мужского рода с мягким окончанием
['гвоздь', false, 2, ['гвоздь', 'гвоздя', 'гвоздю', 'гвоздь', 'гвоздем', 'гвозде']],
['день', false, 2, ['день', 'дня', 'дню', 'день', 'днем', 'дне']],
Expand Down Expand Up @@ -106,50 +108,51 @@ public function testImmutableWords($word)

public function immutableWordsProvider()
{
return array(
array('авеню'),
array('атташе'),
array('бюро'),
array('вето'),
array('денди'),
array('депо'),
array('жалюзи'),
array('желе'),
array('жюри'),
array('интервью'),
array('какаду'),
array('какао'),
array('кафе'),
array('кашне'),
array('кенгуру'),
array('кино'),
array('клише'),
array('кольраби'),
array('коммюнике'),
array('конферансье'),
array('кофе'),
array('купе'),
array('леди'),
array('меню'),
array('метро'),
array('пальто'),
array('пенсне'),
array('пианино'),
array('плато'),
array('портмоне'),
array('рагу'),
array('радио'),
array('самбо'),
array('табло'),
array('такси'),
array('трюмо'),
array('фортепиано'),
array('шимпанзе'),
array('шоссе'),
array('эскимо'),
array('галифе'),
array('монпансье'),
);
return [
['авеню'],
['атташе'],
['бюро'],
['вето'],
['денди'],
['депо'],
['жалюзи'],
['желе'],
['жюри'],
['интервью'],
['какаду'],
['какао'],
['кафе'],
['кашне'],
['кенгуру'],
['кино'],
['клише'],
['кольраби'],
['колье'],
['коммюнике'],
['конферансье'],
['кофе'],
['купе'],
['леди'],
['меню'],
['метро'],
['пальто'],
['пенсне'],
['пианино'],
['плато'],
['портмоне'],
['рагу'],
['радио'],
['самбо'],
['табло'],
['такси'],
['трюмо'],
['фортепиано'],
['шимпанзе'],
['шоссе'],
['эскимо'],
['галифе'],
['монпансье'],
];
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/Russian/NounPluralizationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public function pluralWordsProvider()
['сообщение', false, ['сообщения', 'сообщений', 'сообщениям', 'сообщения', 'сообщениями', 'сообщениях']],
['халат', false, ['халаты', 'халатов', 'халатам', 'халаты', 'халатами', 'халатах']],
['прожектор', false, ['прожекторы', 'прожекторов', 'прожекторам', 'прожекторы', 'прожекторами', 'прожекторах']],
['пирсинг', false, ['пирсинги', 'пирсингов', 'пирсингам', 'пирсинги', 'пирсингами', 'пирсингах']],

['копейка', false, ['копейки', 'копеек', 'копейкам', 'копейки', 'копейками', 'копейках']],
['батарейка', false, ['батарейки', 'батареек', 'батарейкам', 'батарейки', 'батарейками', 'батарейках']],
Expand Down

0 comments on commit e063500

Please sign in to comment.