- •3. Опорный конспект лекций
- •3.1. Введение, определение языка
- •3.1.1. Элементы теории языка и их грамматика. Символы, цепочки и операции над ними
- •Формальное определение языка
- •3.1.3. Отношения и операции над ними
- •3.1.4. Требования, предъявляемые к грамматикам
- •Способы представления синтаксиса языка. Задание бесконечного текста конечными средствами. Проблема разбора. Классификация языков
- •3.2. Сканеры (лексические анализаторы)
- •3.2.1. Автоматные грамматики и диаграмма состояний
- •Регулярные выражения и конечные автоматы
- •Недетерминированные конечные автоматы
- •3.3. Грамматики простого предшествования
- •3.3.1. Простые предшествования.
- •Отношения предшествования и их вычисление
- •Операторное предшествование
- •Вычисление отношений операторного предшествования. Алгоритм разбора на основе операторного предшествования
- •3.3.5. Предшествование более высокого порядка
- •3.3.6. Способ представления грамматики в оп
- •3.3.7. Предшествование более высокого порядка
- •3.3.8. Ограниченный контекст
- •Определение 1:1 ограниченного контекстного распознавателя
- •Алгоритм 1:1 ограниченного контекстного преобразователя
- •Примеры разбора цепочек по алгоритму 1:1 ограниченного контекстного преобразователя
- •Определение m: n - ограниченного контекста
- •3.4. Автоматы с магазинной памятью, [ мп-автомат ]
- •Операции над магазином:
- •Операции над состоянием:
- •Операции над входной цепочкой:
- •Автомат задаётся:
- •Варианты мп-автоматов (доопределение)
- •Эквивалентность мп-автоматов и кс-грамматик
- •Мп, работающий снизу вверх
- •Формальное определение для левой свертки
- •Восходящий распознаватель
- •Детерминированный мп-автомат
- •Проблема зацикливания
- •3.4.1. Общие методы синтаксического анализа.
- •Вопросы для самопроверки
- •Нисходящий разбор
- •Нисходящий преобразователь (распознаватель)
- •Моделирование мп –преобразователя. Нисходящий анализ с возвратом Синтез процедуры
- •Нисходящий разбор в терминах грамматик
- •Алгоритм нисходящего разбора
- •Пример:
- •Алгоритм восходящего разбора
- •3.4.2. Польская запись, тетрады, триады, деревья.
- •Перевод индексной записи в тетрады
- •3.5. Теория перевода
- •3.5.1. Формализмы определения перевода
- •3.5.2. Синтаксически управляемый перевод
- •3.5.3. Конечные преобразователи. (Простейший транслятор)
- •3.5.4. Преобразователи с магазинной памятью
- •Лабораторная работа №7 Поиск основы в грамматиках простого предшествования
- •5. Контроль знаний
- •Глоссарий
Вопросы для самопроверки
С чем связана способность МП – автомата проводить нисходящий разбор?
С чем связана способность МП – автомата проводить восходящий разбор?
Как можно сформулировать проблему разбора входной цепочки моделированием МП – автомата?
Синтаксический анализ «сверху вниз»
Любой контекстно свободный язык может быть принят некоторым недетерминированным магазинным автоматом. Из недетерминированности указанного автомата следует, что построенный на его основе синтаксический анализатор контекстно свободного языка может осуществлять возврат к предыдущему состоянию в процессе функционирования. Сам алгоритм синтаксического разбора определяет вполне однозначный процесс, поэтому, при возникновении необходимости выбора одной из возможных логических ветвей, алгоритм выбирает и в дальнейшем следует всегда единственной из возможных логических ветвей. Это означает, что, обнаружив ошибку выбора, необходимо вернуться к моменту осуществления выбора, вновь осуществить выбор и выполнить другое перемещение. Однако если на порождающую язык грамматику были наложены определенные ограничения, а автомат эффективно использует свой стек, то становится корректным применение ряда хорошо изученных и отработанных приемов, позволяющих построить эффективный синтаксический анализатор для такого языка. На практике все реальные проекты языков программирования, безусловно, содержат все необходимые ограничения, поскольку они получат практическую ценность лишь в том случае, если будут поддержаны достаточно эффективными компиляторами.
При решении задачи синтаксического разбора строки вида х= =а1,а2…аnЄL(G)используют, как правило, один из двух основных методов. Первый из них заключается в построении дерева вывода, корень которого помечен символом S, а листьями являются узлы, помеченные символами а1,а2…аn.
Так называемый LL- разбор относится к методам синтаксического разбора типа «сверху-вниз». Для успешного LL- разбора предложений некоторого языка на порождающую его грамматику должны быть наложены строгие ограничения. И хотя практически это означает, что воспользоваться методом LL- разбора можно лишь на подмножестве класса детерминированных языков, он представляет значительный интерес, так как заложенные в нем принципы использованы в большинстве современных компиляторов.
Нисходящий разбор
Пусть p = 1,2,3,… k – левый разбор цепочки W Î L(G). Зная p, можно построить дерево разбора. Начинают с корня, помеченного начальным символом.
Пусть 1-е правило имеет вид S = x1,…,xk. Нужно присоединить k потомков к вершине S. Если xi – первый слева – нетерминал, то 2-е правило будет иметь вид xi = y1…ye. По этому принципу строим все дерево.
Простая СУ – схема: Т=íN, S, D, R, Sý отображает разбор в левом или правом выводе.
Правила из R, которые имеют вид А:=a, b, представим в виде
A:= a, ia’ , где i – номер правила.
a’:= b\T (в цепочке b удалим все терминальные символы) .
Нисходящий преобразователь (распознаватель)
Если контекстно свободная грамматика G является LL-грамматикой, то с помощью метода итерационного спуска можно построить синтаксический анализатор языка L(G), который явно не использует стек, однако алгоритм его функционирования включает ряд рекурсивных процедур, которые обычно реализуют с помощью стека.
В простейшей форме метод рекурсивного спуска предоставляет удобную возможность построения лексического анализатора (распознавателя символов) языка, порожденного LL(1)-грамматикой G=(N, S, P, S). Такой лексический анализатор каждому символу из множества N S ставит в соответствие единственную процедуру, с помощью которой для любой строки языка можно однозначно определить, выводима она из этого символа или нет.
Пусть имеем грамматику G(N, S, P, S), в которой правила занумерованы от 1 до р.
А также недетерминированный нисходящий распознаватель М1. Тогда его называют левым анализатором. То есть он моделирует левый вывод в грамматике G по правилу:
d (q, e, A) = (q, a, i) A:= a. (i – номер правила, записывается в выходную цепочку).
Анализатор каждый раз развертывает нетерминал, распознанный наверху магазина, в соответствии с некоторым правилом из Р, а также одновременно выдает номер этого правила.
Если наверху магазина находится терминальный символ, то М1 по правилу:
d (q, а, а) = (q1, е, е) проверяет, совпадает ли он с соответствующим символом во входной цепочке.
МL {(q0,q2), (*,+,(,),i), (N T $), (1,…,6), (d, q0, $, q1)};
(*,+,(,),i) – входной алфавит;
(N T $) – алфавит магазинных символов;
(1,…,6) – номера правил на выходе;
q0 – начальный символ автомата;
$ - начальный символ магазина;
Q*E*Г -> Q*Г**D*.
(q0, e, E) = (q0, E+T, 1);
(q0, e, E) = (q0, T, 2);
(q0, e, T) = (q0, T*F, 3);
(q0, e, T) = (q0, F, 4);
(q0, e, F) = (q0, (E), 5);
(q0, e, F) = (q0, i, 6);
(q0, a, a) = (q0, e, e);
(q0, e, $) = (q0, e, p) p - левый разбор цепочки.
(q0, i*(i+i), E, e) |¾ (q0, i*(i+i), T, 2) |¾
(q0, i*(i+i), T*F, 23) |¾ (q0, i*(i+i), F*F, 234) |¾
(q0, i*(i+i), i*F, 2346) |¾ (q0, *(i+i), *F, 2346) |¾
(q0, (i+i), F, 2346) |¾ (q0, (i+i), (E), 23465) |¾
(q0, i+i), E), 23465) |¾ (q0, i+i), E+T), 234651) |¾
(q0, i+i), T+T), 2346512) |¾ (q0, i+i), F+T), 23465124)|¾
(q0, i+i), i+T), 234651246) |¾ (q0, i), T), 234651246) |¾
(q0, i), F), 2346512464) |¾ (q0, i), i), 23465124646) |¾
(q0, e, e, 23465124646) |¾ (q1, e, e, 23465124646)
Левый анализатор – недетерминированная процедура. Чтобы ею пользоваться, необходимо уметь моделировать ее детерминированно. Существует класс грамматик (L,L), для которых левый разбор можно делать детерминированным. Для этого анализатору необходимо предоставить возможность, которая при считывании входной (исследуемой) цепочки позволяла бы заглядывать на k символов вперед, и очередной шаг делался бы после анализа полученной информации.
L, L – означает, что читается слева направо, и выдается левый разбор.
L, R - означает, что читается слева направо, и выдается правый разбор.
Левые и правые разборы используются в зависимости от той или иной грамматики.