- •Университет наяновой
- •М. А. Шамашов основные структуры данных и алгоритмы компиляции
- •Предисловие
- •Введение
- •1. Краткий обзор процесса компиляции
- •2. Лексический анализ
- •0123...9 Пробел
- •3. Организация таблиц компилятора
- •3.1. Общий вид таблиц
- •3.2. Прямой доступ к таблице или метод индексов
- •3.3. Неупорядоченная таблица или метод линейного списка
- •3.4. Упорядоченная таблица. Бинарный, двоичный или логарифмический поиск
- •3.5. Сбалансированные деревья
- •3.6. Деревья оптимального поиска
- •3.7.1. Рехеширование
- •3.7.3. Метод цепочек или гроздей
- •4. Общие методы синтаксического анализа
- •4.1. Нисходящий разбор с возвратами
- •4.2. Восходящий разбор с возвратами
- •4.3. Символьный препроцессор на основе бэктрекинга
- •4.3.1. Фаза анализа и перевода грамматики во внутреннее представление
- •4.3.2. Лексичекий анализ в сп
- •4.3.3. Синтаксический анализ в сп
- •4.3.4. Выполнение семантических действий
- •5. Однопроходный синтаксический анализ без возвратов
- •5.1. Ll(k) языки и грамматики
- •5.1.1. Предсказывающие алгоритмы разбора и разбор для ll(1)-грамматик
- •5.1.2. Рекурсивный спуск
- •5.2. Языки и грамматики простого предшествования
- •Xy, если u xy
- •X y, если u xU1) (y l(u1))
- •X y, если (u u1y) (X r(u1)) or
- •5.2.1. Алгоритм Вирта–Вебера для анализа языков простого предшествования
- •5.2.2. Функции предшествования.
- •5.2.3. Проблемы построения грамматик предшествования
- •5.3. Операторная грамматика предшествования
- •6. Введение в семантику
- •6.1. Внутренние формы исходной программы
- •6.1.1. Польская инверсная запись
- •If выр then инстр 1 else инстр 2
- •6.1.2. Интерпретация полиЗа
- •6.1.3. Генерирование команд по полиЗу
- •6.1.4. Тетрады и триады
- •6.2. Семантические подпрограммы перевода инфиксной записи в полиз и аспекты их реализации
- •6.3. Семантические подпрограммы для перевода в тетрады
- •6.4. Метод замельсона–бауэра для перевода в полиз и тетрады
- •6.5. Нейтрализация ошибок
- •6.5.1. Исправления орфографических ошибок
- •6.5.2. Нейтрализация семантических ошибок
- •6.5.3. Нейтрализация синтаксических ошибок
- •7. Машинно-независимая оптимизация программ
- •7.1. Исключение общих подвыражений
- •7.2. Вычисления во время компиляции
- •7.3. Оптимизация булевых выражений
- •7.4. Вынесение инвариантных вычислений за цикл
- •8. Машинно-зависимые фазы компиляции
- •8.1. Распределение памяти
- •8.2. Генерация кода и сборка
- •8.3. Трансляция с языка ассемблера
- •Заключение
- •Список литературы
- •Содержание
- •1. Краткий обзор процесса компиляции 5
- •2. Лексический анализ 10
- •3. Организация таблиц компилятора 16
- •4. Общие методы синтаксического анализа 28
- •5. Однопроходный синтаксический анализ без возвратов 52
- •6. Введение в семантику 78
- •7. Машинно-независимая оптимизация программ 102
- •8. Машинно-зависимые фазы компиляции 109
5.3. Операторная грамматика предшествования
Алгоритм разбора Вирта–Вебера и отношения простого предшествования, лежащие в его основе, просты для понимания, безупречны и эффективны с теоретической точки и поэтому именно с них мы начали обсуждение детерминированных алгоритмов восходящего разбора. Но в практике построения компиляторов они не нашли широкого применения из–за причин, рассмотренных в разделе 5.2.3.
Во многих компиляторах, особенно при анализе и трансляции арифметических выражений, используется простой в реализации и эффективный метод операторного предшествования, идея которого была формализована Флойдом еще в 1963 году. Собственно Р. Флойду и принадлежит первая трактовка отношений предшествования и функций предшествования, хотя методы, основанные на этих идеях, интуитивно использовались уже в самых ранних компиляторах.
Операторной грамматикой называется КС–грамматика без аннулирующих правил, в которой правые части правил не содержат смежных нетерминалов. Иными словами в операторных грамматиках запрещены правила вида V UW, где U, W .
Для операторных грамматик можно задать отношения предшествования только для терминальных символов, игнорируя нетерминалы, хотя в остальном сами отношения операторного предшествования и пути их определения ничем не отличаются от отношений простого предшествования (см. раздел 5.2).
Введем вначале понятие множества самых левых (L) и самых правых (R) терминалов для нетерминала U:
L(U) = {x | x ( (U x) or (U U1x) or ( (U U2) (x L(U2)))},
где здесь и далее U, U1, U2 (нетерминалы) , а , ( ) (любые цепочки из терминалов и нетерминалов, возможно пустые).
R(U) = {x | x ( (U x) or (U xU1) or ( (U U2) (x R(U2)))}
Определим теперь отношения предшествования для терминалов грамматики x и y:
xy, если U xU1) (y L(U1) ;
xy, если (U U1y) (x R(U1) ;
xy, если U xy or U xU1y.
Пример 5.16. Рассмотрим упрощенную грамматику все тех же арифметических выражений:
E ETT
T TMM
M (E)i
Множества самых левых и самых правых терминальных символов для нетерминалов этой грамматики представлены на рис. 5.19 а, а матрица операторного предшествования на рис. 5.19 б.
Для нахождения основ, состоящих из одного нетерминала, отношения операторного предшествования неприменимы, – для нетерминалов их просто не существует. Если рассмотреть, например, сентенциальную форму MM из арифметической грамматики примера 5.16, то основой здесь является М, а отношения есть только такие: # и # (как и в разделе 3.4 мы предполагаем, что сентенциальная форма заключена между ограничителями # и что #x и x# для всех терминалов x). На каждом шаге разбора при использовании операторного предшествования распознается и редуцируется не основа, а так называемая самая левая первичная фраза.
Под первичной фразой сентенциальной формы здесь понимается подцепочка, в которую входит, по крайней мере, один терминал, а сама она не содержит других первичных фраз.
Общий вид сентенциальной формы, выводимой в операторной грамматике и заключенный между ограничителями, выглядит следующим образом:
# N1T1N2T2 . . . NnTnNn+1 #
где Ni – нетерминалы, которые могут и отсутствовать, а Ti – терминальные символы. Иначе говоря, сентенциальная форма состоит их n терминалов, причем между каждыми двумя соседними терминалами находится не более чем один нетерминал.
Самой левой первичной фразой сентенциальной формы в операторных грамматиках предшествования является такая самая левая подцепочка NjTj ... NiTiNi+1 , что
Tj–1Tj , TjTj+1 , Ti–1Ti , TiTi+1 .
Это определение очень похоже на соответствующее определение для простого предшествования. Основное различие состоит в том, что здесь из отношений исключены нетерминальные символы. Тем не менее, нетерминалы, находящиеся слева от Tj и справа от Ti , а также все нетерминалы лежащие между ними всегда принадлежат первичной фразе.
Пример 5.17. Для иллюстрации этого определения проведем разбор цепочки i(ii), используя матрицу предшествования с рис. 5.19 б. На рис. 5.20 а представлено дерево разбора для этой цепочки, а в таблице на рис. 5.20 б показаны символы, к которым приводятся первичные фразы.
Как видно из рис. 5.20 б, основываясь на интуиции, первое i мы свернули к T, а второе i – к E, хотя единственное, что очевидно из отношений и грамматики – это свертка от i к M. Заметим, что при поиске самой левой первичной фразы, которую нужно редуцировать, нетерминальные символы вообще не принимаются во внимание.
# i
( i
i ) #
# E
( i
i ) #
# E
( E
i ) #
# E
( E
E ) #
# E
( E ) #
# E
E #
# E #
Рис. 5.21
E EEEE(E)i
Рисунок 5.21 иллюстрирует свертку цепочки #i(ii)#, базирующуюся на полученной грамматике и отношениях операторного предшествования с рис. 5.19 б.
Конечно, семантические программы здесь могут стать более сложными, так как они должны будут проводить более подробную проверку операндов, чем в грамматиках простого предшествования. Но выигрыш здесь более существенен, так как распознаватель в целом становится значительно эффективнее. Отметим, что уменьшается объем памяти под матрицу предшествования, так как она содержит теперь отношения только для терминалов грамматики. Более того, распознаватель в явном виде не выполняет таких редукций, как E T или T M, поскольку T и M не первичные фразы и такого рода редукции не несут никакой семантической нагрузки.
Упражнения.
5.1. Построить отношения простого предшествования для грамматики с правилами S aSbcd.
5.2. Построить отношения простого предшествования и функцию предшествования, используя граф линеаризации, для грамматики с правилами S aSSbcd. Покажите этапы свертки фраз aacdbcb , ab , acb.
|
1 |
2 |
3 |
4 |
1 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
5.4. Определить, является ли грамматика логических выражений, правила которой приведены ниже, грамматикой простого предшествования. Если она таковой не является, то преобразовать ее, построить для нее отношения простого предшествования и функцию предшествования, используя граф линеаризации.
E E or TT
T T and MM
M a(E) not M
5.5. Постройте отношения простого предшествования для грамматики с правилами S 0S11011 и терминалами { 0, 1 }. Если данная грамматика не является грамматикой простого предшествования, то преобразуйте ее к такой грамматике.
5.6. Постройте отношения операторного предшествования и функцию предшествования, используя граф линеаризации, для грамматики из упражнения 5.4.
5.7. Преобразуйте грамматику
S E
E TTBE(E)
T abz
B
к грамматике простого предшествования. Покажите этапы свертки фразы a(b+c).
Упражнения на программирование.
5.8. Разработать программу, которая по заданной грамматике строит отношения простого предшествования, функцию предшествования и реализует алгоритм восходящего разбора по полученным отношениям и функции. Визуализировать поэтапное построение отношений предшествования, функции предшествования и работу алгоритма разбора.
5.9. Реализовать программу, которая по заданной грамматике строит отношения простого предшествования. Если грамматика не является грамматикой простого предшествования, то программа должна пытаться привести ее к такому виду. Визуализировать поэтапное построение отношений предшествования и работу алгоритма стратификации.
5.10. Реализовать программу, которая определяет, является ли заданная грамматика операторной, строит отношения операторного предшествования, функцию предшествования и реализует алгоритм синтаксического анализа с использованием этих отношений и функции. Визуализировать процесс построения отношений, функции и работу алгоритма разбора.