ТОМ2 - платформа для парсерных игр

Объявление

Открыт сайт tom2-game.ru.


Последнюю версию платформы можно скачать здесь.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ТОМ2 - платформа для парсерных игр » Библиотеки, интерфейсы, плагины, инструментарий » "Проблемы создания генератора лексем" или "стандартизируем морфкоды"


"Проблемы создания генератора лексем" или "стандартизируем морфкоды"

Сообщений 1 страница 9 из 9

1

Определяем проблему
Разработка визуального редактора уже довольно долго валяется в тёмном углу винчестера. А упёрлось всё в автоматический генератор лексем, т.к. сейчас самой рутиной частью создания программ в нём является описание лексем. Лексем приходится писать много, а способ их описания довольно сложен. А я привык оптимизировать программы начиная с самых непроизводительных мест, так-что пока не будет создан автоматический генератор, редактор вряд ли сдвинется с места.
Генератор лексем, в свою очередь, упирается в несовместимость формата морфологических кодов ТОМа и формата словаря АОТ.
"Стоп!" - скажет внимательный читатель этого форума - "Ты же писал, что автоматический генератор уже был почти сделан, и уже генерировал лексемы!".
Да, тот генератор был попыткой с-лёту, особо не разбираясь в сути проблемы написать программу, автоматически генерирующую лексемы. И да, она генерировала лексемы, но была настолько негибкой и непредсказуемой, что процент правильного генерирования вряд ли дотянул бы до 80%. Причиной этого была несовместимость форматов описания лексем ТОМа и АОТ. Те функции, которые "пытались" переводить эти форматы из одного в другой были больше похожи на заглушки, не учитывающие множество факторов и нестыковок форматов.

Формат морфологических кодов ТОМа
Как известно, морфкоды ТОМа описываются в виде пар символов, где первый символ - значение кода, а второй - тип. Всё описание на этом заканчивается, т.е. пользователь может напридумывать какие-угодно коды и всё это будет работать. Эта неоднозначность - первая, но не самая страшная проблема несовместимости. Не страшная, потому-что всё можно довольно легко придумать, описать и применить в качестве "условного формата". Например, уже сейчас почти везде используется код падежа "п" со значениями "ИРДВТПЗ". Другие падежи я незамечал в ТОМе, но они есть.

Несовместимость ТОМ-АОТ
Второй проблемой можно назвать то, что словарь АОТ позволяет задавать лексемы в довольно свободном виде: в некоторых лексемах могут отсутствовать некоторые словоформы, содержаться по несколько словоформ с одинаковыми граммемами (это там так называются морфкоды). Вот тут то и начинаются сложности: какую форму использовать, если формы с точно-такими же граммемами нет в словаре (наиболее простой пример: требуется извлечь из словаря форму Звательного падежа, но её там нет. В этом случае надо использовать Именительную), или в словаре содержатся две формы с одинаковыми морфкодами (скажете, брать любую или первую по счёту? Не тут то было! Я пробовал - на выходе ерунда получается).

Причина создания этой темы
Этой темой я хотел "расшатать" дальнейшую разработку редактора и попытаться сдвинуть её с мёртвой точки. Т.к. я в школе по русскому имел твёрдую "3", для меня довольно трудно разбираться во всех сложностях русского. Нет, я хорошо знаю русский на уровне "внутренней интуиции", но все эти понятия типа "предикатив", "междометие" вводят меня в ступор и приходится долго читать статьи по русскому (особенно помогает википедия), чтобы начать вникать в тему. А для того, чтобы придумать надёжный алгоритм подбора словоформы из словаря под морфкод, нужно хорошенько структурировать все граммемы АОТ и "стандартизировать" морфкоды ТОМа.

Формат АОТ
На высоком уровне рассмотрения формат лексем этого словаря можно описать так: лексема - набор словоформ, напротив которых подставлены граммемы, определяющие, в какой форме это слово. Одна лексема описывает одно слово и все его словоформы, включая изменения части речи. Например глаголы в одной лексеме имеют и инфинитив и все прочие формы. Кол-во словоформ не стандартизировано, некоторые формы могут отсутствовать или повторяться.
Описание формы слова состоит из части речи и набора граммем.
Части речи:

Код:
      //======= Части речи =======
      crNull     = 0;
      crSush     = 1;  //  C            мама       существительное
      crPril     = 2;  //  П            красный    прилагательное
      crMestSush = 3;  //  МС           он         местоимение-существительное
      crGlag     = 4;  //  Г            идет       глагол в личной форме
      crPrich    = 5;  //  ПРИЧАСТИЕ    идущий     причастие
      crDeepr    = 6;  //  ДЕЕПРИЧАСТИЕ идя        деепричастие
      crInfin    = 7;  //  ИНФИНИТИВ    идти       инфинитив
      crMestPred = 8;  //  МС-ПРЕДК     нечего     местоимение-предикатив
      crMestPril = 9;  //  МС-П         всякий     местоименное прилагательное
      crChisl    = 10; //  ЧИСЛ         восемь     числительное (количественное)
      crChislPor = 11; //  ЧИСЛ-П       восьмой    порядковое числительное
      crNarech   = 12; //  Н            круто      наречие
      crPredik   = 13; //  ПРЕДК        интересно  предикатив
      crPredl    = 14; //  ПРЕДЛ        под        предлог
      crSojuz    = 15; //  СОЮЗ         и          союз
      crMejd     = 16; //  МЕЖД         ой         междометие
      crChast    = 17; //  ЧАСТ         же, бы     частица
      crWwodn    = 18; //  ВВОДН        конечно    вводное слово
      crKrPril   = 19; //  КР_ПРИЛ      красива    краткое прилагательное
      crKrPrich  = 20; //  КР_ПРИЧАСТИЕ построена  краткое причастие
         // недокументированные
      crZwezda   = 21; //  *                       общая форма (плюсуется с другими)
      crPosl     = 22; //  ПОСЛ                    пословица
      crFraz     = 23; //  ФРАЗ                    фразеологизм

Граммемы:

Код:
  //======= Набор граммем ===============
  TGrammema=(grNull,
             grMr, grJr, grSr, // мр, жр, ср - мужской, женский, средний род;
             grOd, grNd,       // од, но - одушевленность, неодушевленность;
             grEdCh, grMnCh,   // ед, мн - единственное, множественное число;
             grImP, grRdP, grDtP, grWnP, grTwP, grPrP, grZwP, // им, рд, дт, вн, тв, пр, зв - падежи: именительный, родительный, дательный, винительный, творительный, предложный, звательный;
             gr2P,             // 2 - обозначает второй родительный или второй предложный падежи;
             grSwW, grNsW,     // св, нс - совершенный, несовершенный вид;
             grPeG, grNpG,     // пе, нп - переходный, непереходный глагол;
             grDstZ, grStrZ,   // дст, стр - действительный, страдательный залог;
             grNstW, grPrW, grBudW,   // нст, прш, буд - настоящее, прошедшее, будущее время;
             grPwlG,           // пвл - повелительная форма глагола;
             gr1L, gr2L, gr3L, // 1л, 2л, 3л - первое, второе, третье лицо;
             grNeizm,          // 0 - неизменяемое.
             grKratk,          // кр - краткость (для прилагательных и причастий).
             grSrawn,          // сравн - сравнительная форма (для прилагательных).
             grImja, grFam, grOtch,  // имя, фам, отч - имя, фамилия, отчество.
             grLok, grOrg,     // лок, орг - локативность, организация.
             grKachPr,         // кач - качественное прилагательное.
             grWopr, grOtnos,  // вопр,относ - вопросительность и относительность (для наречий).
             grDfst,           // дфст - слово обычно не имеет множественного числа.
             grOpech,          // опч - частая опечатка или ошибка.
             grJarg, grArh, grProf,  // жарг, арх, проф - жаргонизм, архаизм, профессионализм.
             grAbbr,           // аббр - аббревиатура.
             grBezlich,        // безл - безличный глагол.
                // недокументированные
             grRazg,           // разг - разговорный
             grMrJr,           // мр-жр - мужской-женский род
             grPrew,           // прев - превосходная степень прилагательного
             grUkazat,         // указат - указательное наречие
             grPritjag         // притяж - притяжательное
                 );

Я как мог сгруппировал граммемы. Граммемы описывают не только морфологические, но и некоторые семантические свойства. Их надо как-то обходить или попросту игнорировать при переводе.

Стандартизация морфкодов
Понятно, что гибкость морфкодов ТОМа - это очень хорошо, но чтобы работать дальше, нужно разработать некий условный формат записи морфкодов, необходимых для автоматической генерации лексем.
Из устоявшихся можно выделить:

Часть речи
Си - имя существительное
Ги - глагол
Пи - имя прилагательное
какие части речи ещё могут понадобиться при генерации лексем? И что делать с инфинитивом?

Падеж
Ип - именительный
Рп - родительный
Дп - дательный
Вп - винительный
Тп - творительный
Пп - предложный
Зп - звательный
как описать ещё два падежа: Партитив (второй родительный) и Локатив (второй предложный)? И не менее важный вопрос: нужны ли они при генерации?

Род
Мр - мужской
Жр - женский
Ср - средний
что делать с общим родом (сирота, недотрога, плакса)?

Число
Еч - единственное
Мч - множественное
а здесь есть грабли?

Одушевлённость
Од - одушевлённое
Нд - неодушевлённое

Лицо
1л - первое лицо
2л - второе лицо
3л - третье лицо

Время
Пв - прошедшее
Нв - настоящее
Бв - будущее
могут ли быть здесь сложности?

Какие ещё морфкоды можно добавить для совмещения с форматом АОТ?

Перевод форматов
После всего этого надо придумать алгоритм перевода морфкодов из одного формата в другой. На их основе сделать функции подбора наиболее подходящей под морфкод словоформы из списка словоформ в лексеме. При этом должны учитываться различные ситуации, как в примере с падежами:
Если не найдена форма Зп, то использовать Ип. Если не найден второй предложный, то использовать обычный предложный и т.д... Проблема не только с падежами, думается мне, что есть еще множество нюансов.

Заключение
Всё написанное здесь - скорее заметка для меня, чем статья. Я хотел таким образом структурировать то, что я наворотил за всё это время, "освежить память" так-сказать, создать некий план работ. Но буду не против, если кто-нибудь что-нибудь подскажет. :) Приму любые замечания и предложения.

И ещё: википедия :cool:
Вот например описание имени существительного (ru.wikipedia.org/wiki/Имя_существительное_в_русском_языке).

2

Alexandr написал(а):

приходится долго читать статьи по русскому (особенно помогает википедия), чтобы начать вникать в тему.

Весьма полезное занятие! :cool: 
Можно узнать много нового и неожиданно удивительного :)

Удивляет, например, как можно было составить школьную программу, чтобы ни разу не коснуться 2-го предложного (местного) падежа?
Это же специально так постараться надо...

3

ASBer написал(а):

Весьма полезное занятие! Можно узнать много нового и неожиданно удивительного

И не надо над этим смеяться. Это действительно осложняет дело.

ASBer написал(а):

как можно было составить школьную программу, чтобы ни разу не коснуться 2-го предложного (местного) падежа?

Да, довольно странно. В школьной программе ещё много чего не хватает. Но с другой стороны - зачем учить всех подряд вникать в полную структуру русского языка. Чтобы нормально писать и говорить без ошибок совсем не обязательно всё это знать. Ведь далеко не все школьники будут лингвистами.

4

Alexandr написал(а):

И не надо над этим смеяться. Это действительно осложняет дело.

Я и сам такой, тут не до смеху :)

Alexandr написал(а):

как описать ещё два падежа: Партитив (второй родительный) и Локатив (второй предложный)? И не менее важный вопрос: нужны ли они при генерации?

Вот пример кода из Containers.tml:

Код:
  //стандартное описание поверхности
  this.st_описание = "{описание}. {описание_содержимого()}."
  описание_содержимого(игнор_пустого,кратко,местоимение)
  { if(местоимение)
      var Th = "{this:лич_мест*this.lex~рч*ПпМу}"
    else
      var Th = "{this.lex*ПпМу}"

    if(item:нечто_видимое.num)
      if(кратко)
        return "{предлог} {Th} {item:нечто_видимое}"
      else
        return "{предлог} {Th} {находится*item:нечто_видимое} {item:нечто_видимое}"
    else if(игнор_пустого)
      return ""
    else
      return "{предлог} {Th} ничего нет"
  }

Здесь ПпМу - это местный падеж (локатив) - [П]редложный [п]адеж [М]естный ([у]точнение).
Лексема "Снег" должна выглядеть как "Снег%; СиМрНд; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е; ПпМу=у"

на снегу находится ...

Как будет выглядеть второй родительный пока не скажу... раньше не встречалось. Как-то так: Рп?у.
А второй винительный так: Вп?у.

5

С учётом произношения лексема "Снег" должна выглядеть как "сне`г%; СиМрНд; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е; ПпМу<снегу`"

6

Alexandr написал(а):

что делать с общим родом (сирота, недотрога, плакса)?

Для таких лексем нужно указывать род того объекта, которому данная лексема принадлежит.
Т.е. если у нас есть 2 сироты -  мальчик и девочка, то в первом случае лексема будет Мр, во втором - Жр.

7

ASBer написал(а):

сне`г%; СиМрНд; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е; ПпМу<снегу`

Я уже думал, что акцентуальные модели (так обзываются ударения в АОТ) не пригодятся и можно их выкинуть. :)
Но с ударениями приходит ещё одно усложнение: в дополнение к 9-ти перечисленным падежам добавляется ещё один "падеж", а точнее "Счётная форма". Она не влияет на написание, но влияет на ударение. Употребляется некоторыми существительными с числительными два, три и четыре:
часто существительные не имеют этой формы:
нет стола`;  два стола`
но иногда могут встречаться:
нет ча`са;  два часа`
нет ря`да;  два ряда`

8

Я думаю пойти по пути наименьшего сопротивления: не делать дополнительные функции для перевода морфкодов из одного формата в другой, а сделать некий набор шаблонов, который будет описываться в отдельном файле. Шаблоны должны содержать определитель (некое регулярное выражение) и непосредственно шаблон (описывает, какие формы на какое место вставлять).
Можно придумать примерно такой формат:

шаблон <Название>
<Определитель>
<Шаблон в
несколько
строк>
.

Например для отдельного существительного:

Код:
шаблон Существительное  // заголовок шаблона
(слово:С им, ед)    // определитель
// шаблон (всё что ниже до точки)
(слово.основа)%;   // основа
Си(слово.д)(слово.р);   // постоянные свойства
ИпЕч;    // свойства по умолчанию
ИпЕч=(слово:С им, ед); РпЕч=(слово:С рд, ед); ДпЕч=(слово:С дт, ед); ВпЕч=(слово:С вн, ед); ТпЕч=(слово:С тв, ед);
ПпЕч=(слово:С пр, ед); ЗпЕч=(слово:С зв, ед); ПпМуЕч=(слово:С пр, 2*, ед);
ИпМч=(слово:С им, мн); РпМч=(слово:С рд, мн); ДпМч=(слово:С рд, мн); ВпМч=(слово:С рд, мн); ТпМч=(слово:С рд, мн);
ПпМч=(слово:С рд, мн); ЗпМч=(слово:С зв, мн); ПпМуМч=(слово:С пр, 2*, мн)
.

Такой формат позволяет описывать простые шаблоны генерации не особо утруждая программу переводом морфкодов.
Определитель состоит из строки-маски, определяющей пригодность данного шаблона для генерации лексемы для входной строки. Допустим, на вход генератора поступает строка "мальчик". Эта строка делится на слова и всё что между слов. Всё это проверяется на принадлежность к шаблону по определителю. А там указано "(слово:С им, ед)", что означает одно слово - существительное в именительном падеже единственного числа. Значит данный шаблон сработает и дальше пойдет генерация. Если, например, на вход поступило бы "мальчики" или "мальчиков" или "маленький мальчик", этот шаблон бы не сработал. Так-же определитель может быть словосочетанием. Например, "(сл_прил:ПРИЛ им, ед) (сл_сущ:С им, ед)" будет срабатывать на "большой стол", "красивая ложка", а так-же на "красная диск" :sceptic: .
Шаблон представляет собой длинную строку, в которой все части в скобках будут заменяться по определённому алгоритму.
"слово.основа" - "<ссылка на слово>.<функция>". Ссылка указывает на слово в определителе, т.е. во входной строке. Функция - некая внутренняя функция генератора, которая возвращает какое-то значение относительно слова перед точкой. "слово.основа" возвратит основу слова. "слово.д" - одушевлённость в формате ТОМ.
"слово:С пр, 2*, мн" - "<ссылка на слово>:<граммемы АОТ>". Возвращает окончание слова в форме по указанным граммемам. Если после граммемы стоит *, то при отсутствии словоформы с данной граммемой, нужно взять форму без этой граммемы.

В общем, как-то так мне это видится. Описал, конечно очень скверно, но сейчас нет точных определений, поэтому и описывать сложно.
Такой формат имеет и множество недостатков:
В приведённом выше примере используется звательный и местный падежи, которые довольно редко встречаются. Несмотря на это они будут генерироваться для всех существительных, подставляя именительный и предложный соответственно. Это не влечёт ошибки, но как-то нерационально.
Придётся описывать шаблоны для всех вариантов перестановок и сочетаний слов: прил-сущ, прил-прил-сущ, сущ-прил и очень много других.
Несмотря на это я думаю, что этого на первое время хватит. Займусь реализацией чуть позже, сейчас нет времени. Если есть какие-то замечания, прошу высказывать.

9

Alexandr написал(а):

Время
Пв - прошедшее
Нв - настоящее
Бв - будущее
могут ли быть здесь сложности?

Сложность может быть в том что я предпочитаю объединять в одной лексеме пару глаголов - совершенный + несовершенный:
Пв - вошёл
Нв - входишь
Бв - войдёшь


Вы здесь » ТОМ2 - платформа для парсерных игр » Библиотеки, интерфейсы, плагины, инструментарий » "Проблемы создания генератора лексем" или "стандартизируем морфкоды"