
- •Структура компилятора. Типы транслирующих программ.
- •Определение языка. Синтаксис и семантика.
- •Порождающие грамматики Хомского. Примеры порождающих грамматик.
- •Контекстно-свободные грамматики.
- •Деревья вывода. Канонические выводы. Двусмысленные порождающие грамматики
- •Любой язык может быть порожден бесконечным числом грамматик.
- •Лексический анализ.
- •Пример структуры программы сканирования
- •Ll(n) и lr(n) – грамматики.
- •Ll(k)-грамматики
- •Lr(k) грамматики
- •Построение синтаксического графа.
- •Восходящий синтаксический анализ.
- •Пример:
- •Работа с таблицей символов.
- •Реализация в виде массива
- •Реализация в виде цепочной структуры (связанного списка)
- •2. Дополнительные затраты памяти, поскольку хранятся ссылки на последующий и, возможно, предыдущий элемент На практике также встречается комбинация этих подходов.
- •Восстановление при синтаксических ошибках.
- •Постфиксная запись.
- •Методы генерирования кода.
Ll(n) и lr(n) – грамматики.
Ll(k)-грамматики
LL(k) грамматики – это наиболее общий класс грамматик, позволяющих выполнить нисходящий синтаксический анализ, просматривая входную цепочку слева (первый символ L в названии) при восстановлении левого канонического вывода (второй символ L в названии) данной терминальной цепочки, заглядывая вперед по входной цепочке на каждом шаге не более чем на k символов при принятии решения о том, какой из альтернативных правых частей заменить текущий – самый левый – нетерминалочередной сентенциальной формы. Очевидно, что класс LL(1)-грамматик включает как автоматные (с детерминированным распознаванием) так и s-грамматики, а также грамматики
рекурсивного спуска. Для всех этих грамматик альтернативный выбор правил для каждого нетерминала делался на основании ключа – первого терминала, стоящего в начале альтернативы.
Две буквы L в LL(k) означают, что строки разбираются слева направо (Left) и используются самые левые выводы (Left), а цифра k – что варианты порождающих правил выбираются с помощью k предварительно просмотренных символов.
Если речь идет, например, о LL(2)-грамматике, это значит, что строки разбираются слева направо и используются самые левые выводы, а варианты порождающих правил выбираются с помощью двух предварительно просмотренных символов.
Lr(k) грамматики
Это наиболее широкий класс грамматик, допускающих эффективный восходящий детерминированный синтаксический анализ. Буква 'L' в названии LR(k) говорит, что анализируемая цепочка (сентенциальная форма) просматривается слева. Буква 'R' говорит о том, что восстанавливается правый канонический вывод цепочки языка. (Если сентенциальная форма просматривается слева в поиске самой левой связки, то и восстанавливаться в ней сначала будут самые левые нетерминалы, а это как раз характеризует правый канонический вывод, когда в сентенциальных формах подстановка продукций осуществляется для самого правого нетерминала). Символ k указывает количество символов, которые алгоритм свертки просматривает вперед (lookahead) для обнаружения очередной связки. LR(k)-грамматики были введены Д.Кнутом и являются сейчас основным классом грамматик, для которого строятся практические производственные компиляторы.
LR(k)-распознаватель, считывая сентенциальную форму символ за символом, имеет цель определить самую левую связку (как и в алгоритме предшествования), а также нетерминал левой части, которым следует заменить связку. В отличие от алгоритма предшествования, LR(k)-распознаватель при поиске связки учитывает информацию не только о парах соседних символов, но информацию о всей просмотренной слева части входной цепочки.
LR(k)–распознаватель принимает на вход цепочки - сентенциальные формы - и выдает ответ: какая продукция определяет очередную связку. Поэтому LR(k)–распознаватель можно рассматривать как автомат, переходящий из состояния в состояние при очередном входном символе. Легко видеть, что классов эквивалентных предысторий, характеризующих поведение такого автомата, конечное число. Действительно, с точки зрения возможных сверток каждую позицию внутри сентенциальной формы в процессе ее просмотра можно описать так называемым "характеристическим множеством" – множеством продукций, релевантных этой позиции, c меткой-указателем в каждой продукции, показывающей, в каком месте продукции находится анализатор на данном шаге просмотра сентенциальной формы. Такую помеченную продукцию будем записывать А→ α•β;γ где точка указывает позицию внутри продукции А→ αβ, а γ - правый контекст длиной k. Очевидно, что поскольку продукций у грамматики конечное количество, их наборов с указанием метки позиции внутри них – тоже конечное количество, и подмножеств таких помеченных продукций (характеристических множеств) со своими контекстами также конечное количество. Поэтому LR(k)– распознаватель является конечным автоматом, состояниями которого являются характеристические множества. k в LR(k) означает количество символов входного потока, следующих за текущим, которые синтаксический анализатор может при необходимости просмотреть, не перенося в стек.