
- •Глава 5
- •Обработка текста
- •Введение
- •Лексический анализ и грамматический разбор
- •Содержание данной главы
- •Стратегии грамматического разбора и стратегии решения задач
- •5. 1. Лексический анализатор
- •Процедура "читатьпредлож"
- •Алгоритм работы лексического анализатора "читатьпредлож"
- •Использование программы "читатьпредлож"
- •5. 2. Система нисходящего грамматического разбора Программа "объект"
- •Использование программы "объект"
- •Использование процедуры "объект" в обратном направлении
- •Расширение грамматики
- •Принцип работы системы нисходящего грамматического разбора
- •5. 3. Система восходящего грамматического разбора Принцип работы системы восходящего грамматического разбора
- •Вид правила "восх_объект"
- •Анализ процесса грамматического разбора
- •Леворекурсивные правила
- •Работа леворекурсивного правила
- •Использование процедур грамматического разбора
- •5. 4. Конвертер программ с dec-10 пролога на микро-пролог Синтаксис микро-Пролога
- •Компоненты микро-Пролога
- •Реализация программы "d_to_m"
- •Использование процедуры "d_to_m"
- •Улучшение интерфейса с пользователем
- •Ограничения процедуры "d_to_m"
- •5.5. Язык запросов
- •Спецификация схемы базы данных
- •Стратегия реализации
- •Грамматика языка запросов
- •Программа "зобъект"
- •Алгоритм работы программы "зобъект
- •Процедура "построить_псписки"
- •Выходные данные программы "построить-псписки"
- •Процедура "построить-зсписки"
- •Выходная информация программы "построить_зсписки"
- •Процедура "список_во_фразу"
- •Выходные данные процедуры "список_во_фразу"
- •Процедура "печатать_тсписок"
- •Объединение составных частей в единую программу
- •Интерпретатор
- •Библиографические заметки
- •Упражнения
Использование процедуры "d_to_m"
Подадим на вход процедуры "d_to_m" простой факт, записанный на DEC-10 Прологе, и посмотрим, что получится на выходе процедуры. Факт:
отец(филип,чарльз).
можно представить в виде списка слов:
[ отец,' (', филип, чарльз, ')','.']
Этот список можно подвергнуть грамматическому разбору:
! ?- d_to_m (фраза,
[ отец,' (', филип, чарльз,')',' .' ],
[],МР,[]).
MP=['('.'(',отец,филип, чарльз,')',')']
От формы записи в виде списка легко можно перейти к обычной форме записи факта в микро-Прологе:
( (отец филип чарльз) )
С другой стороны, правило, записанное на микро-Прологе:
((элемент X(Y | Z)) (элемент X Z))
можно разложить на следующие элементы:
['(','(',элемент, X,'(\Y,'! ',Z,')',
')','(', элемент, X, Z,')' ’)']
Затем это правило можно подвергнуть грамматическому разбору:
! ? - d_to_m(фраза, DEC,[ ],
['(','(',элемент,Х,'(',Y,
'|',Z,')',')','(',элемент,
X,Z,')',')' ]),
[]).
DEC=[элемент.' (', X,',',[','Y'.' |',
'Z',' ]',' )' ,' :- , элемент,' (',
X,',',Z,')','.']
От формы записи в виде списка можно перейти к следующей форме:
элемент (X. [Y| Z]) :- элемент (X, Z).
Улучшение интерфейса с пользователем
Одно из затруднений, связанных с использованием приведенных выше запросов, заключается в том, что для этих запросов требуется кропотливый перевод языковых выражений в списки, состоящие из элементов. Ранее мы уже пользовались программой, которая автоматизировала эту утомительную задачу. Это был лексический анализатор "читатьпредлож", описанный в начале главы. Однако для того, чтобы стало возможным применение процедуры "читатьпредлож" для ввода Пролог - текстов, в базу данных "пунктуация" необходимо добавить дополнительные лексикографические символы, такие как , и ; .
Для преобразования выходных данных систем грамматического разбора в удобочитаемую форму можно воспользоваться процедурой, которая выводит на печать каждый элемент списка. Эту функцию выполняет процедура "печать выраж":
печать_выраж ( [ ]) :- n1.
печать_выраж (X ; Y]) :-
write(X), write(' '), печать_выраж(Y).
Теперь можно употребить процедуру "d_to_m" в нижеследующем составном запросе:
! ?- write (' введите фразу DEC-10 Пролога:'),
nl,
читатьпредлож (DЕС),
d_to_m (фраза, DEC, [ ], МР, [ ] ),
печать_выраж (МР),
fail.
введите фразу DEC-10 Пролога:
отец(филип, чарльз).
( (отец филип чарльз) )
нет
Подцель «fail», стоящая в конце запроса, подавляет печать значений переменных.
Ограничения процедуры "d_to_m"
Приведенная версия процедуры "d_to_m" не может обрабатывать следующие синтаксические особенности DEC-10 Пролога:
1) структуры;
2) префиксные, инфиксные и постфиксные операции;
3) большую часть в строенных предикатов.
Это как раз те особенности, по которым отсутствует структурное сходство между рассматриваемыми версиями языка Пролог. Поэтому для расширения процедуры "d_to_m" с тем, чтобы она смогла работать с этими языковыми средствами, потребуется добавить правила, которые будут применяться только при конвертировании в одну сторону. Например, вследствие того, что в микро-Прологе отсутствуют структуры общего назначения, имеющиеся в DEC-10 Прологе( в микро-Прологе есть целостные информационные элементы (tuples), но они не могут быть вложенными таким же образом, как структуры.), программист, пишущий программы на микро-Прологе, пользуется списками во многих ситуациях, в которых программист, работающий на DEC-10 Прологе, употребил бы структуру. Поэтому если бы программа "d_to_m" применялась для конвертирования с DEC-10 Пролога на микро-Пролог, то она должна была бы преобразовывать каждую структуру DEC-10 Пролога в список микро-Пролога. Но в этом случае при переводе программ с микро-Пролога на DEC-10 Пролог возникла бы неоднозначность: если программа-конвертер [встретит в микро - прологовском тексте список, то будет неясно во что его следует преобразовывать - в список DEC-10 Пролога или же в структуру DEC-10? Если допустить, чтобы правила, устанавливающие взаимное соответствие между структурой DEC-10 Пролога и списком микро - Пролога, были бы полностью двунаправленными, то в программе "d_to_m" Нужно было бы иметь два способа грамматического разбора каждого спискa микро-Пролога.
Наиболее надежное, хотя и требующее кропотливой работы решение этой задачи состоит в том, что заранее объявлять имена и количества аргументов всех структур DEC-10, используемых в программе. Тогда если при переводе с микро-Пролога на DEC-10 Пролог программа "d_to_m" (Встретит список микро-Пролога, то она обратится к базе данных, состоящей из структур DEC-10, чтобы выяснить, во что нужно преобразовать этот конкретный список - в DEC-10 структуру или же в список DEC-10. Приведем текст расширения программы "d_to_m", которое реализует на практике этот метод работы со структурами.
% база данных, состоящая из структур DEC-10:
% Имя Количество аргументов
структура (клиент, 3).
структура (маршрут, 3).
% преобразовать список микро-Пролога в структуру DEC-10:
% структура _или_список -—> атом ( арг_ты ) // ( атом арг_ты )
d_to_m (структура_или_список, Id, Od, Im, Om) :—
найти__допустимую_структуру (Id, Od, Im, Om).
% _ _
найти_опустимую_структуру ([ Имя,' (' | Rd], Od,
% + _
['(',Имя ! Rm],Om) :-
var (Rd), % направление: с МР на DEC
atom (Имя),
% проверить, является ли переменная Имя именем структуры
% DEC-10:
структура (Имя, Кол_во_арг),
% взять арг_ты из начала списка Rm:
d_to_m (арг_ты, Rd, [')' j Od], Rm,
[')','Оm]),
% проверить правильность количества аргументов:
length (Rm, Rm длина),
length ([')' \ От], От длина),
Кол_во_арг is Оmдлина — Rmдлина.
% преобразовать структуру DEC-10 в список микро-Пролога:
% структура_или_список -->атом (арг_ты) // (атом арг_ты)
d_to_m (структура _или_список, [Имя,' (' | Rd], Od,
['(',Имя |Rm],Оm) :-
var (Rm), % направление: с DEC на МР
atоm (Имя),
d_to_m (арг_ты, Rd [')' | Od], Rm, [')' | Оm] ).
% преобразовать список микро-Пролога в список DEC-10 или
% наоборот:
% структура_или_список ~—> список // список
d_to_m (структура _или_список, Id, Od, Im, От) :—
not (найти__допустимую_структуру (Id, Od, Im, Оm)),
d_to_m (список, Id, Od, Im, Оm).
% аргумент ~->перем ; атом; структура _или_список
d to_m (аргумент. Id, Od, Im, Om) :-
d_to_m (перем, Id, Od, Im, Om)
;
d_to_m (атом. Id, Od, Im, Om)
;
d_to_m (структура_или_список. Id, Od, Im, Om).
Нижеследующие запросы иллюстрируют работу данного расширения процедуры "d_to_m".
| ?— repeat,
write (' введите структуру или список микро-'),
write (' Пролога:'), n1,
читатьпредлож (МР),
oдин_paз(d_to_m (структура _или_список, DEC, [ ], МР, [ ]))
пeчaть_выpaж(DEC), nl,
fail.
введите структуру или список микро-Пролога:
(один два три)
[ один, два, три ]
введите структуру или список микро-Пролога:
(клиент смит сокращенная неделя)
клиент (смит, сокращенная, неделя)
введите структуру или список микро-Пролога:
(маршрут нью-йорк бостон)
[ маршрут, нью_йорк, бостон ]
В последнем примере список не был преобразован в структуру "маршрут", как согласно объявлению количество аргументов у структуры "маршрут" должно равняться трем, а не двум.
Остальные особенности DEC-10 Пролога, такие как операции и встроенные предикаты, можно реализовать по аналогии с тем, как это было сделано для структур.