
- •5.2. Ll(1)-метод синтаксического анализа.
- •Отношения между классами кс-грамматик
- •1.Семантический анализ
- •1.1. Польская инверсная запись
- •1.2.Интерпретация полиЗа
- •1.3.Генерирование команд по полиЗу
- •1.4.Алгоритм Замельсона и Бауэра перевода выражений в полиз
- •7.5. Атрибутные грамматики
- •Генерация кода Свойства языка внутреннего представления программы.
- •Синтаксически управляемый перевод на примере перевода арифметического выражения в полиз.
- •Представление условных операторов, операторов цикла и оператора безусловного перехода в полиз.
- •Генерация кода на языке ассемблер, для вычисления арифметического выражения.
- •Генерация кода для операторов read и write языка паскаль.
- •Генерация кода для условного оператора if, вложенного оператора if языка паскаль.
- •Генерация кода для оператора цикла for, вложенного оператора for языка паскаль.
- •Генерация кода для операторов цикла while, repeat языка паскаль.
1.Семантический анализ
Обычно в компиляторах и интерпретаторах каждому правилу грамматики, каждой альтернативе любого нетерминала ставятся в соответствие семантические подпрограммы. Эти подпрограммы выполняются при синтаксических редукциях по заданным правилам грамматики в восходящем разборе или отождествлении фрагмента входной цепочки с некоторой альтернативой продукции при разборе нисходящем.
Все внутренние представления программы обычно содержат элементы двух типов: операторы и операнды. Различия представлений состоят лишь в том, как эти элементы объединяются между собой. В дальнейшем мы будем использовать такие традиционные операторы, как +, , , MOD, DIV, , AND, OR, >, <, = и т. п., а также БП (Безусловный Переход) и УПЛ (Условный Переход по Лжи), точнее, условный переход в том случае, когда значение операнда (логического выражения) – ложь (FALSE, 0). Внутри компилятора, конечно же, все они представляются соответствующими лексемами или целочисленными кодами.
Операнды, с которыми мы будем иметь дело, – это простые идентификаторы (имена переменных, процедур и т.п.), константы, временные переменные, генерируемые самим компилятором, и переменные с индексами.
1.1. Польская инверсная запись
Вместо традиционного инфиксного (скобочного) представления арифметических и логических выражений в различных вычислителях часто используется польская инверсная запись (ПОЛИЗ), которая просто и точно указывает порядок выполнения операций без использования скобок. В этой записи операторы располагаются непосредственно за операндами, над которыми они выполняются в порядке их выполнения. Поэтому иногда ПОЛИЗ называют суффиксной, или постфиксной записью. Например, AB записывается как AB, ABC – как ABC, A(BCD) – как ABCD, а ABCD – как ABCD.
Остановимся на простейших правилах, которые позволяют переводить в ПОЛИЗ вручную:
1. Идентификаторы и константы в ПОЛИЗе следуют в том же порядке, что и в инфиксной записи.
2. Операторы в ПОЛИЗе следуют в том порядке, в каком они должны вычисляться (слева направо).
3. Операторы располагаются непосредственно за своими операндами.
Таким образом, мы могли бы записать следующие синтаксические правила:
операндидентификаторконстантаоперандоперандоператор
оператор
Унарный минус и другие унарные операторы можно представить двумя способами: либо записывать их бинарными операторами, то есть вместо B писать 0B, либо для унарного минуса можно ввести новый специальный символ, например @, и использовать еще одно синтаксическое правило операндоперанд@. Таким образом, выражение A(BCD) мы могли бы записать AB@CD.
С равным успехом мы могли бы ввести префиксную запись, где операторы стоят перед операндами. Таким образом, любую управляющую конструкцию, можно представить в трех формах записи: префиксной, инфиксной (обычная запись, где операторы располагаются между операндами, а круглые скобки позволяют изменять приоритет операций) и постфиксной. Человек традиционно использует инфиксную запись, тогда как для автоматического вычисления выражений самым удобным способом представления является постфиксная запись или ПОЛИЗ.
ПОЛИЗ расширяется достаточно просто. Нужно только придерживаться правила, что за операндами следует соответствующий им оператор. Так, присваивание переменнаявыражение в ПОЛИЗе примет вид переменнаявыражение. Например, присваивание АBCD100 запишется в ПОЛИЗе как АBCD100.
Индексированную переменную в ПОЛИЗе, а точнее вычисление ее адреса можно представить в виде:
идентификаториндексные выраженияконстанта[ ,
где [ – обозначает знак операции вычисления индекса, идентификатор – имя (базовый адрес) индексированной переменной, а константа – количество индексов (мерность массива). Так, переменную A[i,j+k] можно представить в виде Аijk+2[ .
Условный оператор
IF выр THEN инстр 1 ELSE инстр 2
в ПОЛИЗе будет иметь вид:
выр m УПЛ инстр 1 n БП инстр 2 ,
где
выр – логическое выражение (условие), которое может принимать значения – 0 (FALSE, ложь) или 1 (TRUE, истина);
m – номер (место, позиция, индекс) символа ПОЛИЗа, с которого начинается инстр 2;
УПЛ (Условный Переход по Лжи) – оператор с двумя операндами выр и m , смысл которого состоит в том, что он изменяет традиционный порядок вычислений и осуществляет переход на символ строки ПОЛИЗа с номером
m , если (и только если) выр – ложно (равно 0);
n – номер символа, следующего за инстр 2;
БП (Безусловный Переход) – оператор с одним операндом n , который также изменяет порядок вычислений по ПОЛИЗу и осуществляет переход на символ с номером n .