Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 15:

Выбор инструкций при генерации кода

Представление выводов


Следующей нашей задачей будет построение множества выводов для данного дерева t в данной грамматике G .

Для представления множества выводов построим разметку C , которая вершине дерева v и нетерминалу K сопоставляет множество правил, каждое из которых начинает вывод образца t(v) из образца K в грамматике G (правило R начинает вывод образца t(v) из образца K тогда и только тогда, когда в множестве всех выводов t(v) из K DG (K,t(v)) существует вывод, который начинается тройкой (K, K, R) , т.е. применением правила R к единственной вершине, помеченной нетерминалом K .)

Построение выводов


Приведем алгоритм построения разметки C для грамматики в нормальной форме.

Данный алгоритм обходит дерево снизу-вверх. При этом он пытается применить все возможные правила к текущей вершине root. Если какое-либо правило R=N:p применимо, то в разметку для пары С[root][N] добавляется правило R .

Для того, чтобы проверить применимость правила для текущей вершины, проверяется соответствие этой вершины образцу в правой части правила (этим занимается функция Match ).

Кроме того, после вывода нового нетерминала в разметке C строится ее замыкание относительно цепных правил (это делает функция BuildClosure ).

Заметим, что формально говоря всегда можно рассматривать грамматики без цепных правил, поскольку любую грамматику можно преобразовать в эквивалентную, не содержащую цепных правил. Однако такое преобразование увеличивает число правил, в которых требуется нетривиальное сопоставление с образцом.

Построение выводов (продолжение)


Рассмотрим задачу сопоставления с образцом для вершины дерева (функция Match). Нас в данном случае интересуют образцы двух видов: лист, помеченный неким терминальным символом и дерево высоты один, корень которого помечен неким терминальным символом, а листья - нетерминалами. Кроме того, возможны образцы цепных правил, но они будут учтены при построении замыкания. Этим набором исчерпываются все образцы грамматики в нормальной форме.

Что касается образца первого вида, то данная вершина соответствует ему в том и только том случае, когда она является листом, помеченным тем же самым терминальным символом.

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

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