
- •Глава 5
- •Обработка текста
- •Введение
- •Лексический анализ и грамматический разбор
- •Содержание данной главы
- •Стратегии грамматического разбора и стратегии решения задач
- •5. 1. Лексический анализатор
- •Процедура "читатьпредлож"
- •Алгоритм работы лексического анализатора "читатьпредлож"
- •Использование программы "читатьпредлож"
- •5. 2. Система нисходящего грамматического разбора Программа "объект"
- •Использование программы "объект"
- •Использование процедуры "объект" в обратном направлении
- •Расширение грамматики
- •Принцип работы системы нисходящего грамматического разбора
- •5. 3. Система восходящего грамматического разбора Принцип работы системы восходящего грамматического разбора
- •Вид правила "восх_объект"
- •Анализ процесса грамматического разбора
- •Леворекурсивные правила
- •Работа леворекурсивного правила
- •Использование процедур грамматического разбора
- •5. 4. Конвертер программ с dec-10 пролога на микро-пролог Синтаксис микро-Пролога
- •Компоненты микро-Пролога
- •Реализация программы "d_to_m"
- •Использование процедуры "d_to_m"
- •Улучшение интерфейса с пользователем
- •Ограничения процедуры "d_to_m"
- •5.5. Язык запросов
- •Спецификация схемы базы данных
- •Стратегия реализации
- •Грамматика языка запросов
- •Программа "зобъект"
- •Алгоритм работы программы "зобъект
- •Процедура "построить_псписки"
- •Выходные данные программы "построить-псписки"
- •Процедура "построить-зсписки"
- •Выходная информация программы "построить_зсписки"
- •Процедура "список_во_фразу"
- •Выходные данные процедуры "список_во_фразу"
- •Процедура "печатать_тсписок"
- •Объединение составных частей в единую программу
- •Интерпретатор
- •Библиографические заметки
- •Упражнения
Алгоритм работы программы "зобъект
Процедура "зобъект" имеет на два аргумента больше, чем процедура "объект". Через четвертый аргумент процедуры "зобъект" возвращается результат процесса грамматического разбора. Например, если будет обнаружен объект "па" (предикат + аргумент), то процедура разбора возвратит структуру, состоящую из предиката, аргумента и значения:
(p,a,v)
Список таких структур строится нетерминалами "па список" и "уточнение". Построенные списки объединяются в один список в нетерминале "предложение". Список структур, вырабатываемый нетерминалом "предложение", содержит все аргументы, к которым нужно обратиться в итоговом Пролог-запросе. Пятый аргумент процедуры "зобъект" используется только в правиле "предложение"; он является списком всех структур, которые требуется вывести на печать после выполнения Пролог-запроса.
Выходные данные процедуры грамматического разбора
Можно проверить работу процедуры грамматического разбора, проанализировав результаты, которые вырабатывает тестовый запрос.
| ?- зобъект (
[выдать, служащий, имя, и, отдел, менеджер, где,
код, служащий, является, отдел, код],
[ ], предложение, Tlist, Printlist).
Tlist= [ т (служащий, имя, _613),
т (отдел, менеджер, _642),
т (служащий, код, _668),
т (отдел, код, _668) ]
Printlist= [ т (служащий, имя, _613),
т (отдел, менеджер, _642) ]
Заметьте, что в списке «Printlist» содержатся только те структуры, к которым имеется обращение из "па_список" после команды "выдать". Поэтому список «Printlist» является подмножеством списка «Tlist». Список «Tlist» содержит все объекты "па", упомянутые в запросе. В результате действия правила "уточнение" одна и та же переменная _668 появляется и в структуре, несущей информацию о служащем, и в структуре со сведениями об отделе.
Процедура "построить_псписки"
Следующей задачей будет объединение каждого множества структур "т" с одинаковыми именами предикатов в список, состоящий из имени предиката и пар имя/значение аргумента. Каждая пара имя/значение аргумента обозначается идентификатором « AVpair » и записывается в виде структуры «п(Имя, Значение)». Итоговый список таких структур носит название «Plist».
Пусть, к примеру, в списке «Tlist», построенном процедурой грамматического разбора/содержатся две структуры "т":
[т(служащий,имя,_1), т (служащий,код,_2)]
Тогда будет сгенерирован такой список « Plist »:
[служащий, п (имя,„I), п (код,_2) ]
Процедура "построить_псписки" берет в качестве входного аргумента список «Tlist», выработанный процедурой "зобъект", а затем генерирует список «Plists», каждым элементом которого является список «Plist». Каждому списку «Plist» соответствует отдельный предикат, встречающийся в списке «Tlist » . Процедура "построить_псписки" отслеживает предикаты, которые она уже обработала, помещая их во второй аргумент, обозначаемый идентификатором «Donelist». Когда процедура построить_псписки" встречает необработанный предикат, она вызывает процедуру "построить_парыАЗ" для построения структур "п" по всем структурам "т" из списка «Tlist», содержащим этот предикат. Вызов Процедуры "унифицировать_перем" преобразует получившийся список структур "п" таким образом, что переменные, несущие информацию о значениях аргументов, унифицируются в тех случаях, когда совпадают имена аргументов. Например, если в список структур « AVpairsI » (входная информация для процедуры "унифицировать_перем") входят такие две структуры "п":
[п (имя,_50),. . . п (имя. —65)],
то в списке структур «AVpairs2 » (выходная информация процедуры "унифицировать_перем") будут унифицированными такие неконкретизированные переменные:
[п(имя. -50), . . . п(имя,„50)].
Этот шаг необходим для сохранения любых унификации, выполненных Процедурой грамматического разбора.
% имена переменных:
% Р = имя предиката
% А = имя аргумента
% V = значение аргумента (неконкретизированная
% переменная)
%Tlist = [t(p,a,v),t(p,a,v),...]
% AVpairs = [п (А, V), п (А, V),. . . ]
% Plist = [P,n(A,V),n(A,V)....]
% Plists = список, каждый элемент которого - это список Plist
% построить_псписки:
% преобразовать список структур т (Р, А, V) в
% Р + список структур п (А, V).
% + + _
построить_псписки ([],_, [ ]).
% пропустить структуру т(Р, А, V), , если значение Р содержится в
% списке Donelist:
построить_псписки ([т(Р, А, V); Tlist], Donelist, Plists) :-
элемент (Р, Donelist),
!, построить-псписки (Tlist, Donelist, Plists).
% в противном случае обработать Р:
построить-псписки ([т (Р, А, V); Tlist], Donelist,
[[Р| AVpairs2 ] | Plists]) :-
построить-парыАЗ (Р, [t(p,a,v); Tlist] ,AVpairsl),
унифицировать_перем (AVpairsI, AVpairs2),
% добавить Р в список Donelist:
!, построить-псписки (Tlist, [P ; Donelist], Plists).
% построить_парыАЗ:
% построить список структур п (А, V) для одного предиката.
% + + -
построить-парыАЗ (_, [ ], [ ]).
%Р (первый аргумент) согласуется с Р, входящим в структуру
%т(Р, А, V), поэтому добавить структуру п(А, V) в список AVpairs:
построить_парыАЗ (Р, [т(Р, А, V) ; Tlist],
[п (A, V); AVpairs]) :-
!, построить_парыАЗ (Р, Tlist, AVpairs).
% Р 1 не согласуется с Р2, поэтому продвинуться вперед:
построить_парыАЗ (Р1, [т(Р2, А, V) ; Tlist], AVpairs) :-
!, построить-парыАЗ (Р1, Tlist, AVpairs).
% + _
унифицировать-перем ([ ], [ ]).
унифицировать_перем ([п(А, V) | In-AVpairs],
[п(А, V) ; Out-AVpairs]) :-
% "элемент" унифицирует V с V, когда А согласуется с А:
элемент (п(А, V), In_AVpairs),
!, унифицировать_перем (In_AVpairs, Out_AVpairs).
унифицировать-перем ([п(А, V); In_AVpairs],
[п(А, V) ; Out-AVpairs]) :-
% если подцель "элемент" потерпит неудачу, перейти к
% следующей паре:
!, унифицировать-перем (hi-AVpairs, Out—A Vpairs).