БЛОК-СХЕМА РАБОТЫ ИНТЕРПРЕТАТОРА

Анализатор команд

            Анализатор команд – это подпрограмма, на входе которой находится введенная игроком строка, а на выходе массив, состоящий из значений – Действие, Основной, Дополнительный и Вспомогательный предметы, а также количество по каждому из них. Или ошибка и сообщение с причиной.

 

 

Процедура ПоискДействия(Строка)

 

Входящие данные: строка, которая должна содержать только один глагол, а также все относящиеся к нему имена существительные, прилагательные, числительные, предлоги и наречия.

 

Описание: ищет в строке действие и предметы и составляет из них массив, каждая строка которого будет содержать некоторое действие к выполнению.

 

Алгоритм:

v    Запускаем процедуру ПроверкаСлов(Строка). Если строка с ошибками, то дальше не идём.

v    Последовательно каждое слово в строке ищем в списке наречий;

Ø     Если нашли, то удаляем слово из строки и ищем дальше (пока опустим обработку наречий);

v    Последовательно каждое слово в строке ищем в списке глаголов;

Ø     Если нашли, то запоминаем глагол, удаляем слово из строки и заканчиваем поиск глагола;

Ø     Если нет, то ошибка. Такая строка не должна попадать в эту процедуру.

v    Отправляем полученную строку без глагола в функцию РазделениеПредметов(Строка,Глагол);

v    Отправляем полученный из функции массив в функцию РасстановкаПредметов(Массив, Глагол);

v    Получили другой массив. Он выглядит следующим образом:

 

 

Основной предмет

Кол-во

Предлог

Дополнительный предмет

Кол-во

Предлог

Вспомогательный предмет

Кол-во

 

v    Делаем цикл по строкам:

Ø     Если глагол непереходный, то есть основной предмет указывать не нужно, а он указан, то ошибка. И наоборот – тоже ошибка.

Ø     Ищем среди конструкций глагола такую, в которой участвует указанный набор предметов и указанные предлоги. Если не найдена – ошибка.

Ø     Если найдена, то ищем действие, которое описывает данная конструкция. Если такое действие не существует – ошибка.

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

v    Дело сделано – получили массив с действиями, предметами и их количеством.

 

 

Процедура ПроверкаСлов(Строка)

 

Входящие данные: строка текста, введённая игроком.

 

Описание: проверяет наличие каждого из слов строки в своём словарном запасе.

И выдаёт ошибку, если что не так. Если есть желание, можно попытаться автоматически исправить ошибки. Также должна проверять указание нескольких предлогов или разделителей подряд и указание разделителя сразу после предлога. Эта процедура должна вычленить очевидные ошибки в строке.

 

 

Процедура РазделениеПредметов(Строка, Глагол)

 

Входящие данные: строка, которая содержит команду без глагола, то есть, по сути, информацию о предметах.

 

Результат: массив вида:

 

Предлог

Количество

Падеж

Предмет в игровой базе

Флаг наличия разделителя

 

 

 

Описание: эта процедура делит входящую строку на части, относящиеся к каждому из предметов. Каждая такая часть анализируется и порождает одну строчку результирующего массива.

 

Алгоритм:

v    Ищем первое имя существительное в строке. Если не найдено, то ошибка;

Ø     Правее найденного имени ищем первый предлог, имя существительное или разделитель «и» или «,»;

§       Если там предлог или разделитель, то всё, что до него, относится к текущему имени существительному;

§       Если там другое существительное, то все слова между ними будем относить к тому, что находится правее в строке (В дальнейшем можно усложнить алгоритм, анализируя наличие числительных и падеж прилагательных между существительными);

Ø     В найденной подстроке разделителей быть не должно, но не факт, нужно проверить. Пока можно их попросту удалять.

Ø     В подстроке ищем предлог. Он там должен быть один (иначе – ошибка). Найденный предлог вырезаем из строки и добавляем в массив.

Ø     Подстроку без предлога отправляем в функцию ПоискПредмета(Строка,Глагол,Предлог), а возвращённые предмет и количество добавляем в результирующий массив;

v    Возвращаем результирующий массив. Он выглядит следующим образом:

 

Предлог

Количество

Падеж

Предмет в игровой базе

Флаг наличия разделителя

 

 

 

 

 

Функция ПоискПредмета(Строка,Глагол,Предлог)

 

Входящие данные: строка, которая должна содержать только имена существительные и прилагательные,  а также числительные. Последние должны находиться в начале строки, дальнейший порядок не важен. Глагол и предлог идут отдельно.

 

Результат: предмет в игровой базе, количество и падеж, в котором он описан в строке. Или ошибка.

 

Алгоритм:

v    Ищем первое в строке слово среди числительных;

Ø     Если нашли, то Количество=Количество + найденная сумма, удаляем первое слово из строки и ищем дальше;

Ø     Если нет, то дальше числительных уже быть не должно (желательно этот факт проверить и вывести ошибку, если что не так). Если числительных не было вообще, то Количество=1;

v    Последовательно каждое слово в строке ищем среди имен прилагательных;

Ø     Если нашли, то добавляем в массив найденное имя, удаляем слово из строки и ищем дальше;

v    Ищем первое в строке слово среди имен существительных;

Ø     Если нашли, то добавляем в массив найденное имя, удаляем первое слово из строки и ищем дальше;

Ø     Если нет, то ошибка - такого слова нет в базе;

v    Строка должна быть пуста. Имеем: количество, набор имён существительных и набор имен прилагательных. Узнаём падеж слов строке со следующими правилами:

Ø     Если по написанию имени существительного можно точно определить падеж, то берем его. Падеж прилагательных в этом случае роли не играет

Ø     Если же определить нельзя (например, «пальто»), тогда определяем падеж по совокупности всех имен прилагательных и существительного. Если задача имеет решением один единственный падеж – берем его.

Ø     Если в функцию передали предлог, тогда среди конструкций глагола ищем, какие падежи могут идти после данного предлога, и сравниваем с падежами из строки. Если решение единственно, тогда берем его. Если же нет (такой вариант вообще существует?) выбираем падеж по некоторому приоритету.

Ø     Если предлога нет, тогда это либо винительный падеж (основной предмет), либо творительный (дополнительный или вспомогательный предмет). Опять же просматриваем все конструкции глагола и пытаемся решить задачу. Если единственного решения нет (варианты таких команд есть, но какие-то бессмысленные), тогда выбираем винительный падеж.

v    Ищем предмет, в котором присутствуют все названные имена.

Ø     Нашли – возвращаем результат.

Ø     Нет – ошибка, такого предмета в игровой базе нет.

 

 

Функция РасстановкаПредметов(Массив,Глагол)

 

Входящие данные: глагол и массив из функции РазделениеПредметов():

 

Предлог

Количество

Падеж

Предмет в игровой базе

Флаг наличия разделителя

 

 

 

 

Результат: Массив вида:

 

Основной предмет

Кол-во

Предлог

Дополнительный предмет

Кол-во

Предлог

Вспомогательный предмет

Кол-во

 

Описание: функция должна разделить предметы на основной, дополнительный и вспомогательный, а так же определить их комбинации, с которыми будут потом совершаться действия. Каждый из таких вариантов заносится в массив.

Алгоритм:

v    Если глагол непереходный, то есть основной предмет указывать не нужно, тогда нам важны только первый и пятый столбцы входящего массива (предлог и флаг разделителя):

предлог

флаг разд.

из

0

в

1

в

1

в

0

из

0

 

Такая последовательность из предлогов и разделителей делится на части, каждая из которых имеет вид: (I)Предлог1 + [разделитель] + (II)[Предлог2 + разделитель + Предлог2 +разделитель...] + (III)[Предлог2]. То, что указано в квадратных скобках, может и не присутствовать. Почему выбран вариант с одним первым предлогом? Давайте сравним:

«Выстрелить из пушки по воробьям и по сорокам»

и

«Выстрелить из пушки и из винтовки по сорокам».

В первом случае, как бы произносящий не ставил ударение, ясно, что стрелять нужно по тем и другим. Во втором, если сделать акцент на «из пушки» и после этого выдержать паузу, получится, что из пушки нужно просто стрельнуть, а вот из винтовки уже по птичкам.

v    Такая логика и привела к вышеупомянутой структуре. Как найти часть:

Ø     (I) – берем, естественно, на эту роль первую строчку. Если есть разделитель, то часть сразу же закончена.

Ø     (II) - все последующие строки с одинаковыми предлогами (отличными от первого, иначе – ошибка) и с разделителями.

Ø     (III) – Если разделителя нет, а предлог совпадает с предыдущими, то он относится к первой части только в том случае, если дальше уже массив заканчивается. Иначе он становится началом для построения следующей части.

v    Части найдены, можно уже распределить предметы и определить количество действий. Ясно, что предметы, которые идут с Предлогом1 составят дополнительные предметы и к каждому из них указывается набор вспомогательных предметов, то есть тех, которые идут с Предлогом2. Основного предмета не будет, т.к. глагол непереходный.

 

 

v    С переходными глаголами всё немного сложнее. Здесь нужно поделить все предметы и предлоги на свои основные предметы, а дальше уже обработка каждой такой части совпадает с обработкой у непереходных глаголов.

v    Основной предмет  всегда в винительном падеже и без предлога. В таблице падеж и предлог указаны. Как будем делить: всё, до последнего разделителя между одним и другим основными предметами, относится к первому, оставшаяся часть – ко второму.

v    Теперь можем заполнить результирующий массив.

 

Процедура АнализСтроки(Строка)

 

Входящие данные: строка, которая содержать команду игрока.

 

Описание: должна найти в строке несколько действий и поделить предметы между ними, а затем для каждой части вызвать функцию ПоискДействия().

 

Алгоритм:

v    Между двумя глаголами отнесём к первому всё то, что идёт до последнего разделителя между ними. Остальное уйдёт ко второму.