gramdict / zalizniak-2010

Данные 6-го издания «Грамматического словаря русского языка» А. А. Зализняка (2010) в виде текстовых файлов
Other
17 stars 3 forks source link

Написать программу «развертывания» словаря #6

Open bzaar opened 3 years ago

bzaar commented 3 years ago

Зачем?

Способ представления грамматической информации, придуманный Зализняком, очень удобен для лексикографов: простым индексом вроде «св 2а» мы можем описать 120 форм глагола.

Но для автоматической обработки нужен более простой формат, содержащий как можно меньше исключений. Например, словарь OpenCorpora можно скачать в одном из двух форматов, текстовый и XML:

1
ЁЖ  NOUN,anim,masc sing,nomn
ЕЖА NOUN,anim,masc sing,gent
ЕЖУ NOUN,anim,masc sing,datv
ЕЖА NOUN,anim,masc sing,accs
ЕЖОМ    NOUN,anim,masc sing,ablt
ЕЖЕ NOUN,anim,masc sing,loct
ЕЖИ NOUN,anim,masc plur,nomn
ЕЖЕЙ    NOUN,anim,masc plur,gent
ЕЖАМ    NOUN,anim,masc plur,datv
ЕЖЕЙ    NOUN,anim,masc plur,accs
ЕЖАМИ   NOUN,anim,masc plur,ablt
ЕЖАХ    NOUN,anim,masc plur,loct
<lemma id="1" rev="1">
  <l t="ёж"><g v="NOUN"/><g v="anim"/><g v="masc"/></l>
  <f t="ёж"><g v="sing"/><g v="nomn"/></f>
  <f t="ежа"><g v="sing"/><g v="gent"/></f>
  <f t="ежу"><g v="sing"/><g v="datv"/></f>
  <f t="ежа"><g v="sing"/><g v="accs"/></f>
  <f t="ежом"><g v="sing"/><g v="ablt"/></f>
  <f t="еже"><g v="sing"/><g v="loct"/></f>
  <f t="ежи"><g v="plur"/><g v="nomn"/></f>
  <f t="ежей"><g v="plur"/><g v="gent"/></f>
  <f t="ежам"><g v="plur"/><g v="datv"/></f>
  <f t="ежей"><g v="plur"/><g v="accs"/></f>
  <f t="ежами"><g v="plur"/><g v="ablt"/></f>
  <f t="ежах"><g v="plur"/><g v="loct"/></f>
</lemma>

Мне лично симпатичен формат YAML, в котором ту же самую информацию можно представить гораздо проще:

id: 1
rev: 1
[NOUN, masc, anim]:
  sing:
    nomn: ёж
    gent: ежа
    datv: ежу
    accs: ежа
    ablt: ежом
    loct: еже
  plur:
    nomn: ежи
    gent: ежей
    datv: ежам
    accs: ежей
    ablt: ежами
    loct: ежах

По выразительной силе YAML сопоставим с JSON: в нем есть списки и объекты (aka массивы пар ключ-значение).

Задача

Нужно написать программу-конвертер из формата Зализняка в развернутый формат. Под «развернутым» имеется в виду, что словоформы выписаны явно. Так, например, из статьи Иван мо 1а получается вот такая портянка:

[сущ, м, одуш, собств]:
  ед:
    И: Ива́н 
    Р: Ива́на
    Д: Ива́ну
    В: Ива́на
    Т: Ива́ном
    П: Ива́не
  мн:
    И: Ива́ны
    Р: Ива́нов
    Д: Ива́нам
    В: Ива́нов
    Т: Ива́нами
    П: Ива́нах
отчество:
  м:
    ед:
      И: Ива́нович 
      Р: Ива́новича
      Д: Ива́новичу
      В: Ива́новича
      Т: Ива́новичем
      П: Ива́новиче
    мн:
      И: Ива́новичи
      Р: Ива́новичей
      Д: Ива́новичам
      В: Ива́новичи
      Т: Ива́новичами
      П: Ива́новичах
  ж:
    ед:
      И: Ива́новна
      Р: Ива́новны
      Д: Ива́новне
      В: Ива́новну
      Т: 
        ой: Ива́новной
        ою: Ива́новною
      П: Ива́новне
    мн:
      И: Ива́новны
      Р: Ива́новен
      Д: Ива́новнам
      В: Ива́новны
      Т: Ива́новнами
      П: Ива́новнах

Как превращать Иван мо 1а в портянки («строить все грамматические формы»), описано здесь:

Как построить нужные формы слова

Данные, которые нужно преобразовать, находятся в данном репозитории, в каталоге dictionary.

Вот еще примеры, которые можно использовать как тесты для такого конвертера (TDD, да!):

https://gist.github.com/bzaar/9a75502bc9d6a4928a25aee51a355ffb

Формат этого файла:

  1. Строка с зализняковской статьей (вход конвертера)
  2. Строка-разделитель (---) (для красоты, пропускается)
  3. Результат работы конвертера в формате YAML.
  4. Пустая строка

И дальше все повторяется.

Конвертер желательно написать на C# (F#), так как предполагается встроить его в бэкенд сайта gramdict.ru, который написан на C#.

Среди настроек конвертера должна быть опция «ставить ударения». Если она отключена, то ударения не ставятся и варианты, различающиеся только ударением, объединяются в одну форму: кра́сно и красно́ → красно, собра́лись и собрали́сь → собрались.

Подробности устройства «развернутого» формата

Формы Р2 и П2 не указываются, если они равны Р и П соответственно. (См. Пометы Р2 и П2) Примеры, где эти формы нужны: дуб, кофеёк.

Форма сравнительной степени прилагательных (тег «сравн») указывается только одна. Остальные формы могут быть построены по следующему незамысловатому правилу:

Например, из темнее получается: темнее, темней, потемнее, потемней. Из тише только две формы (потому что тише не оканчивается на -ее) — тише, потише.

Все буквы в YAML — русские, чтобы не возникало сомнений: если видим, например, букву Р, то знаем, что она русская, а не латинская.

bzaar commented 2 years ago

Update: Пока пишу грамматику для генератора парсеров. Уже разбираются более 99% всех статей. Удобство этого подхода в том, что генератор может генерировать парсеры на разных языках программирования, включая Python, Java, C. Хотя «развертывание» все равно придется писать на каком-то конкретном языке.