Типы ключевых слов (kwtype)
Все мы знаем детский стишок Маршака про воробья:
(11) — Где обедал, воробей?
— В зоопарке у зверей.
Пообедал я сперва
За решеткою у льва.
Подкрепился у лисицы.
У моржа попил водицы.
Ел морковку у слона.
С журавлем поел пшена.
Погостил у носорога,
Отрубей поел немного.
Побывал я на пиру
У хвостатых кенгуру.
Был на праздничном обеде
У мохнатого медведя.
А зубастый крокодил
Чуть меня не проглотил.
Из первых двух строк следует, что воробей обедал у каких-то зверей, которые живут в зоопарке. Попробуем написать несложную систему правил, с помощью которых мы сможем узнать, у каких же именно зверей обедал воробей.
Для такой грамматики нам потребуется не только грамматическая, но и семантическая информация о словах из текста. Для этого нам надо построить мини-словарь.
Мы сталкивались со словарем в самом начале, когда создавали корневой файл mydic.gzt
. Теперь рассмотрим этот формат подробнее.
Словарь в Томите называется газеттиром и пишется в отдельном файле с расширением gzt
. Как и любой словарь, газеттир состоит из статей. Создадим файл animals_dict.gzt
и напишем в нем простейшую статью, в которой перечислим некоторых животных:
encoding "utf8";
TAuxDicArticle “животные”
{
key = "собака" | "кот" | "лошадь" | "корова" | "лев" | "слон" | "волк" |
"кенгуру" | "крокодил"
}
В этом примере TAuxDicArticle
– тип статьи, «животные» — ее название, а в поле key
мы перечисляем все слова, входящие в эту статью.
Созданный словарь обязательно надо импортировать в корневой словарь. Для этого в файле mydic.gzt
надо добавить следующую строчку:
import "animals_dict.gzt";
Теперь на созданную статью можно ссылаться из грамматики. Для этого используются пометы kwtype
и kwset
, в качестве значения которых выступает тип или имя статьи. Тип TAuxDicArticle
является типом по умолчанию и используется во многих статьях, поэтому мы ссылаемся на название, которое уникально:
#encoding "utf-8"
S -> 'у' (Adj<gnc-agr[1]>) Noun<kwtype='животные', gram='род', rt, gnc-agr[1]>;
S -> 'с' (Adj<gnc-agr[1]>) Noun<kwtype='животные', gram='твор', rt, gnc-agr[1]>;
Если мы запустим эту грамматику на стишке про воробья, мы получим следующие подцепочки:
у лев
у слон
у хвостатый кенгуру
Естественно, полнота результата напрямую зависит от полноты словаря: в нашем примере у нас выделились только те животные, которых мы включили в словарь.
Названий животных очень много, и перечислять их всех внутри словаря не слишком удобно. Поэтому в газеттире есть возможность из статьи сослаться на текстовый файл, в котором перечислены все слова, входящие в данную статью. Перепишем наш словарь с учетом этой возможности:
TAuxDicArticle “животные”
{
key = { "animals.txt" type=FILE }
}
В поле key указывается название текстового файла и тип ключа — FILE. Соответственно, в файле animals.txt перечислены названия животных:
собака
кот
лошадь
корова
лев
слон
волк
кенгуру
крокодил
С помощью газеттира можно решать более сложные задачи, например, мы можем узнать, с какими птицами обедают воробьи. Для этого нам нужно разделить животных по разным статьям в зависимости от их класса:
TAuxDicArticle "млекопитающие"
{
key = "собака" | "кот" | "лошадь" | "корова" | "лев" | "слон" | "волк" |
"кенгуру" | "морж" | "лисица" | "носорог" | "медведь"
}
TAuxDicArticle "птицы"
{
key = "воробей" | "журавль" | "павлин"
}
TAuxDicArticle "рептилии"
{
key = "черепаха" | "крокодил"
}
Чтобы сохранить информацию о том, что все млекопитающие, птицы и рептилии являются животными, целесообразно вместо стандартного типа статьи TAuxDicArticle использовать свой — например, animal. Типы статей описываются в специальном формате в отдельном файле. Создадим файл kwtypes.proto и запишем туда следующее:
import "base.proto";
import "articles_base.proto";
message animal : TAuxDicArticle {}
Первые две строчки импортируют встроенные в парсер файлы base.proto
и article_base.proto
аналогично тому, как это делается в корневом словаре, а в последней описывается тип статьи animal
, производный от базового типа TAuxDicArticle. Все типы статей должны быть производными от TAuxDicArticle. Создание пользовательских типов статей позволяет объединить несколько статей в группу, чтобы в дальнейшем можно было бы использовать их все, указав только их тип при помощи пометы kwtype
(например, kwtype=animal
), но не перечисляя каждую в отдельности.
Теперь мы можем переписать газеттир с использованием нового класса:
encoding "utf-8";
import "kwtypes.proto"; //импортируем файл, в котором описаны используемые в словаре типы статей
animal "млекопитающие"
{
key = "собака" | "кот" | "лошадь" | "корова" | "лев" | "слон" | "волк" |
"кенгуру" | "морж" | "лисица" | "носорог" | "медведь"
}
animal "птицы"
{
key = "воробей" | "журавль" | "павлин"
}
animal "рептилии"
{
key = "черепаха" | "крокодил"
}