Дерево вывода. Методы построения дерева вывода

 

Деревом вывода грамматики G(VT,VN,P,S) называется дерево (граф), которое соответствует некоторой цепочке вывода и удовлетворяет следующим условиям:

 каждая вершина дерева обозначается символом грамматики A(VTVN);

 корнем дерева является вершина, обозначенная целевым символом граммати­ки – S;

 листьями дерева (концевыми вершинами) являются вершины, обозначенные терминальными символами грамматики или символом пустой цепочки ;

 если некоторый узел дерева обозначен символом AVN, а связанные с ним узлы – символами b1,b2,...,bn; n>0, n  i > 0: bi(VTVN{}), то в грамма­тике G(VT,VN,P,S) существует правило Ab1,b2,...,bn Р.

Из определения видно, что по структуре правил дерево вывода в указанном виде всегда можно построить только для грамматик типов 2 и 3 (контекстно-свобод­ных и регулярных). Для грамматик других типов дерево вывода в таком виде можно построить не всегда (либо же оно будет иметь несколько иной вид).

На основе рассмотренного выше примера построим дерево вывода для цепочки вывода 1. Это дерево приведено на рис. 1.2.

 

Рис. 1.2. Пример дерева вывода для грамматики целых десятичных чисел со знаком

 

Для того чтобы построить дерево вывода, достаточно иметь только цепочку вывода. Дерево вывода можно построить двумя способами: сверху вниз и снизу вверх. Для строго формализованного построения дерева вывода всегда удобнее пользоваться строго определенным выводом: либо левосторонним, либо право­сторонним.

При построении дерева вывода сверху вниз построение начинается с целевого символа грамматики, который помещается в корень дерева. Затем в грамматике выбирается необходимое правило, и на первом шаге вывода корневой символ раскрывается на несколько символов первого уровня. На втором шаге среди всех концевых вершин дерева выбирается крайняя (крайняя левая – для левосторон­него вывода, крайняя правая – для правостороннего) вершина, обозначенная нетерминальным символом, для этой вершины выбирается нужное правило грамматики, и она раскрывается на несколько вершин следующего уровня. По­строение дерева заканчивается, когда все концевые вершины обозначены терми­нальными символами, в противном случае надо вернуться ко второму шагу и продолжить построение.

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

Поскольку все известные языки программирования имеют нотацию записи “сле­ва – направо”, компилятор также всегда читает входную программу слева на­право (и сверху вниз, если программа разбита на несколько строк). Поэтому для построения дерева вывода методом “сверху вниз”, как правило, используется ле­восторонний вывод, а для построения “снизу вверх” – правосторонний вывод. На эту особенность компиляторов стоит обратить внимание. Нотация чтения программ “слева направо” влияет не только на порядок разбора программы компилятором (для пользователя это, как правило, не имеет значения), но и на порядок выполнения операций – при отсутствии скобок большинство равно­правных операций выполняются в порядке слева направо, а это уже имеет суще­ственное значение.