Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Синтаксический анализ сверху вниз.doc
Скачиваний:
5
Добавлен:
01.03.2025
Размер:
2 Мб
Скачать
☆

Синтаксически управляемый перевод на примере перевода арифметического выражения в полиз.

Продолжая рассмотренный алгоритм, приведём реальный пример перевода выражения с языка Паскаль в обратную польскую запись.

Для этого сделаем несколько дополнений, в частности мы можем ввести операции с наивысшим приоритетом:

Оператор

Приоритет

:=

101

^,.

0

Так как выражение присваивания обычно имеет вид <переменная>:= <выражение>, то приоритет операции присваивания должен быть менее приоритета скобок, а приоритет операций ссылки по указателю, и ссылки на структуру наивысший. Отдельно отметим, что операция адресации "@" прямо не является операцией, а лишь префиксом, который отменяет последнюю адресацию, хотя при соответствующем генераторе кода с возможностью отмены последней ссылки адресация может быть обработана как обычная операция в стеке.

Последний штрих - после конца строки мы выталкиваем оператор присваивания неким фиктивным оператором, приоритет которого менее приоритета оператора присваивания.

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

Представление условных операторов, операторов цикла и оператора безусловного перехода в полиз.

Условные операторы, операторы цикла и операторы безусловного перехода довольно легко представляются в обратной польской записи. В любом случае внутри этих операторов лежат безусловный и условный переходы. Безусловный переход достаточно просто определяется - как в соответствующем языке ассемблера

JMP     метка

оператор условного перехода требует большей работы. Вспомним, что любое логическое выражение оставляет на арифметическом стеке булево значение, обычно не нуль или нуль. Таким образом фрагмент программы может выглядеть так:

pop     ax test    ax,ax jnz     метка_перехода

Генерация кода на языке ассемблер, для вычисления арифметического выражения.

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

Рассмотрим таблицу случаев генерации кода для процессора 8086/8087, для случая - один для 8086, другой для сопроцессора 8087. Условимся, что вершина арифметического стека кешируется в 8086 процессоре в регистре bx.

Действие

Код для 8086

Код для 8087

:=

pop ax ; адрес xchg ax,bx mov [bx],ax ; двигаем

fstp dword ptr [bx]; в bx адрес pop bx

Внесение левой части в стек (или любого адреса)

push bx mov bx, offset var

Внесение переменной в стек

push bx mov bx, var

fld var

Унарный минус

neg bx

fchs

Бинарная операция: вычитание

pop ax xchg ax,bx sub bx,ax

fsub

Бинарная операция: сложение

pop ax add bx,ax

fadd

Ссылка по адресу

mov bx,[bx]

Ссылка на структуру

mov bx,[bx+offset field]

Тернарная условная операция

test bx,bx pop bx pop ax jz exit1 xchg ax,bx exit1: ...

fistp temp wait mov ax,temp and ax,ax jz exit2 fxch exit2: fincstp ffree st

Загрузка значения по адресу

mov bx, [bx]

fld dword ptr [bx]

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