[uk] rule improvements

This commit is contained in:
Andriy Rysin 2026-04-07 17:28:49 -04:00
parent b5a70f35d0
commit 9c113084fa
6 changed files with 247 additions and 82 deletions

View file

@ -29,19 +29,19 @@ public class TokenAgreementPrepNounExceptionHelper {
// на дивом уцілілій техніці
if( tokenReadings.getToken().equals("дивом") )
if( token.equals("дивом") )
return new RuleException(0);
// в тисяча шістсот якомусь році
if( i < tokens.length - 1
&& tokenReadings.getToken().equals("тисяча")
&& token.equals("тисяча")
&& (PosTagHelper.hasPosTagPart(tokens[i+1], "numr")
|| LemmaHelper.hasLemma(tokens[i+1], "якийсь"))) {
return new RuleException(0);
}
// в дев'яносто восьмому
if( i < tokens.length - 1
//tokenReadings.getToken().equals("тисяча")
// token.equals("тисяча")
&& PosTagHelper.hasPosTagPart(tokenReadings, "numr") && PosTagHelper.hasPosTagPart(tokenReadings, "v_naz")
&& PosTagHelper.hasPosTagPart(tokens[i+1], "numr") && PosTagHelper.hasPosTag(tokenReadings, Pattern.compile(".*v_(rod|dav|zna|oru|mis).*")) ) {
return new RuleException(1);
@ -312,7 +312,7 @@ public class TokenAgreementPrepNounExceptionHelper {
return new RuleException(0);
}
if( tokenReadings.getToken().equals("наприклад") )
if( token.equals("наприклад") )
return new RuleException(0);
if( PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("adv(?!p).*")) ) {

View file

@ -1932,6 +1932,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<example>хочеться також зазначити</example>
</rule>
<!--
<rulegroup id="perenos_vs_perenesennya" name="Перенос і перенесення">
<rule>
<pattern>
<token inflected="yes">перенос</token>
</pattern>
<message>На позначення дії правильно: <suggestion>перенесення</suggestion></message>
<example correction="скасовувати|касувати|зносити|анулювати"><marker>відміняються</marker> податки</example>
<example>знак переносу</example>
</rule>
</rulegroup>
-->
<!--TODO: як вловити правильний вжиток відміняти: змінювати??? -->
<rulegroup id="VIDMINYTY_VS_SKASUVATY" name="Відмінити і скасувати">
<antipattern>
@ -1942,6 +1955,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<token regexp="yes" inflected="yes" skip="-1">дієслово|іменник|прикметник|речення|відмінок</token>
<token regexp="yes" inflected="yes">відміняти(ся)?|відмінити(ся)?|відмінявши(сь)?|відміняючи(сь)?|відмінивши(сь)?|відміна|відмінений</token>
</antipattern>
<antipattern>
<token regexp="yes" inflected="yes">поділяти(ся)?|поділити|поділ</token>
<token>на</token>
<token inflected="yes">відміна</token>
</antipattern>
<rule>
<pattern>
@ -3173,7 +3191,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<or>
<token><exception postag_regexp="yes" postag=".*:[mn]:v_mis.*"/></token>
<token postag_regexp="yes" postag="noun.*:nv.*:abbr.*"/>
<token>її</token>
</or>
</pattern>
<message>Краще: <suggestion>надалі</suggestion></message>
@ -3185,6 +3202,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<example>що надалі стало підставою</example>
</rule>
<rule id="v_cilyah" name="В цілях">
<pattern>
<marker>
<token regexp="yes">[ву]</token>
<token>цілях</token>
</marker>
<token postag_regexp="yes" postag=".*v_rod.*"/>
</pattern>
<message>Краще: <suggestion>для</suggestion></message>
<suggestion>щоб (з інфінітивом)</suggestion>
<example correction="для|щоб (з інфінітивом)">і <marker>в цілях</marker> пропаганди</example>
<example>також в цілях приховати</example>
</rule>
<rule id="skhodu_bad" name="Сходу">
<antipattern>
<token regexp="yes">заходу|півдн[яю]|півночі|Криму</token>
<token postag_regexp="yes" postag="conj.*"/>
<token>сходу</token>
</antipattern>
<pattern>
<token postag_regexp="yes" postag="conj.*"/>
<marker>
<token case_sensitive="yes">сходу</token>
</marker>
<token postag_regexp="yes" postag="verb.*"/>
</pattern>
<message>Правильно: <suggestion>спрожогу</suggestion></message>
<suggestion>з наскоку</suggestion>
<example correction="спрожогу|з наскоку">і <marker>сходу</marker> заявляє</example>
<example>жителів сходу</example>
<example>так і Сходу розуміють</example>
</rule>
<rule id="NEVIDYEMNYI" name="Невід'ємний">
<pattern>
<marker>

View file

@ -53,6 +53,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<token case_sensitive="no">о</token>
<token postag_regexp="yes" postag="verb.*impr.*"/>
</antipattern>
<antipattern>
<token case_sensitive="no">о</token>
<token inflected="yes" regexp="yes">чергувати(ся)?</token>
</antipattern>
<antipattern>
<token inflected="yes" regexp="yes">група|турнір|гепатит</token>
<token case_sensitive="yes" regexp="yes">[А-Я]</token>
@ -89,6 +93,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-->
<example>кількість захворювань на гепатит В зменшилась у вісім разів.</example>
<example>О слався, о слався, сміливцю...</example>
<example>де о чергується з і</example>
</rule>
<rulegroup id="MODAL_WORD" name="Узгодження з модальними словами">
@ -2962,26 +2967,95 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
</rule>
</rulegroup>
<!--
<rulegroup id="yih_vs_yiniy" name="Їх та їхній" default="off">
<rulegroup id="yih_vs_yiniy" name="Їх та їхній">
<url>http://yak-my-hovorymo.wikidot.com/zajmennyky#yih-yihnij</url>
<rule>
<antipattern>
<token regexp="yes">[ву]</token>
<token>їхньому</token>
<token>виконанні</token>
</antipattern>
<pattern>
<marker>
<token inflected="yes">їхній</token>
</marker>
<token inflected="yes" regexp="yes">кількість|розгляд|обговорення|використання|реалізація|виконання|звільнення|виробництво|застосування |проведення|утримання|вирішення|загибель|аналоги|однолітки|перелік|затримання|створення|розміщення|лікування|втілення|арешт|формування|наявність|збереження</token>
</pattern>
<message>Якщо займенник відповідає на питання «кого/чого», а не «чий», треба вживати: <suggestion>їх</suggestion></message>
<example correction="їх">незважаючи на <marker>їхню</marker> кількість.</example>
<example>в їхньому виконанні</example>
</rule>
<rule>
<antipattern>
<token inflected="yes" regexp="yes">позбавляти|позбавити|позбавивши|позбавлявши|позбавляючи|позбавлення</token>
<token regexp="yes" min="0">би?</token>
<token postag_regexp="yes" postag="(adj|numr).*v_rod.*" min="0"/>
<token>їх</token>
</antipattern>
<antipattern>
<token inflected="yes" regexp="yes">навчати|навчити|навчаючи|навчавши|навчивши</token>
<token regexp="yes" min="0">би?</token>
<token>їх</token>
</antipattern>
<antipattern>
<!-- too many verbs, ideally we need logic: verb with rv_zna+rv_oru
<token inflected="yes" regexp="yes">перекладати|перекласти|перекладаючи|переклавши|наділяти|наділити|наділяюячи|наділявши|наділивши|супроводжувати|супроводжуючи|озвучувати|озвучувавши|виховувати|воховуючи|(на)друкувати|друкування|підкріплювати|підкріплюючи|забезпечити|забезпечувати|забезпечивши|забезбечуючи|завантажувати|завантажити|завантажуючи</token>
-->
<token postag_regexp="yes" postag="(verb.*|advp.*)"/>
<token regexp="yes" min="0">би?</token>
<token>їх</token>
<token postag_regexp="yes" postag="adj.*v_oru.*" min="0"/>
<token postag_regexp="yes" postag="noun.*v_oru.*"/>
</antipattern>
<antipattern>
<token inflected="yes" regexp="yes">(під)?давати|(під)?дати|(під)?даючи|(під)?дававши|(під)?давши|протиставляти|протиставляючи</token>
<token regexp="yes" min="0">би?</token>
<token>їх</token>
<token postag_regexp="yes" postag=".*v_dav.*"/>
</antipattern>
<antipattern>
<token>їх</token>
<token postag_regexp="yes" postag="(noun|adj).*pron.*"/>
</antipattern>
<pattern>
<marker>
<token>їх</token>
</marker>
<token inflected="yes" regexp="yes">організм|пам'ять|становище|замисел|сподівання|ресурс|потреба|майно|знайомство|хвиля|голос|тренер|родич</token>
< життя ? >
<unify>
<feature id="gender"/>
<feature id="case"/>
<token postag_regexp="yes" postag="adj.*" min="0"/>
<token inflected="yes" regexp="yes">організм|професія|обов'язок|думка|вимога|cтановище|побажання|потреба|замисел|сподівання|життя|участь|право|небезпека|мова|знання|сім'я|діяльність|слово|дія
<exception regexp="yes">знання|мовою</exception>
</token>
</unify>
</pattern>
<message>Якщо «їх» відповідає на питання «кого/чого», а не «чий», треба вживати <suggestion>їхній</suggestion>?</message>
<example correction="їхній">на <marker>їх</marker> сподівання.</example>
<message>Якщо «їх» відповідає на питання «чий», а не «кого/чого», треба вживати <suggestion>їхній</suggestion></message>
<example correction="їхній">на <marker>їх</marker> організм.</example>
<example correction="їхній">на <marker>їх</marker> загальний обов'язок.</example>
<example correction="їхній">відповідатиме <marker>їх</marker> економічно-соціальним потребам.</example>
<example>позбавивши їх життя</example>
<example>жінка навчає їх англійської мови</example>
<example>перекладати їх іншими мовами</example>
<example>позбавити обох їх батьківських прав</example>
<example>низький рівень їх знання поміж українців</example>
<example>якщо їх цього права позбавити</example>
<example>писали їх українською мовою</example>
</rule>
</rulegroup>
-->
<rulegroup id="pyvyd_vs_pryvid" name="Привід та привид">
<rule>
<pattern>
<token regexp="yes" inflected="yes">механічний|електричний|формальний|зайвий|да(ва)?ти|шукати|мати</token>
<token regexp="yes" inflected="yes">механічний|електричний|формальний|зайвий|офіційний|гарний|непоганий|повний</token>
<marker>
<token>привид</token>
</marker>
@ -2990,6 +3064,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<example correction="привід">механічний <marker>привид</marker>.</example>
</rule>
<rule>
<pattern>
<token regexp="yes" inflected="yes">(на)?дати|(на)?давати|(на)?даючи|(на)?давши|шукати|шукаючи|знайти|знайшовши|мати|cтворювати|створити|потрібен</token>
<token postag_regexp="yes" postag="(adj:m:v_zna:rinanim|noun.*v_dav).*" min="0"/>
<marker>
<token>привид</token>
</marker>
</pattern>
<message>Може ви мали на увазі <suggestion>привід</suggestion>?</message>
<example correction="привід">дав їм <marker>привид</marker>.</example>
<example correction="привід">дав гарний <marker>привид</marker>.</example>
</rule>
<rule>
<pattern>
<marker>
@ -3000,6 +3087,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<message>Може ви мали на увазі <suggestion>привід</suggestion>?</message>
<example correction="привід">шукав <marker>привид</marker> для.</example>
</rule>
<rule>
<pattern>
<marker>
<token>привид</token>
</marker>
<token postag_regexp="yes" postag="verb.*inf.*" />
</pattern>
<message>Може ви мали на увазі <suggestion>привід</suggestion>?</message>
<example correction="привід">просто <marker>привид</marker> втекти додому.</example>
</rule>
</rulegroup>
<rule id="sprytni_napoi" name="Спритні напої">

View file

@ -1493,6 +1493,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<!-- group: велика літера -->
<rule id="z_velykoiy" name="Назви з великої">
<antipattern>
<token regexp="yes">(не)?хай</token>
<token>господь</token>
</antipattern>
<antipattern>
<token>господь</token>
<token regexp="yes">і</token>
<token regexp="yes">тобою|вами</token>
</antipattern>
<pattern>
<and>
<token case_sensitive="yes" regexp="yes">[а-яіїєґ].*</token>
@ -1506,6 +1515,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<example correction="Різдва">готувався до <marker>різдва</marker></example>
<example>по тонкому покрову</example>
<example>така затишна господа</example>
<example>нехай господь помагає</example>
</rule>
<!-- group: інші -->
@ -1656,7 +1666,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<example correction="примʼятий|прим’ятий|прим'ятий">він <marker>прим"ятий</marker>.</example>
<example correction="примʼятий|прим’ятий|прим'ятий">він <marker>прим´ятий</marker>.</example>
<example correction="привʼязати|прив’язати|прив'язати">там <marker>прив”язати</marker>.</example>
<!--
<example correction="привʼязати|прив’язати|прив'язати">ось там <marker>прив`язати</marker>.</example>
-->
</rule>
</category>

View file

@ -384,75 +384,78 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
<!-- старший/молодший кого/чого -->
<rule>
<antipattern>
<token regexp="yes">та|і</token>
<token postag_regexp="yes" postag="adj:.:v_naz.*" inflected="yes" regexp="yes">старший|молодший</token>
<token postag_regexp="yes" postag="noun.*:p:v_naz.*"/>
</antipattern>
<antipattern>
<unify>
<feature id="gender"/>
<feature id="case"/>
<token inflected="yes" regexp="yes" postag_regexp="yes" postag="adj:.:v_naz.*">старший|молодший</token>
<token postag_regexp="yes" postag="noun.*|adj.*"/>
</unify>
</antipattern>
<antipattern>
<token regexp="yes">старш(ий|а)</token>
<unify>
<feature id="gender"/>
<feature id="case"/>
<token postag_regexp="yes" postag="adj:.:v_rod.*" min="0"/>
<token regexp="yes">років|групи|загону|зміни|підрозділу|школи|роду|родини|війська|наряду|позиції|року|віку</token>
</unify>
</antipattern>
<pattern>
<token inflected="yes" regexp="yes" postag_regexp="yes" postag="adj:[mfp]:v_naz.*">старший|молодший</token>
<marker>
<token postag_regexp="yes" postag="noun.*?:[^p]:v_rod.*">
<exception postag_regexp="yes" postag="noun.*?:nv.*|verb.*|numr.*"/>
<exception regexp="yes">всього|чогось</exception>
</token>
</marker>
</pattern>
<message>Правильно: <suggestion>за <match no="2" postag_regexp="yes" postag="(.*):(?:v_rod)(.*)" postag_replace="$1:(v_zna)$2"/></suggestion></message>
<suggestion>від <match no="2"/></suggestion>
<suggestion>ніж <match no="2" postag_regexp="yes" postag="(.*):(?:v_rod|nv)(.*)" postag_replace="$1:(v_naz|nv)$2"/></suggestion>
<example correction="за сестру|від сестри|ніж сестра">він старший <marker>сестри</marker> на 3 роки</example>
<example correction="за сестру|від сестри|ніж сестра">вона старша <marker>сестри</marker> на 3 роки</example>
<example correction="за місто|від міста|ніж місто">він старший <marker>міста</marker> на 3 роки</example>
<!--
<example correction="за Богдана|від Богдана|ніж Богдан">вона старша <marker>Богдана</marker> на 3 роки</example>
-->
<example correction="За Єву|Від Єви|Ніж Єва">він молодший <marker>Єви</marker> на 3 роки</example>
<!--
<example correction="За Родольфо|Від Родольфо|Ніж Родольфо">він старше <marker>Родольфо</marker> на 3 роки</example>
-->
<example>старша сестра</example>
<example>старша онука</example>
<example>старший брат</example>
<example>старший механік</example>
<example>старші колеги</example>
<example>старше п'яти</example>
<example>старший групи</example>
<example>середня і старша групи</example>
<example>старший слідчої групи</example>
<example>молодші Олександр Ірванець, Оксана Луцишина</example>
<example>молодший Джимів брат</example>
<example>старша його донька</example>
<example>молодша забрала</example>
<example>старший минулого року пішов до школи</example>
<example>середня та старша сестри</example>
<!-- taken care by adj/noun token agreement rule -->
<example>старше сестри</example>
<!-- Десь було таке правило (rule of thumb), що якщо вказується ознака відносно певної точки, то така конструкція можлива.
Працездатний вік задає таку точку. Ще приклад: вище/нижче нуля. А якщо йде порівняння з іншою особою/об'єктом,
то тоді треба прийменника: старший за мене, цей стілець вищий від того тощо -->
<example>старший працездатного віку</example>
</rule>
</rulegroup>
<antipattern>
<token regexp="yes">та|і</token>
<token postag_regexp="yes" postag="adj:.:v_naz.*" inflected="yes" regexp="yes">старший|молодший</token>
<token postag_regexp="yes" postag="noun.*:p:v_naz.*"/>
</antipattern>
<antipattern>
<unify>
<feature id="gender"/>
<feature id="case"/>
<token inflected="yes" regexp="yes" postag_regexp="yes" postag="adj:.:v_naz.*">старший|молодший</token>
<token postag_regexp="yes" postag="noun.*|adj.*"/>
</unify>
</antipattern>
<antipattern>
<token regexp="yes">старш(ий|а)</token>
<unify>
<feature id="gender"/>
<feature id="case"/>
<token postag_regexp="yes" postag="adj:.:v_rod.*" min="0"/>
<token regexp="yes">років|групи|загону|зміни|підрозділу|школи|роду|родини|війська|наряду|позиції|року|віку</token>
</unify>
</antipattern>
<pattern>
<token inflected="yes" regexp="yes" postag_regexp="yes" postag="adj:[mfp]:v_naz.*">старший|молодший</token>
<marker>
<token postag_regexp="yes" postag="noun.*?:[^p]:v_rod.*">
<exception postag_regexp="yes" postag="noun.*?:nv.*|verb.*|numr.*"/>
<exception regexp="yes">всього|чогось</exception>
<exception scope="next" postag_regexp="yes" postag="verb.*"/>
</token>
</marker>
</pattern>
<message>Правильно: <suggestion>за <match no="2" postag_regexp="yes" postag="(.*):(?:v_rod)(.*)" postag_replace="$1:(v_zna)$2"/></suggestion></message>
<suggestion>від <match no="2"/></suggestion>
<suggestion>ніж <match no="2" postag_regexp="yes" postag="(.*):(?:v_rod|nv)(.*)" postag_replace="$1:(v_naz|nv)$2"/></suggestion>
<example correction="за сестру|від сестри|ніж сестра">він старший <marker>сестри</marker> на 3 роки</example>
<example correction="за сестру|від сестри|ніж сестра">вона старша <marker>сестри</marker> на 3 роки</example>
<example correction="за місто|від міста|ніж місто">він старший <marker>міста</marker> на 3 роки</example>
<!--
<example correction="за Богдана|від Богдана|ніж Богдан">вона старша <marker>Богдана</marker> на 3 роки</example>
-->
<example correction="За Єву|Від Єви|Ніж Єва">він молодший <marker>Єви</marker> на 3 роки</example>
<!--
<example correction="За Родольфо|Від Родольфо|Ніж Родольфо">він старше <marker>Родольфо</marker> на 3 роки</example>
-->
<example>старша сестра</example>
<example>старша онука</example>
<example>старший брат</example>
<example>старший механік</example>
<example>старші колеги</example>
<example>старше п'яти</example>
<example>старший групи</example>
<example>середня і старша групи</example>
<example>старший слідчої групи</example>
<example>молодші Олександр Ірванець, Оксана Луцишина</example>
<example>молодший Джимів брат</example>
<example>старша його донька</example>
<example>молодша забрала</example>
<example>старший минулого року пішов до школи</example>
<example>середня та старша сестри</example>
<!-- taken care by adj/noun token agreement rule -->
<example>старше сестри</example>
<!-- Десь було таке правило (rule of thumb), що якщо вказується ознака відносно певної точки, то така конструкція можлива.
Працездатний вік задає таку точку. Ще приклад: вище/нижче нуля. А якщо йде порівняння з іншою особою/об'єктом,
то тоді треба прийменника: старший за мене, цей стілець вищий від того тощо -->
<example>старший працездатного віку</example>
<example>старші його підбадьорювали</example>
</rule>
</rulegroup>
<!-- group: канцеляризми
<rulegroup name="Канцелярзми" id="KANZ" default="off">

View file

@ -122,6 +122,7 @@ public class TokenAgreementPrepNounRuleTest extends AbstractRuleTest {
assertEmptyMatch("станом на зараз виконавча влада");
assertEmptyMatch("в тисяча шістсот якомусь році");
assertEmptyMatch("у ти́сяча сімсо́т вісімдеся́т дев’я́тому");
assertEmptyMatch("на Піп Іван");
// assertEmptyMatch("Імена від Андрій до Юрій"); // називний між від і до рідко зустрічається але такий виняток ховає багато помилок