Разработка компиляторов

       

Пример входного файла lburg


%start stmt -- стартовый нетерминал

%term CNSTF4=4113 -- терминалы %term CNSTF8=8209 %term CNSTF16=16401 %term CNSTI1=1045 ... mem: INDIRU4(addr) "dword ptr %0" ... mrc3: mem "%0" 3 mrc3: rc "%0" ... reg: addr "lea %c,%0\n" 1 ....

Рассмотрим формат описания основных элементов в грамматике для lburg.

Традиционно нетерминалы обозначаются идентификаторами, состоящими из строчных букв, терминалы - идентификаторами, состоящими из прописных букв. Конструкция %start <nonterminal> служит для описания стартового нетерминала. Конструкция %term <terminal>=<constant> определяет терминал, при этом числовое значение справа от знака равенства соответствует внутреннему коду узла дерева в представлении программы, выдаваемом frontend'ом.

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

В данном случае приведено четыре правила из описания кодогенератора для процессора x86: первое порождает команду косвенной адресации для четырехбайтового адреса, второе и третье выводит нетерминал, соответствующий режиму адресации mcr (memory+constant+register) из нетерминалов, соответствующих регистру и адресу в памяти, четвертое описывает команду загрузки содержимого памяти в регистр.

Форматная строка напоминает таковую в стандартных функциях обмена, однако ассортимент форматных символов несколько иной: так, "%0" обозначает результат свертки 1-го сына текущего узла, "%c " - результат свертки текущего узла и т.д.



Содержание раздела