# -*- mode: perl; coding: cyrillic-koi8; -*- # Copyright (C) 1999-2003 Juri Linkov # License: GNU GPL 2 (see the file README) # Version: 0.0.1 # $Revision$ package Lingua::RU::Zaliz::Inflect; =head1 NAME Lingua::RU::Zaliz::Inflect - Русское словоизменение по словарю А.А.Зализняка Lingua::RU::Zaliz::Inflect - Russian inflection from dictionary of A.A.Zaliznyak =head1 SYNOPSIS Реализация правил словоизменения русского языка, описанных в книге: Зализняк А. А. Грамматический словарь русского языка: Словоизменение - 3-е изд. - М.: Рус.яз., 1987. =head1 DESCRIPTION Полную документацию ищите в файле README. For more information see the file README. =cut ## Параметры # $fic - feminine instrumental case: # при ненулевом значении генерирует дополнительные формы # творительного падежа с -ою, -ею, -ёю для слов женского рода $fic = 1; ## Глобальные переменные $v = "аеёиоуыэюя"; # гласные (vowel) $c = "бвгджзйклмнпрстфхцчшщ"; # согласные (consonant) $c2 = "бвгдзйклмнпрстфх"; # согласные без щипящих $sch = "шжчщ"; # щипящие ## Парадигмы: соответствие части речи кодам склонений/спряжений %paradigms = ( "с" => ["ие","ре","де","ве","те","пе", "им","рм","дм","вм","тм","пм"], "п" => ["пием","прем","пдем","пвемн","пвемо","птем","ппем", "пиеж","преж","пдеж","пвежн","пвежо","птеж","ппеж", "пиес","прес","пдес","пвесн","пвесо","птес","ппес", "пим" ,"прм" ,"пдм" ,"пвмн" ,"пвмо" ,"птм" ,"ппм" , "кием","киеж","киес","кимм", "с"], "мс" => ["и","р","д","в","т","п"], "мс-п" => ["ием","рем","дем","вемн","вемо","тем","пем", "иеж","реж","деж","вежн","вежо","теж","пеж", "иес","рес","дес","весн","весо","тес","пес", "им" ,"рм" ,"дм" ,"вмн" ,"вмо" ,"тм" ,"пм" ,], "числ" => ["и","р","д","вн","во","т","п"], "числ-п" => ["ием","рем","дем","вемн","вемо","тем","пем", "иеж","реж","деж","вежн","вежо","теж","пеж", "иес","рес","дес","весн","весо","тес","пес", "им" ,"рм" ,"дм" ,"вмн" ,"вмо" ,"тм" ,"пм" ,], "г" => ["и", "пем","пеж","пес","пм", "н1е","н2е","н3е","н1м","н2м","н3м", "б1е","б2е","б3е","б1м","б2м","б3м", "!2е","!2м", "дн","дп", #"чнд", "чнд-пием","чнд-прем","чнд-пдем","чнд-пвемн","чнд-пвемо","чнд-птем","чнд-ппем", "чнд-пиеж","чнд-преж","чнд-пдеж","чнд-пвежн","чнд-пвежо","чнд-птеж","чнд-ппеж", "чнд-пиес","чнд-прес","чнд-пдес","чнд-пвесн","чнд-пвесо","чнд-птес","чнд-ппес", "чнд-пим" ,"чнд-прм" ,"чнд-пдм" ,"чнд-пвмн" ,"чнд-пвмо" ,"чнд-птм" ,"чнд-ппм" , "чнд-кием","чнд-киеж","чнд-киес","чнд-кимм", #"чпд", "чпд-пием","чпд-прем","чпд-пдем","чпд-пвемн","чпд-пвемо","чпд-птем","чпд-ппем", "чпд-пиеж","чпд-преж","чпд-пдеж","чпд-пвежн","чпд-пвежо","чпд-птеж","чпд-ппеж", "чпд-пиес","чпд-прес","чпд-пдес","чпд-пвесн","чпд-пвесо","чпд-птес","чпд-ппес", "чпд-пим" ,"чпд-прм" ,"чпд-пдм" ,"чпд-пвмн" ,"чпд-пвмо" ,"чпд-птм" ,"чпд-ппм" , "чпд-кием","чпд-киеж","чпд-киес","чпд-кимм", #"чнс", "чнс-пием","чнс-прем","чнс-пдем","чнс-пвемн","чнс-пвемо","чнс-птем","чнс-ппем", "чнс-пиеж","чнс-преж","чнс-пдеж","чнс-пвежн","чнс-пвежо","чнс-птеж","чнс-ппеж", "чнс-пиес","чнс-прес","чнс-пдес","чнс-пвесн","чнс-пвесо","чнс-птес","чнс-ппес", "чнс-пим" ,"чнс-прм" ,"чнс-пдм" ,"чнс-пвмн" ,"чнс-пвмо" ,"чнс-птм" ,"чнс-ппм" , "чнс-кием","чнс-киеж","чнс-киес","чнс-кимм", #"чпс", "чпс-пием","чпс-прем","чпс-пдем","чпс-пвемн","чпс-пвемо","чпс-птем","чпс-ппем", "чпс-пиеж","чпс-преж","чпс-пдеж","чпс-пвежн","чпс-пвежо","чпс-птеж","чпс-ппеж", "чпс-пиес","чпс-прес","чпс-пдес","чпс-пвесн","чпс-пвесо","чпс-птес","чпс-ппес", "чпс-пим" ,"чпс-прм" ,"чпс-пдм" ,"чпс-пвмн" ,"чпс-пвмо" ,"чпс-птм" ,"чпс-ппм" , "чпс-кием","чпс-киеж","чпс-киес","чпс-кимм"] ); ## Таблица стандартных окончаний # (сгенерирована следующей командой) # swiprolog -g "load_files(['main.pl','util.pl','zaliz.pl'],[silent(true)])" -t "print_all_wfi." %wi_we_tab = ( 'ам1нб' => {'де' => 'ому','ие' => 'ый','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ый','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'ам1об' => {'де' => 'ому','ие' => 'ый','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ого','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'ам1ну' => {'де' => 'ому','ие' => 'ой','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ой','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'ам1оу' => {'де' => 'ому','ие' => 'ой','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ого','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'ам2нб' => {'де' => 'ему','ие' => 'ий','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ий','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'ам2об' => {'де' => 'ему','ие' => 'ий','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'его','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'ам2ну' => {'де' => 'ему','ие' => 'ий','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ий','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'ам2оу' => {'де' => 'ему','ие' => 'ий','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'его','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'ас1нб' => {'де' => 'ому','ие' => 'ое','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ое','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'ас1об' => {'де' => 'ому','ие' => 'ое','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ое','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'ас1ну' => {'де' => 'ому','ие' => 'ое','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ое','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'ас1оу' => {'де' => 'ому','ие' => 'ое','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ое','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'ас2нб' => {'де' => 'ему','ие' => 'ее','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ее','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'ас2об' => {'де' => 'ему','ие' => 'ее','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ее','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'ас2ну' => {'де' => 'ему','ие' => 'ее','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ее','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'ас2оу' => {'де' => 'ему','ие' => 'ее','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ее','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'аж1нб' => {'де' => 'ой','ие' => 'ая','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'ую','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'аж1об' => {'де' => 'ой','ие' => 'ая','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'ую','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'аж1ну' => {'де' => 'ой','ие' => 'ая','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'ую','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ые',}, 'аж1оу' => {'де' => 'ой','ие' => 'ая','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'ую','дм' => 'ым','им' => 'ые','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'аж2нб' => {'де' => 'ей','ие' => 'яя','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'юю','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'аж2об' => {'де' => 'ей','ие' => 'яя','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'юю','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'аж2ну' => {'де' => 'ей','ие' => 'яя','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'юю','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'ие',}, 'аж2оу' => {'де' => 'ей','ие' => 'яя','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'юю','дм' => 'им','им' => 'ие','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'км1нб' => {'ие' => '','им' => 'ы',}, 'км1об' => {'ие' => '','им' => 'ы',}, 'км1ну' => {'ие' => '','им' => 'ы',}, 'км1оу' => {'ие' => '','им' => 'ы',}, 'км2нб' => {'ие' => 'ь','им' => 'и',}, 'км2об' => {'ие' => 'ь','им' => 'и',}, 'км2ну' => {'ие' => 'ь','им' => 'и',}, 'км2оу' => {'ие' => 'ь','им' => 'и',}, 'кс1нб' => {'ие' => 'о','им' => 'ы',}, 'кс1об' => {'ие' => 'о','им' => 'ы',}, 'кс1ну' => {'ие' => 'о','им' => 'ы',}, 'кс1оу' => {'ие' => 'о','им' => 'ы',}, 'кс2нб' => {'ие' => 'е','им' => 'и',}, 'кс2об' => {'ие' => 'е','им' => 'и',}, 'кс2ну' => {'ие' => 'ё','им' => 'и',}, 'кс2оу' => {'ие' => 'ё','им' => 'и',}, 'кж1нб' => {'ие' => 'а','им' => 'ы',}, 'кж1об' => {'ие' => 'а','им' => 'ы',}, 'кж1ну' => {'ие' => 'а','им' => 'ы',}, 'кж1оу' => {'ие' => 'а','им' => 'ы',}, 'кж2нб' => {'ие' => 'я','им' => 'и',}, 'кж2об' => {'ие' => 'я','им' => 'и',}, 'кж2ну' => {'ие' => 'я','им' => 'и',}, 'кж2оу' => {'ие' => 'я','им' => 'и',}, 'мм1нб' => {'де' => 'ому','ие' => '','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => '','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мм1об' => {'де' => 'ому','ие' => '','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ого','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мм1ну' => {'де' => 'ому','ие' => '','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => '','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мм1оу' => {'де' => 'ому','ие' => '','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'ого','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мм2нб' => {'де' => 'ему','ие' => 'ь','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'ь','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мм2об' => {'де' => 'ему','ие' => 'ь','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'его','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'мм2ну' => {'де' => 'ему','ие' => 'ь','пе' => 'ём','ре' => 'его','те' => 'им','ве' => 'ь','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мм2оу' => {'де' => 'ему','ие' => 'ь','пе' => 'ём','ре' => 'его','те' => 'им','ве' => 'его','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'мс1нб' => {'де' => 'ому','ие' => 'о','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'о','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мс1об' => {'де' => 'ому','ие' => 'о','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'о','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мс1ну' => {'де' => 'ому','ие' => 'о','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'о','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мс1оу' => {'де' => 'ому','ие' => 'о','пе' => 'ом','ре' => 'ого','те' => 'ым','ве' => 'о','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мс2нб' => {'де' => 'ему','ие' => 'е','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'е','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мс2об' => {'де' => 'ему','ие' => 'е','пе' => 'ем','ре' => 'его','те' => 'им','ве' => 'е','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'мс2ну' => {'де' => 'ему','ие' => 'ё','пе' => 'ём','ре' => 'его','те' => 'им','ве' => 'ё','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мс2оу' => {'де' => 'ему','ие' => 'ё','пе' => 'ём','ре' => 'его','те' => 'им','ве' => 'ё','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'мж1нб' => {'де' => 'ой','ие' => 'а','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мж1об' => {'де' => 'ой','ие' => 'а','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мж1ну' => {'де' => 'ой','ие' => 'а','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ы',}, 'мж1оу' => {'де' => 'ой','ие' => 'а','пе' => 'ой','ре' => 'ой','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ым','им' => 'ы','пм' => 'ых','рм' => 'ых','тм' => 'ыми','вм' => 'ых',}, 'мж2нб' => {'де' => 'ей','ие' => 'я','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мж2об' => {'де' => 'ей','ие' => 'я','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'мж2ну' => {'де' => 'ей','ие' => 'я','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'и',}, 'мж2оу' => {'де' => 'ей','ие' => 'я','пе' => 'ей','ре' => 'ей','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'им','им' => 'и','пм' => 'их','рм' => 'их','тм' => 'ими','вм' => 'их',}, 'см1нб' => {'де' => 'у','ие' => '','пе' => 'е','ре' => 'а','те' => 'ом','ве' => '','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => 'ов','тм' => 'ами','вм' => 'ы',}, 'см1об' => {'де' => 'у','ие' => '','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'а','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => 'ов','тм' => 'ами','вм' => 'ов',}, 'см1ну' => {'де' => 'у','ие' => '','пе' => 'е','ре' => 'а','те' => 'ом','ве' => '','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => 'ов','тм' => 'ами','вм' => 'ы',}, 'см1оу' => {'де' => 'у','ие' => '','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'а','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => 'ов','тм' => 'ами','вм' => 'ов',}, 'см2нб' => {'де' => 'ю','ие' => 'ь','пе' => 'е','ре' => 'я','те' => 'ем','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'см2об' => {'де' => 'ю','ие' => 'ь','пе' => 'е','ре' => 'я','те' => 'ем','ве' => 'я','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'см2ну' => {'де' => 'ю','ие' => 'ь','пе' => 'е','ре' => 'я','те' => 'ём','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'см2оу' => {'де' => 'ю','ие' => 'ь','пе' => 'е','ре' => 'я','те' => 'ём','ве' => 'я','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'см8нб' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ем','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'см8об' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ем','ве' => 'и','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'см8ну' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ём','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'см8оу' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ём','ве' => 'и','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'сс1нб' => {'де' => 'у','ие' => 'о','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'о','дм' => 'ам','им' => 'а','пм' => 'ах','рм' => '','тм' => 'ами','вм' => 'а',}, 'сс1об' => {'де' => 'у','ие' => 'о','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'о','дм' => 'ам','им' => 'а','пм' => 'ах','рм' => '','тм' => 'ами','вм' => '',}, 'сс1ну' => {'де' => 'у','ие' => 'о','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'о','дм' => 'ам','им' => 'а','пм' => 'ах','рм' => '','тм' => 'ами','вм' => 'а',}, 'сс1оу' => {'де' => 'у','ие' => 'о','пе' => 'е','ре' => 'а','те' => 'ом','ве' => 'о','дм' => 'ам','им' => 'а','пм' => 'ах','рм' => '','тм' => 'ами','вм' => '',}, 'сс2нб' => {'де' => 'ю','ие' => 'е','пе' => 'е','ре' => 'я','те' => 'ем','ве' => 'е','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ь','тм' => 'ями','вм' => 'я',}, 'сс2об' => {'де' => 'ю','ие' => 'е','пе' => 'е','ре' => 'я','те' => 'ем','ве' => 'е','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ь','тм' => 'ями','вм' => 'ь',}, 'сс2ну' => {'де' => 'ю','ие' => 'ё','пе' => 'е','ре' => 'я','те' => 'ём','ве' => 'ё','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'я',}, 'сс2оу' => {'де' => 'ю','ие' => 'ё','пе' => 'е','ре' => 'я','те' => 'ём','ве' => 'ё','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'сс8нб' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ем','ве' => 'ь','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'я',}, 'сс8об' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ем','ве' => 'ь','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей','вм' => 'ь',}, 'сс8ну' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ём','ве' => 'ь','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'я',}, 'сс8оу' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ём','ве' => 'ь','дм' => 'ям','им' => 'я','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'сж1нб' => {'де' => 'е','ие' => 'а','пе' => 'е','ре' => 'ы','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => '','тм' => 'ами','вм' => 'ы',}, 'сж1об' => {'де' => 'е','ие' => 'а','пе' => 'е','ре' => 'ы','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => '','тм' => 'ами','вм' => '',}, 'сж1ну' => {'де' => 'е','ие' => 'а','пе' => 'е','ре' => 'ы','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => '','тм' => 'ами','вм' => 'ы',}, 'сж1оу' => {'де' => 'е','ие' => 'а','пе' => 'е','ре' => 'ы','те' => 'ою','те' => 'ой','ве' => 'у','дм' => 'ам','им' => 'ы','пм' => 'ах','рм' => '','тм' => 'ами','вм' => '',}, 'сж2нб' => {'де' => 'е','ие' => 'я','пе' => 'е','ре' => 'и','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ь','тм' => 'ями','вм' => 'и',}, 'сж2об' => {'де' => 'е','ие' => 'я','пе' => 'е','ре' => 'и','те' => 'ею','те' => 'ей','ве' => 'ю','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ь','тм' => 'ями','вм' => 'ь',}, 'сж2ну' => {'де' => 'е','ие' => 'я','пе' => 'е','ре' => 'и','те' => 'ёю','те' => 'ёй','ве' => 'ю','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'сж2оу' => {'де' => 'е','ие' => 'я','пе' => 'е','ре' => 'и','те' => 'ёю','те' => 'ёй','ве' => 'ю','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, 'сж8нб' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ью','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'сж8об' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ью','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей','вм' => 'ь',}, 'сж8ну' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ью','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'и',}, 'сж8оу' => {'де' => 'и','ие' => 'ь','пе' => 'и','ре' => 'и','те' => 'ью','ве' => 'ь','дм' => 'ям','им' => 'и','пм' => 'ях','рм' => 'ей','тм' => 'ями','вм' => 'ей',}, ); use Lingua::RU::Accent; =item wi2paradigm -- convert word information to paradigm Преобразование информации о слове в полную парадигму слова. Функция возвращет массив вариантов с полной информацией о слове и хеш с парадигмой слова. =cut sub wi2paradigm { my $wi = shift; my @wia = @{$wi}; my $wia0 = $wia[0]; if ((!defined $wia0->{'и'} || defined $wia0->{'и'} && $wia0->{'и'} eq "0") && !defined($wia0->{'искл'})) { # для слов без индекса и без исключений if (defined $wia0->{'т'} && $wia0->{'т'} eq "с") { # если существительное не склоняется, то слово копируется во все парадигмы my %wfh; # word forms hash for $parad (@{$paradigms{$wia0->{'т'}}}) { my %wf; $wf{'с'} = $wia0->{'с'}; $wf{'у'} = $wia0->{'у'}; push(@{$wfh{$parad}}, (\%wf)); } return (\@wia, \%wfh); } else { # иначе слово не имеет парадигмы return (\@wia, undef); } } my @wi = map { get_all_wi($_) } @wia; my %wfh; # word forms hash for $wi (@wi) { # если существительное неодушевленное и одушевленное, # то склоняются отдельно оба варианта if ($wia0->{'т'} eq "с" && $wi->{'о'} eq "но") { $wi->{'о'} = "н"; my $wi2 = get_all_wi($wi); for $parad (@{$paradigms{$wi2->{'т'}}}) { push(@{$wfh{$parad}}, @{inflect($wi2, $parad)}); } $wi->{'о'} = "о"; $wi2 = get_all_wi($wi); for $parad (@{$paradigms{$wi2->{'т'}}}) { push(@{$wfh{$parad}}, @{inflect($wi2, $parad)}); } $wi->{'о'} = "но"; } else { for $parad (@{$paradigms{$wia0->{'т'}}}) { push(@{$wfh{$parad}}, @{inflect($wi, $parad)}); } } # слово с факультативной особенностью склонения склоняется отдельно if (defined $wi->{'осф'}) { $wi->{'ос'} = $wi->{'осф'}; delete $wi->{'осф'}; for $parad (@{$paradigms{$wia0->{'т'}}}) { push(@{$wfh{$parad}}, @{inflect($wi, $parad)}); } $wi->{'осф'} = $wi->{'ос'}; delete $wi->{'ос'}; } } # удаляются полные дубликаты созданных парадигм while (($key,$value) = each %wfh) { my @wfh = @$value; if (@wfh > 1) { my %saw; @wfh = grep(!$saw{join("", %$_)}++, @wfh) } $wfh{$key} = \@wfh; } (\@wi, \%wfh) } =item get_all_wi -- get all word information Предварительная подготовка всех данных, необходимых для склонения/спряжения. =cut sub get_all_wi { my $wi = shift; my %wi = %$wi; if ($wi{'т'} ne "г") { # Склонение if (!defined $wi{'рм'} && defined $wi{'р'}) { $wi{'рм'} = $wi{'р'} } if (!defined $wi{'т2'}) { $wi{'т2'} = $wi{'т'} } $wi{'т2'} =~ s/^п$/а/; $wi{'т2'} =~ s/^мс-п$/м/; $wi{'т2'} =~ s/^мс$/м/; if (defined $wi{'ч2'} && $wi{'рм'} eq "м" && $wi{'и'} eq "3") { $wi{'ч'} = ""; # bad hack - WHY ??? } # if (defined $wi{'ч'} && !defined $wi{'мн'}) { # $wb = rem_vowel($wb, \%wi); # # not yet: $wi{'сб2'} = add_vowel($wb, \%wi); # } my $wb = $wi{'с'}; if (defined $wi{'мн'} && $wi{'мн'} ne ":" && $wi{'мн'} ne "от") { $wb = $wi{'мн'}; $wb =~ tr/АЕЁИОУЫЭЮЯ/аеёиоуыэюя/; $wi{'у'} = Lingua::RU::Accent::raccent($wi{'мн'},"u"); $wi{'у'} =~ s/\,.*//; # ударение для ё не нужно } if ($wi{'т2'} =~ /^[см]/) { (defined $wi{'ч'}) && ($wb =~ /[^$vйь]$/ || $wb =~ s/[йь]$//) && (($wb,$wi{'сб2'}) = (rem_vowel($wb, \%wi),$wb)) || ($wb =~ s/[$vйь]$//) } if ($wi{'т2'} =~ /^[а]/) { # ($wi{'т2'} =~ /^[ам]/) if (!(defined $wi{'фн'} && $wi{'фн'} =~ /\^п/)) { # TODO: ? wi{'фн'}->{'п','с'} ($wb =~ s/..ся$//) && ($wi{'ся'} = "",1) || ($wb =~ s/..$//) } # else rem_vowel ? } my ($exc, $excp); (defined($exc = $wi{'искл'})) && (defined($excp = $exc->{'б'})) && ($wb = $excp); $wi{'б'} = $wb; $wi{'о'} = "н" if !defined $wi{'о'}; $wi{'и2'} = $wi{'и'} = "0" if !defined $wi{'и'} || $wi{'и'} eq "0"; $wi{'и2'} = "1" if $wi{'и'} =~ /[1345]/; $wi{'и2'} = "2" if $wi{'и'} =~ /[267]/; $wi{'и2'} = "8" if $wi{'и'} =~ /[8]/; if ($wi{'т2'} eq "с") { $wi{'сф'} = $wi{'т2'}.$wi{'рм'}.$wi{'и2'}.$wi{'о'}; } elsif ($wi{'т2'} ne "ч") { $wi{'сф'} = $wi{'т2'}."м".$wi{'и2'}.$wi{'о'}; } if ($wi{'у'} =~ /^(\d+)(.*)?$/) { $wi{'уо'} = $1; $wi{'уд'} = $2 if defined $2; } } else { # Спряжение my ($vv, $i) = ($wi{'гв'}, $wi{'и'}); $wi{'нсв'} = ($vv eq "нсв" || $vv eq "св-нсв"); $wi{'св'} = ($vv eq "св" || $vv eq "св-нсв"); # if (!defined $i) { return \%wi } $wi{'тс'} = ($i =~ /^[45]$/ ? 2 : 1); if ($wi{'тс'} == 1) { $wi{'ок1'} = $wi{'ок3м'} = "ю"; $wi{'ок3е'} = "е"; } elsif ($wi{'тс'} == 2) { $wi{'ок1'} = "ю"; $wi{'ок3м'} = "я"; $wi{'ок3е'} = "и"; } my $wb = $wi{'б'} = $wi{'с'}; ($wb =~ s/с[яь]$//) && (@wi{'б','ся'} = ($wb,"")); my $wb1; my $wbi = $wb; $wbi =~ s/[тч][ьи]$//; $i == 1 && $wb =~ s/ть$// || $i == 2 && ($wb =~ s/овать$/у/ || $wb =~ s/([$schц])евать$/$1у/ || $wb =~ s/([^$schц])евать$/$1ю/) || $i == 3 && ($wb =~ s/уть$// && ($wi{'ок1'} = $wi{'ок3м'} = "у")) || $i == 4 && ($wb =~ s/ить$// && ($wb =~ /[$sch]$/ && (@wi{'ок1','ок3м'} = ("у","а")) || 1) && (defined ($wb1 = verb_ch3($wb,$wi{'ч3'})) && $wb1 =~ /[$sch]$/ && ($wi{'ок1'} = "у"))) || $i == 5 && ($wb =~ s/[аяе]ть$// && ($wb =~ /[$sch]$/ && (@wi{'ок1','ок3м'} = ("у","а")) || 1) && (defined ($wb1 = verb_ch3($wb,$wi{'ч3'})) && $wb1 =~ /[$sch]$/ && ($wi{'ок1'} = "у"))) || $i == 6 && ($wb =~ s/[ая]ть$// && ($wb =~ /[$sch]$/ && ($wi{'ок1'} = $wi{'ок3м'} = "у") || 1) && ((defined ($wi{'ч2'}) && ($wi{'ок1'} = $wi{'ок3м'} = "у")) || (defined ($wb1 = verb_ch3($wb,$wi{'ч3'})) && ($wb = $wb1) && $wb1 =~ /[$sch]$/ && ($wi{'ок1'} = $wi{'ок3м'} = "у")))) || $i == 7 && ($wb =~ s/([зс])т[иь]$/$1/ && ($wi{'ок1'} = $wi{'ок3м'} = "у")) && (defined ($ch3 = $wi{'ч3'}) && $wb =~ s/[$c]$/$ch3/) || $i == 8 && ($wb =~ s/чь$// && ($wi{'ок1'} = $wi{'ок3м'} = "у")) && ($wb1 = $wb) && (defined ($ch3 = $wi{'ч3'}) && ($wb1 .= $ch3) && ($wb = $wb1) && (($wb =~ s/г$/ж/) || ($wb =~ s/к$/ч/))) || $i == 9 && ($wb =~ s/ереть$/р/ && ($wi{'ок1'} = $wi{'ок3м'} = "у")) || $i == 10 && ($wb =~ s/(о[лр])оть$/$1/) || $i == 11 && ($wb =~ s/ить$/ь/) || $i == 12 && ($wb =~ s/греть$/гре/ || $wb =~ s/петь$/по/ || $wb =~ s/брить$/бре/ || $wb =~ s/ыть$/о/ || $wb =~ s/уть$/у/ || $wb =~ s/ить$/и/) || $i == 13 && ($wb =~ s/авать$/а/) || $i == 14 && ($wb =~ s/[ая]ть$// && ($wi{'ок1'} = $wi{'ок3м'} = "у")) && ($wb1 = $wb) && (defined ($ch3 = $wi{'ч3'}) && ($wb1 .= $ch3) && ($wb = $wb1)) || $i == 15 && ($wb =~ s/ть$/н/ && ($wi{'ок1'} = $wi{'ок3м'} = "у")) || $i == 16 && ($wb =~ s/ть$/в/ && ($wi{'ок1'} = $wi{'ок3м'} = "у")) ; @wi{'сби','сб1','сб3'} = ($wbi,($wb1 or $wb),$wb); if ($wi{'сб'}) { $wi{'сб1'} = $wi{'сб3'} = $wi{'сб'}; } # Исключения my ($exc, $excp); if (defined($exc = $wi{'искл'})) { if ($wi{'св'}) { # дублируются все формы исключений будущего времени в настоящее foreach $key (sort(keys %{$exc})) { (($key2 = $key) =~ s/^б/н/) && ($exc->{$key2} = $exc->{$key}); } } if (!defined($exc->{'н2е'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3е'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/т(с[ья])?$/"шь".(defined $1 && "ся")/e; \%h } @{$excp}; $exc->{'н2е'} = \@wfh; } if (!defined($exc->{'н1м'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3е'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/т(с[ья])?$/"м".(defined $1 && "ся")/e; \%h } @{$excp}; $exc->{'н1м'} = \@wfh; } if (!defined($exc->{'н2м'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3е'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/т(с[ья])?$/"те".(defined $1 && "сь")/e; \%h } @{$excp}; $exc->{'н2м'} = \@wfh; } if (!defined($exc->{'н3м'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3е'})) { my ($excp1, $j) = ($exc->{'н1е'}, 0); my @wfh = map { my %h = %{$_}; if ($h{'с'} =~ /[её]т(с[ья])?$/ && defined($excp1)) { $h{'с'} = defined($excp1->[$j]) && $excp1->[$j]->{'с'} || $excp1->[0]->{'с'}; $h{'с'} =~ s/(с[ья])?$/"т".(defined $1 && $1)/e; } else { ($h{'с'} =~ s/([$sch])ит(с[ья])?$/"$1ат".(defined $2 && $2)/e) || ($h{'с'} =~ s/ит(с[ья])?$/"ят".(defined $1 && $1)/e); } ($h{'с'} =~ s/([$v])с[ья]$/$1сь/) || ($h{'с'} =~ s/с[ья]$/ся/); $j++; \%h } @{$excp}; $exc->{'н3м'} = \@wfh; } if (!defined($exc->{'!2е'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3м'})) { my @wfh = map { my %h = %{$_}; ($h{'с'} =~ s/([$c])[юуяа]т(с[ья])?$/"$1и".(defined $2 && "сь")/e) && ($h{'у'} = length($h{'с'}) - (defined $2 && length($2) || 0)) || ($h{'с'} =~ s/([$v])[юуяа]т(с[ья])?$/"$1й".(defined $2 && "ся")/e) # NB! исправленное правило: # на стр. 89: "ударение там же, где в 3 мн." # например: "обЯзывают" -> "обЯзывай" # но "поЮт" -> "пой": по правилу ударение должно быть на букве "й"! # поэтому здесь ударение сдвигается на одну букву влево && (($h{'у'} == length($h{'с'})) && ($h{'у'} = length($h{'с'}) - 1)); \%h } @{$excp}; $exc->{'!2е'} = \@wfh; } if (!defined($exc->{'!2м'}) && defined($excp = $exc->{'!2е'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/(с[ья])?$/"те".(defined $1 && "сь")/e; \%h } @{$excp}; $exc->{'!2м'} = \@wfh; } if (!defined($exc->{'дн'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3м'})) { my ($excp1, $j) = ($exc->{'н1е'}, 0); my @wfh = map { my %h = %{$_}; $h{'у'} = defined($excp1->[$j]) && $excp1->[$j]->{'у'} || $excp1->[0]->{'у'}; ($h{'с'} =~ s/([$sch])[юуиа]т(с[ья])?$/"$1а".(defined $2 && "сь")/e) || ($h{'с'} =~ s/[юуиая]т(с[ья])?$/"я".(defined $1 && "сь")/e); ($wi{'св'}) && ($h{'ф'} = "фн"); # 'св' && ('н3е' || 'б3е') ??? $j++; \%h } @{$excp}; $exc->{'дн'} = \@wfh; } if (!defined($exc->{'чнд'}) && defined($exc->{'н1е'}) && defined($excp = $exc->{'н3м'})) { my ($excp1, $j) = ($exc->{'н1е'}, 0); my @wfh = map { my %h = %{$_}; ($h{'с'} =~ s/т(с[ья])?$/"щий".(defined $1 && "ся")/e); ($h{'с'} =~ /[ая]щий(с[ья])?$/) && ($h{'у'} = defined($excp1->[$j]) && $excp1->[$j]->{'у'} || $excp1->[0]->{'у'}); ($wi{'св'}) && ($h{'ф'} = "фн"); # 'св' && ('н3е' || 'б3е') ??? $j++; \%h } @{$excp}; $exc->{'чнд'} = \@wfh; } if (!defined($exc->{'чнс'}) && defined($exc->{'н1е'}) && defined($exc->{'н3е'}) && defined($excp = $exc->{'н1м'})) { my ($excp1, $excp3, $j) = ($exc->{'н1е'}, $exc->{'н3е'}, 0); my @wfh = map { my %h = %{$_}; my ($excpw3, $excpa3) = defined($excp3->[$j]) ? ($excp3->[$j]->{'с'}, $excp3->[$j]->{'у'}) : ($excp3->[0]->{'с'}, $excp3->[0]->{'у'}); ($h{'с'} =~ s/(с[ья])?$/"ый".(defined $1 && "ся")/e); ($h{'с'} =~ /имый(с[ья])?$/) && ($h{'у'} = defined($excp1->[$j]) && $excp1->[$j]->{'у'} || $excp1->[0]->{'у'}); !(($excpw3 =~ /ит(с[ья])?$/) || ($excpw3 =~ /[$v]ет(с[ья])?$/) && ($excpa3 != length($excpw3)-1-(defined $1 && length($1) || 0))) && ($h{'ф'} = "фн"); (($wi{'св'}) || ($wi{'гп'} ne "п")) && ($h{'ф'} = "фн"); # 'св' && ('н3е' || 'б3е') ??? $j++; \%h } @{$excp}; $exc->{'чнс'} = \@wfh; } if (!defined($exc->{'пес'}) && defined($exc->{'пем'}) && defined($excp = $exc->{'пеж'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/а(с[ья])?$/"о".(defined $1 && $1)/e; \%h } @{$excp}; $exc->{'пес'} = \@wfh; } if (!defined($exc->{'пм'}) && defined($exc->{'пем'}) && defined($excp = $exc->{'пеж'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/а(с[ья])?$/"и".(defined $1 && $1)/e; \%h } @{$excp}; $exc->{'пм'} = \@wfh; } if (!defined($exc->{'дп'}) && defined($excp = $exc->{'чпд'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/й(с[ья])?$/(defined $1 && "сь")/e; \%h } @{$excp}; $exc->{'дп'} = \@wfh; } if (!defined($exc->{'чпд'}) && defined($exc->{'пеж'}) && defined($excp = $exc->{'пем'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/л(с[ья])?$/"вший".(defined $1 && "ся")/e || $h{'с'} =~ s/(с[ья])?$/"ший".(defined $1 && "ся")/e; \%h } @{$excp}; $exc->{'чпд'} = \@wfh; } if (!defined($exc->{'дп'}) && defined($exc->{'пеж'}) && defined($excp = $exc->{'пем'})) { my @wfh = map { my %h = %{$_}; $h{'с'} =~ s/л(с[ья])?$/"вши".(defined $1 && "сь")/e || $h{'с'} =~ s/(с[ья])?$/"ши".(defined $1 && "сь")/e; \%h } @{$excp}; $exc->{'дп'} = \@wfh; } if ($wi{'св'}) { foreach $key (sort(keys %{$exc})) { (($key2 = $key) =~ s/^н/б/) && ($exc->{$key2} = delete $exc->{$key}); } } $wi{'искл'} = $exc; } } \%wi } =item verb_ch3 -- convert verb base Стандартные чередования согласных основы форм глаголов (стр.78). =cut sub verb_ch3 { my ($wb, $ch3) = @_; defined $ch3 && $wb =~ s/[$c]$/$ch3/ || $wb =~ s/([бпвфм])$/$1л/ || $wb =~ s/с[тк]$/щ/ || substr($wb,-1,1) =~ tr/зсдтгкх/жшжчжчш/ || ($wb = undef); $wb } =item inflect -- word inflection Склонение или спряжение слова. =cut sub inflect { if ($_[0]->{'т'} ne "г") { decline(@_); } else { conjugate(@_); } } =item decline -- declension Склонение существительных, прилагательных, местоимений и числительных. =cut sub decline { my ($wi, $p) = @_; # $p - падеж (парадигмы) my %wi = %$wi; # %wi (word information) my $we; # $we (word ending) - новое окончание словоформы my %wf; # %wf (word forms) - хеш всех словоформ (парадигмы) # $wb (word base) - основа слова # $i (index) - индекс # $i2 - дополнительный индекс # $an (animate) - одушевлённость # $wfi (word form info) - информация о словоформе # $ch - чередование my ($wb, $i, $i2, $an, $wfi, $ch) = ($wi{'б'}, $wi{'и'}, $wi{'и2'}, $wi{'о'}, $wi{'сф'}, $wi{'ч'}); my ($t, $t2) = ($wi{'т'}, $wi{'т2'}); # $g (gender) - род морфологический my $g = $wi{'рм'} || "м"; my $u1 = $wi{'у1'}; # $ae (accented ending) - ударное окончание: "у" - ударное, "б" - безударное # $ac (accent) - новое ударение в словоформе my ($ae, $ac); # $exc (exception) - ислючения my ($exc, $excp); # @wfh (word forms hash) my @wfh; my $po = $p; # сохранить начальное значение $p my $pf = ($t eq "п" && $p =~ s/^([кп])(..)/$2/) && $1 || ""; if ($t2 =~ /^[ам]/) { ($p =~ s/([но])$//) && ($an = $1) && (substr($wfi, 3, 1) = $an); if ($pf eq "к") { (defined $wi{'у2'}) && ($u1 = $wi{'у2'}); substr($wfi, 0, 1) = "к"; if ($t2 eq "м") { $wf{'ф'} = "фн" } # для т:п т2:мс ч } if ($p eq "с") { # Построение сравнительной степени прилагательных (стр.35) if ($t2 eq "м") { $wb =~ s/[$vйь]$//; $wf{'ф'} = "фн"; } if ($wb =~ /[^кгх]$/) { $we = "ее"; ($u1 eq "a" && !defined $wi{'у2'}) && ($ae = "б") || ($ae = "у"); } else { substr($wb,length($wb)-1,1) =~ tr/кгх/чжш/; $we = "е"; (($wb.$we) =~ /([$v][^$v]*){2}$/) && ($ac = length($`) + 1); # $ae = "б"; # ??? полнёхОньче слабенЕче копОтче } } if ($p =~ /(..)(.)?/) { ($p, $g) = ($1, ($2 or $g)); substr($wfi, 1, 1) = $g } } # Винительный падеж (стр.38) if ($p eq "ве" && !(defined($exc = $wi{'искл'}) && defined($exc->{$po}))) { if ($g eq "с" || $g eq "м" && $an eq "н") { $p = "ие"; $po =~ s/в(..?).?/и$1/ } elsif ($g eq "м" && $an eq "о") { $p = "ре"; $po =~ s/в(..?).?/р$1/ } } elsif ($p eq "вм" && !(defined($exc = $wi{'искл'}) && defined($exc->{$po}))) { if ($an eq "н") { $p = "им"; $po =~ s/в(.).?/и$1/ } elsif ($an eq "о") { $p = "рм"; $po =~ s/в(.).?/р$1/ } } # TODO: copy next to get_all_wi !!! HOW ??? if (defined($exc = $wi{'искл'})) { if (defined($excp = $exc->{$po})) { # (($t eq "п" && $p !~ /^с/) && "$pf$p$g" || $p) @wfh = @{$excp}; goto LABEL1; } elsif ($p eq "тм" && defined($excp = $exc->{(($t eq "п") && "$pfдм$g" || "дм")})) { # (($t eq "п") && "$pfдм$g" || "дм") @wfh = map { my %h = %{$_}; $h{'с'} =~ s/$/и/; \%h } @{$excp}; goto LABEL1; } elsif ($p eq "пм" && defined($excp = $exc->{(($t eq "п") && "$pfдм$g" || "дм")})) { # (($t eq "п") && "$pfдм$g" || "дм") @wfh = map { my %h = %{$_}; $h{'с'} =~ s/м$/х/; \%h } @{$excp}; goto LABEL1; } # return $excp; } if ($t2 eq "ч") { $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; $wf{'ф'} = "фн"; return [\%wf] } if ($i eq "0") { $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; return [\%wf] } # if (defined $ch && $p eq "ие") { # bad hack: не работает для мн.ч. и к.ф. # $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; return [\%wf] # } if (defined $wi{'ч2'} && $g eq "с" && $i eq "8") { if ($p ne "ие") { # стр.53 $wb .= "ен"; } else { $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; return [\%wf] } if ($p =~ /.м/) { substr($wfi, 2, 1) = "1"; } #$i = $i2 = "1" } } # Схемы ударения: $wf{'у1'} - окончание ударное/безударное (у/б) # TODO: this table could be put into hash for performance if ($pf ne "к" && $p ne "с") { # схема ударения полных форм (стр.31) if ($u1 =~ /^a/ || $u1 eq "b1" && $p eq "те" || $u1 eq "c" && $p =~ /.е/ || $u1 =~ /^d/ && $p =~ /.м/ || $u1 eq "d1" && $p eq "ве" || $u1 eq "e" && ($p =~ /.е/ || $p eq "им") || $u1 =~ /^f/ && $p eq "им" || $u1 eq "f1" && $p eq "ве" || $u1 eq "f2" && $p eq "те") { $ae = "б" } else { $ae = "у" } } elsif ($pf eq "к") { # схема ударения кратких форм (стр.33) if ($u1 =~ /^a/ || $u1 =~ /^c/ && !($p eq "ие" && $g eq "ж")) # $p =~ /и(ес|м)/ { $ae = "б" } else { $ae = "у" } } if (defined $wi{'ос'}) { if ($t2 eq "с") { if ($wi{'ос'} =~ /1/ && $p eq "им") { if ($g eq "м") { ($i2 eq "1") && ($we = "а") || $i2 eq "2" && ($we = "я"); } elsif ($g eq "с") { ($i =~ /[15]/) && ($we = "ы") || ($we = "и"); # TEST: } } elsif ($wi{'ос'} =~ /2/ && $p eq "рм") { if ($g eq "м") { ($i2 eq "1") && ($we = "",1) || ($i2 eq "2") && ($we = "ь"); # NOT USED ??? #$i2 eq "1" && ($we = ""); } elsif ($g eq "с") { # TODO: fix this according to page 54 ($i2 eq "1") && ($we = "ов") || ($i2 eq "2") && ($ae eq "б" && ($we = "ев") || ($we = "ёв")); } elsif ($g eq "ж") { $we = "ей" } } } elsif ($t2 eq "а") { if ($wi{'ос'} =~ /1/) { ($pf eq "к") && ($g eq "м") && ($p eq "ие") && ($wb =~ s/н$//) && ($we = "",1) && (undef $ch,1); } elsif ($wi{'ос'} =~ /2/) { ($pf eq "к") && ($wb =~ s/н$//) && (undef $ch,1) || ($p eq "с") && ($ac = $wi{'уо'}); } } } # Дополнительные особенности окончаний субстантивного склонения # Отличия типов склонения (стр.29) if ($t2 eq "с" && !defined $we) { if ($i eq "4" && $p eq "рм") { if ($g eq "м") { $we = "ей" } elsif ($g eq "ж" || $g eq "с") { if ($ae eq "б") { $we = "" } else { $we = "ей" } } } if ($i eq "6" || $i eq "7") { if ($p eq "рм") { if ($g eq "м") { if ($ae eq "б") { $we = "ев" } else { $we = "ёв" } } elsif ($g eq "ж" || $g eq "с") { $we = "й" } } if ($i eq "7" && ($p eq "де" && $g eq "ж" || $p eq "пе")) { if ($ae eq "б") { $we = "и" } else { $we = "е" } } } ##bad: if ($i eq "8" && $p eq "рм") { $we = "ей" } # corrected in ITable.pm } if ($t2 eq "с" && defined $wi{'ч2'}) { # (стр.42) if ($g eq "м") { if ($i eq "1" && $p =~ /^.м$/) { $wb =~ s/ин$//; if ($p eq "им") { $we = "е" } elsif ($p eq "рм") { $we = "" } # Если в ед. числе ударение на "-ин", то при схеме ударения 'а' # оно переходит во мн. числе на один слог влево if ($u1 eq "a" && length($wb) < $wi{'уо'} && $wb =~ /[$v][^$v]*?$/) { $ac = length($`) + 1; } } elsif ($i eq "3") { if ($p =~ /^.е$/) { ##bad: $ch = "" # moved to get_all_wi } elsif ($p =~ /^.м$/) { undef $ch; # hack to pass changing wb to wb2 for plurals ##bad: my $wfi = $wi{'сф'}; if ($wb =~ s/ёно?к$/ят/ || $wb =~ s/оно?к$/ат/) { substr($wfi, 1, 2) = "с1"; } if ($wb =~ s/ёноче?к$/ятк/ || $wb =~ s/оноче?к$/атк/) { substr($wfi, 1, 2) = "ж1"; } ($p =~ /^рм$/) && ($wb =~ s/тк$/ток/); ##bad: $we = $wi_we_tab{$wfi.$ae}->{$p}; # print "\n<",$wfi.$ae,":",$we,">\n"; } } } } if (!defined $we) { $we = $wi_we_tab{$wfi.$ae}->{$p}; # Отличия типов склонения if ($i eq "3") { $we =~ s/^ы/и/ } elsif ($i eq "4") { $we =~ s/^ы/и/; $we =~ s/^о/е/ if ($ae eq "б") } elsif ($i eq "5") { $we =~ s/^о/е/ if ($ae eq "б") } elsif ($i eq "6" || $i eq "7") { $we =~ s/ь/й/ } elsif ($i eq "8" && $wi{'б'} =~ /[$schц]$/) { $we =~ s/^я/а/ } } # NB! Следующий блок должен быть расположен до нахождения ударения, # так как нужно знать беглую гласную для нахождения правильного ударения, # но в то же время он должен быть расположен после нахождения ударения, # так как для нахождения беглой гласной нужно знать ударение! if (defined $ch && $we =~ /^(й|ью?)?$/) { if (defined $wi{'сб2'}) { $wb = $wi{'сб2'} } ##bad: substr($wb, length($wb)-length($&)-1, 0) = "о" ##bad: if ($p eq "рм") { ##bad: if ($g eq "с" || $g eq "ж" && $i ne "8") else { $i eq "6" && ($ae eq "у" && $wb =~ s/ь$/е/ || $ae eq "б" && $wb =~ s/ь$/и/) || $wb =~ s/[ьй]ц$/ец/ || $ae eq "у" && $wb =~ s/[ьй]([$c])$/ё$1/ || $ae eq "б" && $wb =~ s/[ьй]([$c])$/е$1/ || $wb =~ s/([кгх])([$c])$/$1о$2/ || $wb =~ s/([^$schц])([кгх])$/$1о$2/ || $wb =~ s/ц$/ец/ || $ae eq "у" && $wb =~ s/([$schц])([$c])$/$1о$2/ || $ae eq "у" && $wb =~ s/([$c])$/ё$1/ || $ae eq "б" && $wb =~ s/([$c])$/е$1/; ($i eq "2" && $wi{'у1'} eq "a" && $we eq "ь" && ($g eq "ж" && $wi{'с'} =~ /ня$/ || $wi{'с'} =~ /ний$/) && ($we = "")); } # elsif ($g eq "м" && $we eq "" && !defined $wi{'ч2'}) { ##bad: $wb = $wi{'с'}; # bad hack ##bad: } ##bad: } } # Дополнительные правила об ударении (стр.34) if (!defined $ac) { $ac = $a; if ($ae eq "б") { # Если в исходной форме ударение на основе (не на окончании) ## bad: if ($wi{'уо'} < length(defined($wi{'сб2'}) && $wi{'сб2'} || $wi{'б'})) { if ($wi{'у1'} =~ /^[ace]/ || $wi{'у1'} eq "b1") { # то ударение падает на тот же слог основы # NB! "b1" добавлено вопреки правилам, # т.к. в Т.ед. получалось бы "лЮбовью" вместо "любОвью": # стр.31: в b1 И.ед. ударение на окончании, # стр.32: в b1 Т.ед. ударение на основе, # стр.34: если в И.ед. ударение на окончании, то в Т.ед. # на предпоследний слог основы, то есть "лЮбовью" $ac = $wi{'уо'} } else { # В словах схемы f или f1 - на первый слог основы if ($ae =~ /^f/ && $wb =~ /^[^$v]*?[$v]/) { $ac = length($&) } else { # Если основа содержит беглую гласную, то на предпоследний слог основы if (defined $ch && $we =~ /^(й|ью?)?$/ && # ($g eq "с" || $g eq "ж" && $i ne "8") && $p eq "рм" && $wb =~ /[$v][^$v]*?[$v][^$v]*?$/) { # ??? $p eq "рм" $ac = length($`) + 1 } elsif ($wb =~ /[$v][^$v]*?$/) { $ac = length($`) + 1 } } } } else { # Иначе если ударение внутри окончания # (если окончание не содержит гласной, то сдвигаем на один слог влево) if ($we !~ /[$v]/ && $wb =~ /[$v][^$v]*?$/) { $ac = length($`) + 1 } # Иначе ударение падает на первый слог окончания # (за исключением следующего условия) else { if ($t2 eq "м" && $we =~ /^([ое]го|[ое]му)$/) { $ac = length($wb) + length($we); } else { $ac = length($wb) + 1; } } } } $wf{'у'} = $ac; if (defined $wi{'чё'}) { # стр.34 if (substr($wb, $wi{'уо'}-1, 1) eq "ё" && $wf{'у'} != $wi{'уо'}) { substr($wb, $wi{'уо'}-1, 1) =~ tr(ё)(е); } if ($p eq "рм" || substr($wb, $wf{'у'}-1) !~ /.е/) { # bad hack substr($wb, $wf{'у'}-1, 1) =~ tr(е)(ё); } } $wf{'у'} .= $wi{'уд'} if defined $wi{'уд'}; # дополнительные ударения $wb .= $we; $wb .= "ся" if (defined $wi{'ся'}); $wf{'с'} = $wb; # $p = "$pf$p$g" if ($t2 eq "а" && $p !~ /^с/); $p = $po; $wf{'ф'} = "фз" if ($p ne "ие" && defined $wi{'фз'} && $p =~ /$wi{'фз'}/); $wf{'ф'} = "фп" if ($p ne "ие" && defined $wi{'фп'} && $p =~ /$wi{'фп'}/); $wf{'ф'} = "фн" if ($p ne "ие" && defined $wi{'фн'} && $p =~ /$wi{'фн'}/); $wf{'ф'} = "фн" if (defined $wi{'мн'} && $p =~ /^.е/); $wf{'ф'} = $wi{'ф'} if (defined $wi{'ф'}); @wfh = (\%wf); if (($p eq 'пе') && ((defined $wi{'п2'}) || (defined $wi{'п2ф'}))) { my $wf1 = inflect($wi, 'де')->[0]; $wf1->{'с'} =~ s/ё/е/g; $wf1->{'у'} = length($wf1->{'с'}); $wf1->{'п2'} = (defined $wi{'п2'}) && ($wi{'п2'}) || ($wi{'п2ф'}); push(@wfh, $wf1); if (defined $wi{'п2ф'}) { my %wf2 = %wf; $wf2{'п2'} = $wi{'п2ф'}; push(@wfh, \%wf2); } } if (($p eq 'ре') && (defined $wi{'р2'})) { my $wf1 = inflect($wi, 'де')->[0]; $wf1->{'р2'} = $wi{'р2'}; push(@wfh, $wf1); } LABEL1: ##bad: $wf{a} = $wi{a}; # дополнительные особенности ##bad: [\%wf, \%wf] #bad: # if ($fic && $g eq "ж" && $p =~ /^п?те/) { # my %wf1 = %{$wfh[0]}; # $wf1{'с'} =~ s/й$/ю/ && push(@wfh, \%wf1); # } if ($fic && $g eq "ж" && $p =~ /^п?те/) { my $i = 1; for $wfhi (@wfh) { if ($wfhi->{'с'} =~ /й$/) { my %wf1 = %{$wfhi}; $wf1{'с'} =~ s/й$/ю/ && splice(@wfh,$i,0,\%wf1); } $i++; } } #bad: # if ($p eq "с" && $wfh[0]->{'с'} =~ /ее$/) { # $we eq "ее" # my %wf1 = %{$wfh[0]}; # $wf1{'с'} =~ s/е$/й/ && splice(@wfh,1,0,\%wf1); # } if ($p eq "с") { my $i = 1; for $wfhi (@wfh) { if ($wfhi->{'с'} =~ /ее$/) { my %wf1 = %{$wfhi}; $wf1{'с'} =~ s/е$/й/ && splice(@wfh,$i,0,\%wf1); } $i++; } } if ($p =~ /^к/ && $u1 =~ m([12])) { my %wi1 = %wi; ($u1 eq "a1" && ($p eq "киеж") || $u1 eq "c1" && ($p eq "кимм") || $u1 eq "c2" && ($p eq "киес" || $p eq "кимм")) && ($wi1{'у2'} = "b") && (push(@wfh, @{inflect(\%wi1, $p)})) || ($u1 eq "b1" && $p eq "кимм") && ($wi1{'у2'} = "a") && (unshift(@wfh, @{inflect(\%wi1, $p)})); } \@wfh } =item conjugate(???) - спряжение глаголов (verb conjugation) =cut sub conjugate { my ($wi, $p) = @_; # $p - парадигма (падеж) my %wi = %$wi; my ($wb, $we); my %wf; my ($vv, $sv, $nsv, $i) = ($wi{'гв'}, $wi{'св'}, $wi{'нсв'}, $wi{'и'}); my ($u1, $a) = ($wi{'у1'}, $wi{'у'}); my $os = (defined $wi{'ос'}) && $wi{'ос'} || "0"; my $osf = (defined $wi{'осф'}) && $wi{'осф'} || "0"; my @wfh; $we = ""; # bad? if ($p eq "и") { $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; return [\%wf] } # Исключения if (defined($exc = $wi{'искл'})) { if (($p ne "пем") && defined($excp = $exc->{$p})) { @wfh = @{$excp}; goto LABEL2; } } # нет форм будущего несовершенного и настоящего совершенного if (!($nsv && $sv) && (($nsv && $p =~ /^б(..)$/) || ($sv && $p =~ /^н(..)$/))) { $wf{'с'} = ""; $wf{'у'} = 0; $wf{'ф'} = "фн"; return [\%wf]; } if ($p =~ /^(ч..)-(.*)/) { # "чнд","чпд","чнс","чпс" my ($p2,$s2) = ($1,$2); # swi - saved word information # swf - saved word forms my $swi2 = $wi{"swi$p2"}; if (!defined $swi2) { my $wfs2 = $wi{"swf$p2"} || (inflect($wi, $p2) && $wi->{"swf$p2"}); my @wfsh; for $wfp2 (@$wfs2) { my %wf2; my ($wfw2,$wfa2) = ($wfp2->{'с'},$wfp2->{'у'}); @wf2{'с','у','т','и','у1'} = ($wfw2,$wfa2,'п',($p2=~/^ч.д/ && '4' || '1'),'a'); (defined $wfp2->{'ф'}) && ($wf2{'ф'} = $wfp2->{'ф'}); (defined $wfp2->{'з'}) && ($wf2{'з'} = $wfp2->{'з'}); if ($p2 eq "чпс") { ($wfw2 =~ /[аяе]нный$/) && (@wf2{'ч','ос'} = (1,2)) || ($wfw2 =~ /ённый$/) && (@wf2{'ч','чё','ос','у2'} = (1,1,2,'b')) || ($wfw2 =~ /тый$/) && defined $wi{'у2'} && $wi{'у2'} eq "c" && ($wf2{'у2'} = 'c'); } push(@wfsh, get_all_wi(\%wf2)); } $swi2 = $wi->{"swi$p2"} = \@wfsh; } @wfh = map { @{inflect($_, $s2)} } @$swi2; ($s2=~/^к/) && ($p2=~/^ч.д/) && (@wfh = map { ($_->{'ф'} = "фн"); $_ } @wfh); #bad: # my $wfs2 = $wi{"swf$p2"} || (inflect($wi, $p2) && $wi->{"swf$p2"}); # my @wfh; # for $wfp2 (@$wfs2) { # my %wf2; # @wf2{'с', 'у', 'т','и', 'у1'} = # ($wfp2->{'с'},$wfp2->{'у'},'п',($p2=~/^ч.д/ && '4' || '1'),'a'); # push(@wfh, @{inflect(get_all_wi(\%wf2), $s2)}); # } return \@wfh; } # currently exceptions not implemented ??? if (!defined $i) { $wf{'с'} = $wi{'с'}; $wf{'у'} = $wi{'у'}; return [\%wf] } # $ae - ударное окончание: "у" - ударное, "б" - безударное (по умолчанию) # $ac (accent) - новое ударение в словоформе my ($ae, $ac) = ("б"); # Личные формы настоящего времени несов.вида и буд.вр. сов.вида if ($p =~ /^[нб](..)$/) { my $p2 = $1; $wb = ($p2 eq "1е" || $p2 eq "3м" && $wi{'тс'} == 1) && $wi{'сб1'} || $wi{'сб3'}; $p2 eq "1е" && ($we = $wi{'ок1'}, $ae = "у") || $p2 eq "2е" && ($we = $wi{'ок3е'}."шь") || $p2 eq "3е" && ($we = $wi{'ок3е'}."т") || $p2 eq "1м" && ($we = $wi{'ок3е'}."м") || $p2 eq "2м" && ($we = $wi{'ок3е'}."те") || $p2 eq "3м" && ($we = $wi{'ок3м'}."т"); ($u1 eq "c1") && ($p2 =~ /^[123]м$/) && ($ae = "у"); } # Личные формы прошедшего времени elsif ($p =~ /^п([ем][мжс]?)$/) { $wb = $wi{'сби'}; (($i == 7 || $i == 8) && ($wb = $wi{'сб1'}, $wb =~ s/[тд]$//, 1)) || (($i == 9) && ($wb =~ s/е$//, 1)) || (($i == 3) && (defined $wi{'ч2'}) && ($os !~ /5/ || $p ne "пем") && ($wb =~ s/ну$//)); # (($os !~ /6/) && (warn "5 without 6 is impossible!")))); # (($os !~ /5/ || $p ne "пем") && ($wb =~ s/ну$//))); my $u2 = $wi{'у2'}; (defined $u2) && ($u1 = $u2,1) || ($u1 = "a"); $we = "л"; ($wb =~ /[$c]$/) && ($we = ""); $p eq "пеж" && ($wb .= "л", $we = "а", $ae = "у") || $p eq "пес" && ($wb .= "л", $we = "о") || $p eq "пм" && ($wb .= "л", $we = "и"); } # Повелительное наклонение elsif ($p =~ /^!/) { $wb = ($i != 13) && ($wi{'тс'} == 1 && $wi{'сб1'} || $wi{'сб3'}) || $wi{'сби'}; $we = ($wb =~ /[$v]$/) && ($i == 4 && ($u1 ne "a" || $wb =~ /^вы/) && "и" || "й") || ( $u1 ne "a" && "и" || ($wb =~ /^вы/ || $wb =~ /[$c]ь?[$c]$/ || $wb =~ /щ$/) && "и" || "ь"); ($i == 11) && ($wb =~ s/ь$/е/) && ($we = "й"); ($p =~ /^!2[ем]$/) && ($ae = "у"); ($os =~ /2/) && ($we = (($wb =~ /[$v]$/) && "й" || "ь")); ($os =~ /3/) && ($we = (($p eq "!2е") && "и" || "ь")); ($osf =~ /3/) && (($p eq "!2е") && ($os !~ /3/) || ($p eq "!2м")) && ($we = "ь"); } # Действительное причастие настоящего времени elsif ($p eq "чнд") { if (!$nsv) { $wf{'ф'} = "фн" } $wb = $wi{'сб3'}; $we = $wi{'ок3м'}."щий"; $ae = "у" if $wi{'тс'} == 2; } # Деепричастие настоящего времени elsif ($p eq "дн") { if (!($nsv && $i =~ /^([124-7]|1[0236])$/)) { # $wf{'с'} = ""; $wf{'у'} = 0; return [\%wf]; $wf{'ф'} = "фн"; } $wb = ($i == 13) && $wi{'сби'} || $wi{'сб3'}; $we = ($wb =~ /[^$sch]$/) && "я" || "а"; ($i == 13) && ($ac = $a) || ($ae = "у"); } # Действительное причастие прошедшего времени elsif ($p eq "чпд") { # ($wb, $ac) = @{$wi{"sfпем"} || (inflect($wi, "пем") && $wi->{"sfпем"})}; my $wf2 = $wi{"swfпем"} || (inflect($wi, "пем") && $wi->{"swfпем"}); ($wb, $ac) = ($wf2->[0]->{'с'},$wf2->[0]->{'у'}); $wb =~ s/с[яь]$//; $wb =~ s/л$/в/; $we = "ший"; ($i == 7) && $wi{'б'} =~ /сти$/ && (defined $wi{'ч3'}) && ($wi{'ч3'} =~ /^[тд]$/) && ($wb = $wi{'сб1'}); ($os =~ /1/ || $osf =~ /1/) && ($i != 9) && ($ac = $a); ($os =~ /6/) && ($wb !~ /нув?/) && ($wb =~ s/в?$/нув/); } # Деепричастие прошедшего времени elsif ($p eq "дп") { # ($wb, $ac) = @{$wi{"sfчпд"} || (inflect($wi, "чпд") && $wi->{"sfчпд"})}; my $wf2 = $wi{"swfчпд"} || (inflect($wi, "чпд") && $wi->{"swfчпд"}); ($wb, $ac) = ($wf2->[0]->{'с'},$wf2->[0]->{'у'}); $wb =~ s/с[яь]$//; ($wb =~ s/й$//); } # Страдательное причастие настоящего времени elsif ($p eq "чнс") { if ($nsv && $wi{'гп'} eq "п") { if ($u1 eq "a" && ($i =~ /^([12]|12)$/ || $i eq "9" && $wi{'б'} =~ /ять$/) || $i == 13) { # пустой блок } elsif ($i == 4 || $i == 5 || $i == 7 || $i == 6 && ($wi{'б'} =~ /ять$/ || defined $wi{'ч2'})) { # $wf{'ф'} = "фз"; # ? } else { $wf{'ф'} = "фн" } } else { $wf{'ф'} = "фн" } $wb = ($i == 13) && $wi{'сби'} || $wi{'сб3'}; $we = $wi{'ок3е'}."мый"; ($i == 13) && ($ac = $a) || ($wi{'тс'} == 2) && ($ae = "у"); } # Страдательное причастие прошедшего времени elsif ($p eq "чпс") { if ($wi{'гп'} eq "п" && !($nsv && defined $wi{'гпр'})) { # if ($nsv) { $wf{'ф'} = "фз" } } else { $wf{'ф'} = "фн" } if ($i != 14 && $wi{'б'} =~ /[ая]ть$/) { $wb = $wi{'сби'}; $we = "нный"; # ($wb, $we) = (($wb.$we) =~ /(.*)(.{5})$/); # bad hack if ($wi{'б'} =~ /([$v][^$v]*)[$v][^$v]*$/ && $a == length($`) + length($1) + 1) { $ac = length($`) + 1; # substr($wb,$ac-1,1) =~ tr/е/ё/; # my own rule! } else { $ac = $a } } elsif ($i == 4 || $i == 5 && $wi{'б'} =~ /еть$/) { $wb = $wi{'сб1'}; $we = "енный"; if ($i == 4) { $ae = "б" } elsif ($i == 5) { # так же как 3 & 10 if ($wi{'сби'} =~ /([$v][^$v]*)[$v][^$v]*$/ && $a == length($`) + length($1) + 1) { $ac = length($`) + 1 } else { $ac = $a } } } elsif ($i == 1 && ($wi{'б'} =~ /одолеть$/ || $wi{'б'} =~ /печатлеть$/)) { $wb = $wi{'с'}; $wb =~ s/еть$//; $we = "енный"; $we =~ s/^е/ё/; $ac = length($wb) + 1 } elsif ($i == 7 || $i == 8) { $wb = $wi{'сб3'}; $we = "енный"; my $u2 = $wi{'у2'}; (defined $u2) && ($u1 = $u2,1) || ($u1 = "a"); } elsif ($i == 3 || $i == 10) { $wb = $wi{'сби'}; $we = "тый"; # так же как 5 if ($wi{'сби'} =~ /([$v][^$v]*)[$v][^$v]*$/ && $a == length($`) + length($1) + 1) { $ac = length($`) + 1 } else { $ac = $a } } elsif ($i =~ /^(9|1[12456])$/) { # ($wb, $ac) = @{$wi{"sfпем"} || (inflect($wi, "пем") && $wi->{"sfпем"})}; my $wf2 = $wi{"swfпем"} || (inflect($wi, "пем") && $wi->{"swfпем"}); ($wb, $ac) = ($wf2->[0]->{'с'},$wf2->[0]->{'у'}); $wb =~ s/с[яь]$//; $wb =~ s/л$//; $we = "тый"; } else { #bad: # if (!defined $wi{'фн'}) { warn "прич.страд.???\n" } # $wf{'с'} = ""; $wf{'у'} = 0; return [\%wf]; $wb = $wi{'сби'}; $we = "нный"; $wf{'ф'} = "фн" } (defined $wi{'гпс'}) && ($wb =~ s/[$c]$/$wi{'гпс'}/); ($os =~ /7/) && (($wb.$we) =~ /[$v]нный$/) && #(print "!:($wb.$we)\n") && ($ae = "у"); ($ac = length($`) + 1) && ($we =~ s/^е/ё/); # copy from next ($os =~ /8/) && (($wb.$we) =~ /([$v][^$v]*){3}$/) && ($ac = length($`) + 1); } if (!defined $ac) { $ac = $a; if (($u1 eq "a") || ($u1 =~ /^c/) && ($ae eq "б")) { # ($u1 eq "c") ($ac >= length($wb)) && ($wb =~ /[$v][^$v]*?$/) && ($ac = length($`) + 1) ##bad: || substr($wb,$ac-1,1) !~ /^[$v]$/ && ($ac += 1) # hack for additional consonant } else { ($we =~ /[$v]/) && ($ac = length($wb) + length($`) + 1) || ($wb =~ /[$v][^$v]*?$/) && ($ac = length($`) + 1); ($we =~ s/^е/ё/); ($p eq "чнс") && ($wb =~ /[$c]$/) && ($we =~ s/^ё/о/) # bad hack } } $wb .= $we; ($os =~ /1/) && ($p =~ /^п([ем][мс]?)$/ || ($p =~ /^ч.с$/)) && (substr($wb,0,$ac-1) =~ /[$v][^$v]*$/) && ($ac = length($`) + 1); ($os =~ /4/) && ($p eq "чнд") && (substr($wb,0,$ac-1) =~ /[$v][^$v]*$/) && ($ac = length($`) + 1); if (defined $wi{'чё'} && ($p =~ /^п([ем][мжс]?)/ || $p =~ /^[чд]п[дс]?$/)) { my $jo = ($i == 9) && $wi{'б'} =~ /ереть$/ && (length($`) + 1) || $wi{'б'} =~ /е[^е]*$/ && (length($`) + 1); if ($jo == $ac) { substr($wb,$jo-1,1) =~ tr/е/ё/ } } (defined $wi{'чо'}) && ($p eq "чпс") && ($wb =~ s/цеванный/цованный/); ($p eq "!2м") && ($wb .= "те"); #bad: # # save base forms # ($p eq "пем" || $p eq "чпд") && # ($wi->{"sf$p"} = [$wb,$ac]);# || (print "!",$p,":",$wi{"sfпем"},"\n"); (defined $wi{'ся'}) && ($wb =~ /[$v]$/ && ($wb .= "сь") || ($wb .= "ся")); $wf{'с'} = $wb; $wf{'у'} = $ac; #bad place (see after LABEL2): # $wf{'ф'} = "фз" if (defined $wi{'фз'} && $p =~ /$wi{'фз'}/); # $wf{'ф'} = "фп" if (defined $wi{'фп'} && $p =~ /$wi{'фп'}/); # $wf{'ф'} = "фн" if (defined $wi{'фн'} && $p =~ /$wi{'фн'}/); # $wf{'ф'} = $wi{'ф'} if (defined $wi{'ф'}); @wfh = (\%wf); LABEL2: for my $wfhi (@wfh) { $wfhi->{'ф'} = "фз" if (defined $wi{'фз'} && $p =~ /$wi{'фз'}/); $wfhi->{'ф'} = "фп" if (defined $wi{'фп'} && $p =~ /$wi{'фп'}/); $wfhi->{'ф'} = "фн" if (defined $wi{'фн'} && $p =~ /$wi{'фн'}/); $wfhi->{'ф'} = "фн" if (defined $wi{'гбл'} && !($p eq "б3е" || $p eq "н3е") && ($p ne "пес")); $wfhi->{'ф'} = $wi{'ф'} if (defined $wi{'ф'}); } if ($p eq "дп") { if ($os =~ /9/) { my %wf1 = %{inflect($wi, "дн")->[0]}; $wfh[0]->{'з'} = "устар."; delete($wf1{'ф'}); unshift(@wfh, \%wf1); } my %wf2 = (defined $wfh[1]) ? %{$wfh[1]} : %{$wfh[0]}; # %wf (($i == 9) && (!defined $wi{'ся'}) && $sv) && (@wf2{'с','у'} = ($wi{'с'},$wi{'у'})) && ($wf2{'с'} =~ s/ть$/в/) && unshift(@wfh, \%wf2); ($wf2{'с'} =~ s/вши$/в/) && unshift(@wfh, \%wf2); } if ($u1 =~ /c[12]/ && ($p =~ /^п[ем][мжс]?$/)) { # bad, TODO: for these accents same method as for declension can be used my %wf1 = %wf; (($u1 eq "c1") && ($p eq "пес") || ($u1 eq "c2") && ($p =~ /^п[ем][мс]?$/)) && ($wf1{'с'} =~ /[$v][^$v]*$/) && ($wf1{'у'} = length($`) + 1) && (($p eq "пем") && ($wf1{'з'} = "устар.") || 1) && push(@wfh, \%wf1) } # save word forms ($p eq "пем" || $p =~ /^ч/) && ($wi->{"swf$p"} = \@wfh); # $p eq "чпд" # исключение для "пем" if (defined($exc = $wi{'искл'})) { if (($p eq "пем") && defined($excp = $exc->{$p})) { return $excp; } } \@wfh } =item add_vowel - add vowel Добавление беглой гласной. =cut sub add_vowel { my ($wi, $ae) = @_; my %wi = %$wi; # my $wb = $wi{'б'}; if (defined $wi{'ч'}) { # && $we =~ /^(й|ью?)?$/) { # substr($wb, length($wb)-length($&)-1, 0) = "о" # if ($p eq "рм") { if ($g eq "с" || $g eq "ж" && $wi{'и'} ne "8") { $wi{'и'} eq "6" && ($ae eq "у" && $wb =~ s/ь$/е/ || $ae eq "б" && $wb =~ s/ь$/и/) || $wb =~ s/[ьй]ц$/ец/ || $ae eq "у" && $wb =~ s/[ьй]([$c])$/ё$1/ || $ae eq "б" && $wb =~ s/[ьй]([$c])$/е$1/ || $wb =~ s/([кгх])([$c])$/$1о$2/ || $wb =~ s/([^$schц])([кгх])$/$1о$2/ || $wb =~ s/ц$/ец/ || $ae eq "у" && $wb =~ s/([$schц])([$c])$/$1о$2/ || $ae eq "у" && $wb =~ s/([$c])$/ё$1/ || $ae eq "б" && $wb =~ s/([$c])$/е$1/ } elsif ($g eq "м" && $we eq "" && !defined $wi{'ч2'}) { $wb = $wi{'с'}; # bad hack } # } } } =item rem_vowel - remove vowel Удаление беглой гласной. =cut sub rem_vowel { my ($wb, $wi) = @_; my %wi = %$wi; my $t2 = defined $wi{'т2'} && $wi{'т2'} || ""; my $gm = defined $wi{'рм'} && $wi{'рм'} || ""; # if (defined $wi{'ч'} && !defined $wi{'мн'}) { # return $wb if not defined $wi{'рм'}; # bad hack to remove warning for adjectives #bad: # if ($wi{'т2'} eq "м") { # $wb =~ s/и([^$v]*)$/ь$1/ # } if ($t2 eq "м" || $gm eq "м" || $gm eq "ж" && $wi{'и'} eq "8") { $wb =~ s/о([^$v]+)$/$1/ || $wb =~ s/и([^$v]*)$/ь$1/ # s/и([^$v]+)$/ь$1/ || $wb =~ s/([$v])[её]([^$v]+)$/$1й$2/ || $wi{'и'} eq "6" && ($gm eq "м" || $t2 eq "м") && $wb =~ s/[её]$/ь/ || $wi{'и'} eq "3" && ($gm eq "м" || $t2 eq "м") && $wb =~ s/([$c2])[её]([^$v]+)$/$1ь$2/ || $wb =~ s/л[её]([^$v]+)$/ль$1/ || $wb =~ s/[её]([^$v]+)$/$1/; } # elsif () # } $wb } 1;