Назначение адресов
Назначение адресов переменным, параметрам и полям записей происходит при обработке соответствующих объявлений. В однопроходном трансляторе это может производиться вместе с построением основной таблицы символов и соответствующие адреса (или смещения) могут храниться в этой же таблице. В промежуточном представлении Лидер объявления сохранены, что делает это промежуточное представление машинно-независимым.
Напомним, что в Лидер-представлении каждому описанию соответствует некоторый номер. В процессе работы генератора кодов поддерживается таблица Table, в которой по этому номеру (входу) содержится следующая информация:
- для типа: его размер;
- для переменной: смещение в области процедуры (или глобальной области);
- для поля записи: смещение внутри записи;
- для процедуры: размер локальных параметров;
- для массива: размер массива, размер
элемента, значение левой и правой границы.
Функция IncTab вырабатывает указатель (вход) на новый элемент таблицы, проверяя при этом наличие свободной памяти.
Для вычисления адресов определим для каждого объявления два синтезируемых атрибута: DISP будет обозначать смещение внутри области процедуры (или единицы компиляции), а SIZE - размер. Тогда семантика правила для списка объявлений принимает вид
RULE DeclPart ::= ( Decl ) SEMANTICS Disp=0; 1A: Disp=Disp+Size; Size=Disp. |
Все объявления, кроме объявлений переменных, имеют нулевой размер. Размер объявления переменной определяется следующим правилом:
RULE Decl ::= 'VAR' TypeDes SEMANTICS Tablentry Entry; 0: Entry=IncTab; Size=((Table[VAL]+1) / 2)*2; // Выравнивание на границу слова Table[Entry]=Disp+Size. |
В качестве примера трансляции определения типа рассмотрим обработку описания записи:
RULE TypeDes ::= 'REC' ( TypeDes ) 'END' SEMANTICS int Disp; Tablentry Temp; 0: Entry=IncTab; Disp=0; 2A: {Temp=IncTab; Table[Temp]=Disp; Disp=Disp+Table[Entry]+1) / 2)*2; // Выравнивание на границу слова } Table[Entry]=Disp. |