Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Контрольные вопросы ТЯП.doc
Скачиваний:
6
Добавлен:
13.09.2019
Размер:
292.35 Кб
Скачать

23. Много- и однопроходные трансляторы

Синтаксический анализ, особенно в случае неоднозначных грамматик, - хорошее приложение для логического программирования, и для Пролога в частности. (Собственно, Пролог как раз и создавался для этой цели). Правила синтаксиса можно прямо выразить как предложения логической программы, а механизм отката позволяет анализировать грамматики практически произвольного вида. Последнее не очень актуально для современных языков программирования. Их грамматики содержат существенные ограничения, позволяющие однозначно выбирать соответствующее правило грамматики на основе анализа одной лексемы. Но некоторые языки, такие как Кобол или Фортран, не говоря уж о естественных языках, требуют гораздо более глубокого анализа. Логические программы - один из наиболее гибких способов выполнения синтаксического анализа. Их главный недостаток сотсоит в том, что, если грамматика является в значительной степени неоднозначной, синтаксический анализатор оказаться чрезвычайно медленным. Но если неоднозначность ограничена малыми фрагментами данных, например предложениями естественного языка, эффективность будет вполне приемлемой.

24. Метод рекурсивного спуска

В основе метода рекурсивного спуска лежит левосторонний разбор строки языка. Исходной сентенциальной формой является начальный символ грамматики, а целевой – заданная строка языка. На каждом шаге разбора правило грамматики применяется к самому левому нетерминалу сентенции. Данный процесс соответствует построению дерева разбора цепочки сверху вниз (от корня к листьям).

Метод рекурсивного спуска реализует разбор цепочки сверху вниз следующим образом. Для каждого нетерминального символа грамматики создается своя процедура, носящая его имя. Задача этой процедуры – начиная с указанного места исходной цепочки, найти подцепочку, которая выводится из этого нетерминала. Если такую подцепочку считать не удается, то процедура завершает свою работу вызовом процедуры обработки ошибок, которая выдает сообщение о том, что цепочка не принадлежит языку грамматики и останавливает разбор. Если подцепочку удалось найти, то работа процедуры считается нормально завершенной и осуществляется возврат в точку вызова. Тело каждой такой процедуры составляется непосредственно по правилам вывода соответствующего нетерминала, при этом терминалы распознаются самой процедурой, а нетерминалам соответствуют вызовы процедур, носящих их имена.

Метод рекурсивного спуска применим к грамматике, если правила вывода грамматики имеют один из следующих видов:

1) A, где (VTVN)*, и это единственное правило вывода для этого нетерминала;

2) Aa11 | a22 |…| ann, где ai VT для каждого i=1, 2,…, n; aiaj для ij, i(VTVN)*, т.е. если для нетерминала

Можно применить эквивалентные преобразования КС-грамматик, которые способствуют приведению грамматики к требуемому виду, но не гарантируют его достижения.

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

La | a,L или в сокращенной форме La{,a}.

Формально здесь не выполняются условия метода рекурсивного спуска, т.к. две альтернативы начинаются одинаковыми терминальными символами. Но если принять соглашения, что в подобных ситуациях выбирается самая длинная подцепочка, выводимая из нетерминала L, то разбор становится детерминированным, и метод рекурсивного спуска будет применим к данному правилу грамматики.

25. Дерево разбора в автоматной грамматике

26. Регулярные выражения

Регулярный язык L в некотором алфавите  представляет собой регулярное множество строк.

Определение 2.1. Регулярное множество есть , либо {}, либо {а} для некоторого а , либо множество, которое можно получить из указанных множеств путем применения к ним конечного числа операций сцепления, объединения и итерации.

В основе метода определения регулярности заданного языка лежит лемма о разрастании языка.

Лемма о разрастании языка. В достаточно длинной строке регулярного языка всегда можно найти непустую подстроку, повторение которой произвольное количество раз порождает новые строки того же самого языка.

Удобным средством формального определения регулярных языков являются регулярные выражения.

Определение 2.2. Регулярные выражения над алфавитом  определяются следующим образом:

1)  - регулярное выражение (обозначает пустое регулярное множество );

2) - регулярное выражение (обозначает регулярное множество {}, состоящее из пустой строки);

3) а  - регулярное выражение (обозначает множество {а});

4) если p и q – регулярные выражения, обозначающие множества P и Q, то посредством операций над выражениями определяются выражения следующих трех типов:

а) p|q или p+q – регулярное выражение (обозначает объединение PQ), где символ «|» или «+» называют операцией или (альтернативой);

б) pq или pq – регулярное выражение (обозначает множество PQ = {xy | xP, yQ}), где символ «точка» (возможно умалчиваемый) называют операцией сцепления (конкатенации);

в) p* - регулярное выражение (обозначает множество P*), где символ «*» называют операцией итерации.

Таблица 2.1 – Примеры регулярных выражений

Регул-е выраж-е

Значение регулярного выражения

01

единственная строка 01

0|1

две строки: 0 и 1

1*

строки, образованные из единиц, включая пустую строку

(0|1)*

строки, образованные из символов 0 и 1, включая пустую строку

0|1*

строка, состоящая из нуля и любые строки из единиц,

включая пустую

01*

строки, начинающиеся с нуля и любой последующей строки единиц, включая пустую

(0|1)*011

строки, образованные из символов 0 и 1, включая пустую, обязательно оканчивающиеся строкой 011

Соотношение между регулярными языками и регулярными выражениями устанавливает теорема Клини.

Теорема Клини. Каждому регулярному языку из * соответствует регулярное выражение над множеством .

27. Синтаксический анализ арифметических выражений

28. Домино Де Ремера

Домино Де Ремера. Де Ремер предложил наглядную интерпретацию задачи разбора, представив ее как игру в своеобразное домино. Играющий располагает "костями" домино нескольких типов. Типов столько, сколько правил в грамматике. Каждое правило дает один тип пластинки. Считается, что костяшек каждого типа имеется сколько необходимо. Левой части правила грамматики, нижняя - правой. Верхняя и нижние пластинки соединены резиновыми нитями. Пластинки можно представлять друг другу плоскими сторонами полукруга, если на них записаны одинаковые символы. Фигуры домино нельзя переворачивать и нельзя менять порядок следования символов. В начале игры в верхней части поля помещается полукруг, обращенный выпоклустью вверх, в котором записан начальный нетерминал грамматики. В нижние части игрового поля в полукругах, обращенных плоской частью вверх, размещаются терминальные символы. Цель состоит в том, чтобы соединить с помощью имеющихся фигур символы терминальной цепочки и начальный нетерминал. Имея ввиду интерпретацию де Ремера можно представить себе и различные подходы к решению задаче разбора. Если подбор костей удается осуществить так, что однажды поставленную кость никогда не придется убирать, мы имеем дело с детерминированным алгоритмом разбора - выбор применяемого правила грамматики всегда однозначен. Если принятые решения о выборе типа домино приходится отменять - алгоритм работает с возвратами, он недетерминированный. Детерминированные алгоритмы эффективней, и конечно всегда существует стремление найти и использовать такой алгоритм для синтаксического анализа. Если дерево строится свреху вниз от начального нетерминала в сторону терминальной цепочки, алгоритм относится к классу нисходящих, от цепочки в сторону корня дерева - восходящих. Можно вначале подбирать для левых символов, а можно для правых.

29. Эквивалентность и однозначность грамматик

30. Эквивалентной и однозначность грамматик

Однозначность грамматики и языка.

Одним из важных свойств грамматики с точки зрения трансляции является ее однозначность, означающая то, что не существует предложения, являющегося кроной двух или более деревьев вывода в данной грамматике. (Неоднозначность грамматики нельзя путать с неоднозначностью языка, порождаемого грамматикой. Язык неоднозначен, если его нельзя породить ни одной однозначной грамматикой. Таков, например, язык, состоящий из всех цепочек аnbmck, в которых либо п = т, либо т = k.)

Свойство однозначности грамматики может быть нарушено в результате эквивалентного преобразования. Например, для однозначной грамматики Г0 эквивалентной является неоднозначная грамматика, имеющая следующий набор правил:

Е → Е + Е|Е * Е|(Е)|а. Действительно, для выражения а + а * а можно построить два разных дерева вывода (рис. 2.3). Содержательно это означает следующее: нельзя сказать, что выполняется в выражении а + а * а раньше: умножение или сложение. Преобразование,’ нарушающее однозначность грамматики, почти всегда будет недопустимым.

31. LL-грамматика

32. Табличный анализатор