Разработка словесного описания лексики, синтаксиса и семантики языка, предназначенного для программирования потоковых вычислений, страница 8

Таблица целых констант

 Текст слова 

 Номер слова в группе 

5

0

4

2

2

1

0

3

Таблица констант
с плавающей точкой

 Текст слова 

 Номер слова в группе 

34.24

1

10.3

0

Таблица служебных слов языка

 Текст слова 

 Номер слова в группе 

,

13

=>

12

join

6

)

9

?

10

(

8

let

7

do

5

or

11

;

4

:

1

}

2

{

0

vars

3

8. Преобразование последовательности лексем в постфиксную запись.

8.1. Описание алгоритма.

Преобразование последовательности лексем в постфиксную запись осуществляется для блоков vars и do. В процессе работы постфиксная запись для текущего блока формируется в векторе VectPFRBlock. После окончания блока она добавляется в вектор VectPFRTotal, а вектор VectPFRBlock очищается. Таким образом, после завершения работы анализатора, в векторе VectPFRTotal содержится постфиксная запись всей программы. Имена блоков сохраняются в векторе VectNames, для улучшения визуализации результата. Ниже приведён программный код определения необходимых объектов:

final Vector VectPFRBlock = new Vector(); //вектор для хранения постфиксной записи

                                                      //программного кода текущего блока

final Vector VectPFRTotal = new Vector(); //вектор для хранения постфиксной записи всей

      //программы

final Vector VectNames = new Vector(); //вектор для хранения имён блоков

final Stack StOp = new Stack(); //стек для хранения знаков операций

final Stack StIf = new Stack(); //стек для хранения номера текущего условного оператора

Формирование постфиксной записи происходит посредством внесения действия в синтаксис языка. При этом используются стандартные методы классов Stack — push(), pop(), peek(), и Vector () — add(), remove(), removeAllElements().

Учёт приоритетности операций обеспечивается соответствующим порядком следования правил в грамматике — более приоритетные операции расположены ниже.

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

int CntIf = 1; //счетчик количества условных операторов (индексация с единицы)

При вхождении в условный оператор происходит инкрементирование счётчика и занесение его значения в стек StIf. При формировании меток текущего условного оператора используется значение, находящееся на верхушке стека. После завершения обработки текущего условия происходит удаление значения из стека.

Занесение значения в стек и добавление к ПФЗ бинарного оператора условного перехода по лжи:

StIf .push (new Integer(++CntIf)); VectPFRBlock.add("Label1_"+StIf.peek()); VectPFRBlock.add("JmpF");

Добавление в постфиксную запись унарного оператора условного перехода по истине:

VectPFRBlock.add("Label2_"+StIf.peek()); VectPFRBlock.add("Jmp");

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

VectPFRBlock.add("Label1_"+StIf.peek()+":");