@@ -204,12 +204,17 @@ protected static function declinateSubstative($word, $animateness)
204204 $ last = S::slice ($ word , -1 );
205205
206206 if (($ declension = NounDeclension::getDeclension ($ word )) == NounDeclension::SECOND_DECLENSION ) {
207- $ soft_last = $ last == 'й ' || (in_array ($ last , ['ь ' , 'е ' , 'ё ' , 'ю ' , 'я ' ], true )
208- && ((
209- RussianLanguage::isConsonant (S::slice ($ word , -2 ,
210- -1 )) && !RussianLanguage::isHissingConsonant (S::slice ($ word , -2 , -1 )))
211- || S::slice ($ word , -2 , -1 ) == 'и ' ));
212- $ prefix = NounDeclension::getPrefixOfSecondDeclension ($ word , $ last );
207+ $ soft_last = $ last === 'й ' || (
208+ in_array ($ last , ['ь ' , 'е ' , 'ё ' , 'ю ' , 'я ' ], true )
209+ && (
210+ (
211+ RussianLanguage::isConsonant (S::slice ($ word , -2 , -1 ))
212+ && !RussianLanguage::isHissingConsonant (S::slice ($ word , -2 , -1 ))
213+ )
214+ || S::slice ($ word , -2 , -1 ) == 'и '
215+ )
216+ );
217+ $ prefix = NounDeclension::getPrefixOfSecondDeclension ($ word , $ last );
213218 } elseif ($ declension == NounDeclension::FIRST_DECLENSION ) {
214219 $ soft_last = RussianLanguage::checkLastConsonantSoftness ($ word );
215220 } else {
@@ -218,16 +223,17 @@ protected static function declinateSubstative($word, $animateness)
218223
219224 $ forms = [];
220225
221- if (in_array ($ last , ['ч ' , 'г ' ], true )
226+ if (
227+ in_array ($ last , ['ч ' , 'г ' , 'ж ' , 'ш ' ], true )
222228 || in_array (S::slice ($ word , -2 ), ['чь ' , 'сь ' , 'ть ' , 'нь ' , 'рь ' , 'дь ' , 'ль ' ], true )
223- || (RussianLanguage::isVowel ($ last ) && in_array (S::slice ($ word , -2 , -1 ), ['ч ' , 'к ' ],
224- true )) ) { // before ч, чь, сь, ч+vowel, к+vowel
229+ || (RussianLanguage::isVowel ($ last ) && in_array (S::slice ($ word , -2 , -1 ), ['ч ' , 'к ' ], true ))
230+ ) { // before ч, чь, сь, ч+vowel, к+vowel
225231 $ forms [Cases::IMENIT ] = $ prefix . 'и ' ;
226- } elseif (in_array ($ last , ['н ' , 'ц ' , 'р ' , 'т ' , 'с ' , ' ж ' ], true )) {
232+ } elseif (in_array ($ last , ['н ' , 'ц ' , 'р ' , 'т ' , 'с ' ], true )) {
227233 $ forms [Cases::IMENIT ] = $ prefix . 'ы ' ;
228234 } else {
229- $ forms [Cases:: IMENIT ] = RussianLanguage:: chooseVowelAfterConsonant ( $ last , $ soft_last , $ prefix . ' я ' ,
230- $ prefix . 'а ' );
235+ // TODO: fix first declension (depends on animateness and gender, see test cases)
236+ $ forms [Cases:: IMENIT ] = RussianLanguage:: chooseVowelAfterConsonant ( $ last , $ soft_last , $ prefix . ' я ' , $ prefix . 'а ' );
231237 }
232238
233239 // RODIT
@@ -242,25 +248,27 @@ protected static function declinateSubstative($word, $animateness)
242248 } else {
243249 $ forms [Cases::RODIT ] = $ prefix ;
244250 }
245- } elseif (S::slice ($ word , -2 ) == 'ка ' && S::slice ($ word , -3 ,
246- -2 ) !== 'и ' ) { // words ending with -ка: чашка, вилка, ложка, тарелка, копейка, батарейка, аптека
247- if (S::slice ($ word , -3 , -2 ) == 'л ' ) {
251+ } elseif (S::slice ($ word , -2 ) == 'ка ' ) { // words ending with -ка: чашка, вилка, ложка, тарелка, копейка, батарейка, аптека
252+ if (in_array (S::slice ($ word , -3 , -2 ), ['б ' , 'в ' , 'д ' , 'з ' , 'л ' , 'м ' , 'н ' , 'п ' , 'р ' , 'с ' , 'т ' , 'ф ' ], true )) {
248253 $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -2 ) . 'ок ' ;
249- } elseif (in_array (S::slice ($ word , -3 , -2 ), ['й ' , 'е ' ], true )) {
254+ } elseif (in_array (S::slice ($ word , -3 , -2 ), ['ц ' , 'ч ' , 'ш ' , 'щ ' , 'ж ' ], true )) {
255+ $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -2 ) . 'ек ' ;
256+ } elseif (S::slice ($ word , -3 , -2 ) === 'й ' ) {
250257 $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -3 ) . 'ек ' ;
258+ } elseif (in_array (S::slice ($ word , -3 , -2 ), array_merge (['е ' , 'к ' ], RussianLanguage::$ vowels ), true )) {
259+ $ forms [Cases::RODIT ] = $ prefix ;
251260 } else {
252- if ($ word === 'штука ' ) {
253- $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -2 ) . 'к ' ;
254- } else {
255- $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -2 ) . 'ек ' ;
256- }
261+ $ forms [Cases::RODIT ] = S::slice ($ word , 0 , -2 ) . 'ек ' ;
257262 }
258- } elseif (in_array ( $ last, [ 'а ' ], true ) ) { // обида, ябеда
263+ } elseif ($ last === 'а ' ) { // обида, ябеда
259264 $ forms [Cases::RODIT ] = $ prefix ;
260- } elseif (in_array ( $ last, [ 'я ' ], true ) ) { // молния
265+ } elseif ($ last === 'я ' ) { // молния
261266 $ forms [Cases::RODIT ] = $ prefix . 'й ' ;
262- } elseif (RussianLanguage::isHissingConsonant ($ last ) || ($ soft_last && $ last != 'й ' ) || in_array (S::slice ($ word ,
263- -2 ), ['чь ' , 'сь ' , 'ть ' , 'нь ' , 'дь ' ], true )) {
267+ } elseif (
268+ RussianLanguage::isHissingConsonant ($ last )
269+ || ($ soft_last && $ last != 'й ' )
270+ || in_array (S::slice ($ word , -2 ), ['чь ' , 'сь ' , 'ть ' , 'нь ' , 'дь ' ], true )
271+ ) {
264272 $ forms [Cases::RODIT ] = $ prefix . 'ей ' ;
265273 } elseif ($ last == 'й ' || S::slice ($ word , -2 ) == 'яц ' ) { // месяц
266274 $ forms [Cases::RODIT ] = $ prefix . 'ев ' ;
0 commit comments