Модуль морфологического анализа, проверки орфографии и лемматизации украинского языка

Модуль морфологического анализа, проверки орфографии и лемматизации украинского языка

  1. Общее описание модуля.
  2. Форматы данных
    1. Часть речи
    2. Грамматическое описание
    3. Дополнительные признаки
    4. Идентификаторы форм
  3. Программный интерфейс
    1. Коды ошибок
    2. Флаги настройки – options
    3. Проверка правописания
    4. Построение списка нормальных форм
    5. Построение формы слова по идентификатору
    6. Построение формы слова по грамматическому описанию
    7. Перебор лексем (enumeration)
    8. Извлечение части речи лексемы
  4. Украинский алфавит

1.Общее описание модуля

Как и следует из названия, модуль предназначен для проверки правописания отдельных слов (правильно - неправильно), лемматизации (построения нормальных форм слов по произвольной форме), извлечения грамматических описаний тех форм, с которыми совпала поданная строка, и морфологического синтеза форм по нормальной форме и грамматическому описанию, и построения списка возможных правильных начертаний для неправильного слова (подсказка).

Модуль реализован в виде динамической библиотеки Win32, содержит словари в виде ресурсов и экспортирует функции в C-стиле (то есть для их вызова требуется декларация extern “C”).

Модуль работает с ASCIIZ-строками, то есть строками, где один символ кодируется одним байтом, а нулевой символ обозначает конец строки, и подразумевает, что строки на вход ему подаются в кодировке 1251 (Windows Cyrillic).

Словарь модуля объемом около 120000 слов при генерации разбивается на страницы размером менее 64К, что позволяет оптимально организовать работу с памятью и использовать короткое слово (16 бит) для адресации внутри страницы с другой. Алгоритм модуля предельно прост и представляет собой интерпретатор таблиц переходов конечного автомата, в то время как страницы словаря являются этими самыми таблицами.

Благодаря этим решениям словарь модуля не превышает размером один мегабайт, устойчиво работает при объеме доступной памяти около 200К, а при наличии свободного мегабайта оперативной памяти загружает все страницы и выходит на максимальную производительность не менее (а реально более) 10000 слов в секунду (в режиме проверки правописания, процессор Pentium 100). Производительность модуля в режиме лемматизации (построения текстов нормальных форм слова) несколько ниже, так как приходится просматривать весь словарь, и составляет не менее 2000 слов в секунду (в тех же условиях).

2.Форматы данных

При построении нормальных форм слова, равно как и при морфологическом синтезе, модуль морфологического анализа оперирует частями речи и грамматическими описаниями форм. Часть речи и грамматическое описание вместе составляют грамматическую информацию, описываемую структурой SGramInfo:
typedef struct { unsigned char  wInfo; unsigned char  iForm; unsigned short gInfo; unsigned char  other; } SGramInfo;
В этой структуре wInfo - информация о части речи слова с некоторыми дополнительными служебными полями, iForm – идентификатор формы слова, gInfo – расширенное грамматическое описание, other - дополнительные признаки.

2.1.Часть речи

Часть речи, извлекаемая из поля wInfo грамматической информации, может быть использована, например, для определения признака значимости анализируемого слова или для иных целей.
Чтобы определить часть речи, следует замаскировать служебные биты wInfo маской 0x3F, после чего воспользоваться таблицей соответствий:
wInfo & 0x3FМнемоникаЧасть речи украинская
1чНеодушевленное существительное мужского рода
2чiОдушевленное существительное мужского рода
3ч/жНеодушевленное существительное общего рода
4чi/жiОдушевленное существительное общего рода
5ч/сНеодушевленное существительное мужского/среднего рода
6чi/сiОдушевленное существительное мужского/среднего рода
7жНеодушевленное существительное женского рода
8жiОдушевленное существительное женского рода
9ж/сНеодушевленное существительное женского/среднего рода
10сНеодушевленное существительное среднего рода
11сiОдушевленное существительное среднего рода
12мнНеодушевленное существительное множественного числа
13мнiОдушевленное существительное множественного числа
14ч-жНеодушевленное существительное мужского рода, изменяющееся по схеме женского
15чi-жiОдушевленное существительное мужского рода, изменяющееся по схеме женского
16пПрилагательное
17числЧислительное
18числ_2Числительное “два” (имеющее род)
19числ_пПорядковое числительное
20зЛичное местоимение (местоимение - существительное, например, “вiн” - он)
21зпМестоимение - прилагательное
22ipfГлагол несовершенного вида
24pfГлагол совершенного вида
26pfipfДвувидовой глагол
28виг.Междометье
29прийм.Предлог
30присл.Наречие
31спол.Союз
32част.Частица
33незм.Неизменяемое слово без указания части речи
34вводн.Вводное слово
35аб.Аббревиатура

2.2.Грамматическое описание

Грамматическое описание является точным двоичным идентификатором некоторой формы слова, но обладает свойством аддитивности, то есть короткое слово (шестнадцать бит) разделено на зоны, каждая из которых отвечает за некоторый грамматический признак.

Ниже приведены мнемоники из файла прототипов со значениями и толкованиями каждого из них:
ПризнакЗначениеТолкованиеВстречается у
gfRetForms0x8000Признак возвратностиприлагательных, глаголов
gfFormMask0x7000Маска зоны указания падежаглаголов, прилагательных, существительных, числительных, местоимений
gfNominative0x0000Именительный падеж—”—
gfGenative0x1000Родительный падеж—”—
gfDative0x2000Дательный падеж—”—
gfAccusative0x3000Винительный падеж—”—
gfInstrumental0x4000Творительный падеж—”—
gfPrepositional0x5000Предложный падеж—”—
gfCalling0x6000Звательный падеж—”—
gfGendMask0x0E00Маска зоны рода и числа—”—
gfMasculine0x0200Мужской род—”—
gfFeminine0x0400Женский род—”—
gfNewtral0x0600Средний род—”—
gfMultiple0x0800Множественное число—”—
gfVerbForm0x0060Маска зоны личностностиглаголов
vfPersonal0x0000Личная форма—”—
vfActive0x0020Действительное причастие—”—
vfPassiv0x0040Страдательное причастие—”—
vfGerund0x0060Деепричастие—”—
gfVerbFace0x0018Маска зоны лица—”—
vbFirstFace0x0008Первое лицо—”—
vbSecondFace0x0010Второе лицо—”—
vbThirdFace0x0018Третье лицо—”—
gfVerbTime0x0007Маска зоны времени—”—
vtInfinitiv0x0001Инфинитив (неопределенная форма)—”—
vtImperativ0x0002Императив (повелительное наклонение)—”—
vtFuture0x0003Будущее время—”—
vtPresent0x0004Настоящее время—”—
vtPast0x0005Прошедшее время—”—

2.3.Дополнительные признаки

К дополнительным относятся такие признаки, как одушевленность-неодушевленность и затрудненность формы:
ПризнакЗначениеТолкование
afAnimated0x01Данная форма прилагательного или причастия согласуется только с одушевленными существительными
afNotAlive0x02Данная форма прилагательного или причастия согласуется только с неодушевленными существительными
afHardForm0x04Затрудненная форма, отождествление которой возможно лишь в режиме распознавания затрудненных форм слов

2.4.Идентификаторы форм

Часть речиFIDТолкование
существительное 0 ед. именительный падеж
1родительный падеж
2дательный падеж
3винительный падеж
5творительный падеж
6предложный падеж
7звательный падеж
10 мн. именительный падеж
11родительный падеж
12дательный падеж
13винительный падеж
15творительный падеж
16предложный падеж
17звательный падеж
прилагательное 0муж.именительный падеж
1родительный падеж
2дательный падеж
3винительный падеж, неодушевлённый
4винительный падеж, одушевлённый
5творительный падеж
6предложный падеж
8-13жен.см. мужской род, формы 0 - 6
16-22ср.
24-30мн.
глагол 0инфинитив регулярная форма
1 возвратная форма
2повелительное невозвратный ед.
3 мн.
4 возвратный ед.
5 мн.
6 буд. 1-е лицо невозвратная ед.
7 мн.
8 возвратная ед.
9 мн.
10 2-е лицо невозвратная ед.
11 мн.
12 возвратная ед.
13 мн.
14 3-е лицо невозвратная ед.
15 мн.
16 возвратная ед.
17 мн.
18 наст. 1-е лицо невозвратная ед.
19 мн.
20 возвратная ед.
21 мн.
22 2-е лицо невозвратная ед.
23 мн.
24 возвратная ед.
25 мн.
26 3-е лицо невозвратная ед.
27 мн.
28 возвратная ед.
29 мн.
30-61 причастие действительное невозвратноесловоизменение по схеме прилагательного
62-93 возвратное
94-125 страдательное
126 деепричастие невозвратное
127 возвратное
128 прош. невозвратные муж.
129 жен.
130 ср.
131 мн.
132 возвратные муж.
133 жен.
134 ср.
135 мн.
136-167 причастие действительное невозвратноесловоизменение по схеме прилагательного
168-199 возвратное
200-231 страдательное
232 деепричастие невозвратное
233 возвратное

3.Программный интерфейс

3.1.Коды ошибок

Код ошибкиЗначениеТолкование
LEMMBUFF_FAILED-1При лемматизации переполнился массив нормальных форм
LIDSBUFF_FAILED-2При лемматизации переполнился массив идентификаторов лексем
GRAMBUFF_FAILED-3При лемматизации переполнился массив грамматических описаний
WORDBUFF_FAILED-4Слишком длинное исходное слово
PAGELOAD_FAILED-5Не удалась загрузка страницы словаря
PAGELOCK_FAILED-6

3.2.Флаги настройки – options

НастройкаЗначениеТолкование
sfStopAfterFirst0x0001Достаточно одного отождествления
sfIgnoreCapitals0x0002Игнорировать корректность капитализации
sfHardForms0x0004Разрешать затрудненные словоформы

3.3.Проверка правописания

short MLMA_API EXPORT mlmaukCheckWord( const char* lpWord, unsigned short options );
Функция проверяет, есть ли в словаре слово или его форма, то есть правильно ли оно начертано.

Аргументы:
lpWord– ASCIIZ-строка, украинское слово, правописание которого следует проверить;
options– настройки морфологического анализатора.

Функция возвращает 0, если слово не опознано, 1 – если слово написано правильно или отрицательный код ошибки.

3.4.Построение списка нормальных форм

short MLMA_API EXPORT mlmaukLemmatize( const char* lpWord, unsigned short options, char* lpLemm, unsigned long* lpLIDs, char* lpGram, unsigned short ccLemm, unsigned short cdwLID, unsigned short cbGram );
Функция строит список нормальных форм поданного слова и извлекает идентификаторы тех лексем и грамматические описания тех форм, с которыми это слово совпало. Возвращает значение больше нуля – количество построенных лексем, если слово опознано, 0, если слово не опознано, или отрицательное значение – код ошибки.

lpWord– ASCIIZ-строка, слово, которое следует проанализировать;
options– настройки морфологического анализатора;
lpLemm– указатель на массив, принимающий нормальные формы слов, или NULL, если тексты нормальных форм не требуются;
lpLIDs– указатель на массив, принимающий идентификаторы лексем, или NULL, если идентификаторы лексем не требуются;
lpGram– указатель на массив, принимающий грамматические описания, или NULL, если они не требуются;
ccLemm– размерность массива lpLemm в байтах;
cdwLID– размерность массива lpLIDs в двойных словах;
cbGram– размерность массива lpGram в байтах.

Тексты нормальных форм восстанавливаются в минимально допустимой степени капитализации, то есть если слово может быть написано всеми строчными буквами, оно восстанавливается всеми строчными, если только с заглавной буквы - то с заглавной, и т. д.

Грамматические описания восстанавливаются в “плавающем” формате. После отождествления массив psGInfo содержит количество блоков грамматических описаний, равное количеству нормальных форм. При этом каждый блок грамматического описания в начале содержит байт, указывающий количество структур SGramInfo, лежащих сразу после него.

3.5.Построение формы слова по идентификатору

short MLMA_API EXPORT mlmaukBuildForm( const char* lpWord, unsigned long dwLexID, unsigned short options, unsigned char idForm, char* lpDest, unsigned short ccDest );
Функция строит словоформу по ее нормальной форме или идентификатору лексемы и идентификатору этой формы. Возвращает количество построенных строк в случае успеха, 0, если ни одной формы построить не удалось, или отрицательное значение – код ошибки.

Аргументы:
lpWord– ASCIIZ-строка, слово, которое следует проанализировать, или NULL, если задан идентификатор лексемы;
dwLexId– идентификатор лексемы слова или 0, если построение формы идет по ключу – строке;
options– настройки морфологического анализатора;
idForm– идентификатор требуемой формы слова;
lpDest– указатель на массив, принимающий построенные формы;
ccDest– размерность массива lpDest в байтах.

3.6.Построение формы слова по грамматическому описанию

short MLMA_API EXPORT mlmaukBuildFormGI( const char* lpWord, unsigned long dwLexID, unsigned short options, unsigned short grInfo, unsigned char bFlags, char* lpDest, unsigned short ccDest );
Функция строит словоформу по ее нормальной форме или идентификатору лексемы и расширенному грамматическому описанию этой формы. Возвращает количество построенных строк в случае успеха, 0, если ни одной формы построить не удалось, или отрицательное значение – код ошибки.

Аргументы:
lpWord– ASCIIZ-строка, слово, которое следует проанализировать, или NULL, если задан идентификатор лексемы;
dwLexId– идентификатор лексемы слова или 0, если построение формы идет по ключу – строке;
options– настройки морфологического анализатора;
grInfo– расширенное грамматическое описание требуемой формы слова;
bflags– дополнительные грамматические флажки;
lpDest– указатель на массив, принимающий построенные формы;
ccDest– размерность массива lpDest в байтах.

3.7.Перебор лексем (enumeration)

short MLMA_API EXPORT mlmaukEnumWords( TEnumWords enumproc, void *lpv );
Функция перебора всех лексем словника.

Аргументы:

enumproc– адрес функции обработки лексемы;
lpv– пользовательский параметр, передаваемый функции enumproc.

Прототип callback-функции перебора лексем:

typedef short (MLMA_API* TEnumWords)( unsigned long lid, void* lpv );
Функция вызывается функцией перебора лексем словника и получает по очереди все лексемы. Должна возвращать ненулевое значение для продолжения перебора или 0, если перебор лексем следует закончить. Параметр lpv не используется анализатором и транслируется функции напрямую.

Аргументы:

lid– идентификатор лексемы;
lpv– параметр, переданный пользователем функции mlmaukEnumWords.

3.8.Извлечение части речи лексемы

short MLMA_API EXPORT mlmaukGetWordInfo( unsigned long dwLexID, unsigned char* wdinfo );
Функция извлечения части речи по идентификатору лексемы. Возвращает ненулевое значение в случае успеха, 0, если такой лексемы нет, или отрицательное значение – код ошибки.

Аргументы:

dwLexId– идентификатор лексемы слова;
wdinfo– указатель на байт, получающий часть речи.

4.Украинский алфавит

Украинский алфавит очень близок к русскому, однако не совсем с ним совпадает. Так, в нем нет русских букв Ёё, Ыы, Ээ, однако есть некоторые дополнительные, отсутствующие в русском алфавите и, что хуже, выпадающие из общего массива кириллицы - Ґґ, Єє, Її, Іі.
В то же время в реальных текстах вместо Іі часто встречается латинское Ii, сходное по начертанию с украинским. Кроме того, апостроф используется для смягчения предыдущей согласной и иногда играет роль мягкого знака, то есть обязателен при начертании и входит в состав слова.
Для решения этой проблемы ниже приводится таблица, в которой заполнены ячейки, соответствующие символам, которые могут встречаться в составе украинских слов. Символы, вместо которых стоит *, в украинском алфавите отсутствуют, хотя и являются кириллицей.
При выделении слов для подачи модулю также следует учесть возможные огрехи некоторых кириллических драйверов клавиатуры, которых великое множество, и которые не всегда корректно отрабатывают символы, сходные по начертанию с соответствующими латинскими.
Кроме того, при обработке HTML следует учитывать, что символы, не попадающие в интервал А-я, практически всегда записываются в виде специальных последовательностей, начинающихся &.
000102030405060708090A0B0C0D0E0F
20'-
30
40I
50
60`i
70
80
90
A0ҐЄЇ
B0Ііґ
C0АБВГДЕЖЗИЙКЛМНОП
D0РСТУФХЦЧШЩЪЬЮЯ
E0абвгдежзийклмноп
F0рстуфхцчшщъьюя