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


Преобразование ПФЗ в последовательность пентад

Пентады формируются после создания ПФЗ каждого блока. Временные переменные для хранения результатов арифметических и логических вычислений заносятся в таблицу идентификаторов соответствующих блоков. Пентада состоит из 5 полей: поле метки для перехода в логических операциях, поле операции, поле второго операнда, поле первого операнда, поле результата.

Для формирования пентад используются следующие структуры:

//временный вектор для последовательности пентад одного блока

final Vector VectorTetrad = new Vector();

//таблица последовательностей пентад всей программы разбитая по имени блоков

final Hashtable TableBlockTetrad = new Hashtable();

//временный вектор для пентады

final Vector StrTetrad = new Vector();

//стек используемый при формировании тетрад

final Stack StackTetrad = new Stack();

//бинарные операции

final Vector BiOp = new Vector();

//метки

final Vector Metka= new Vector();

Преобразование осуществляется по следующему принципу:

1.  производится проход по вектору с ПФЗ блока от начала вектора. Если вектор пуст, то перейти к шагу 17;

2.  текущий элемент заносится в стэк;

3.  если этот элемент был меткой, то перейти к шагу 9;

4.  если этот элемент был “let”, то перейти к шагу 11;

5.  если этот элемент был знаком арифметической или сравнительной операции, то перейти к шагу 12;

6.  если этот элемент был “GO”, то перейти к шагу 13;

7.  если этот элемент был “GF”, то 14;

8.  значит этот элемент операнд и поэтому переходим к шагу 2;

9.  если следующий элемент ПФЗ тоже метка или текущий элемент последний в ПФЗ, то занести метку в пентаду, а остальные поля текущей пентады заполнить нулями и перейти к шагу 15;

10.  значит следующий элемент является операндом и поэтому заносим метку в пентаду и переходим к шагу 2(остальные поля пентады пока пусты);

11.  заносим let в пентаду в качестве знака операции, извлекаем из стэка один элемент и заносим его как операнд2, извлекаем из стэка ещё один элемент и заносим его как результат. Переход к шагу 15;

12.  заносим знак операции в пентаду, извлекаем из стэка и заносим в пентаду два операнда, создаём переменную для результата, заносим её в таблицу идентификаторов и в поле результата пентады. Переход к шагу 15;

13.  Занести “GO” в качестве знака операции в пентаду, извлечь из стэка и занести в пентаду на место второго операнда последний элемент (имя метки). Переход к шагу 15;

14.  Занести “GF” в качестве знака операции в пентаду, извлечь из стэка и занести в пентаду на место второго операнда последний элемент (имя метки), извлечь из стэка и занести в пентаду на место первого операнда последний элемент.  Переход к шагу 15;

15.  Занесение текущей пентады в вектор пентад;

16.  Очистка полей текущей пентады и переход к шагу 2;

17.  выход из преобразователя.

Код преобразователя ПФЗ в последовательность пентад приведён ниже:

StackTetrad.push("Без этого не работает условие");

for(numtet=0; numtet<StrPFR.size(); numtet++)

{StackTetrad.push(StrPFR.get(numtet));

if(Metka.contains(StackTetrad.peek())==true)

{StrTetrad.add(StackTetrad.pop());

if(numtet+1 >= StrPFR.size())

{StrTetrad.add("_null"); StrTetrad.add("_null"); StrTetrad.add("_null"); StrTetrad.add("_null");VectorTetrad.add(StrTetrad.clone());

StrTetrad.removeAllElements();thismetka = false;}

else

{if(Metka.contains(StrPFR.get(numtet+1))==true)

{StrTetrad.add("_null");StrTetrad.add("_null");

StrTetrad.add("_null");

StrTetrad.add("_null"); VectorTetrad.add(StrTetrad.clone());

StrTetrad.removeAllElements();thismetka = false;}

else thismetka=true; }}

if(StackTetrad.peek()=="let")

{if(thismetka == false)StrTetrad.add(""); StrTetrad.add(StackTetrad.pop());

StrTetrad.add(StackTetrad.pop()); StrTetrad.add("_null");

StrTetrad.add(StackTetrad.peek());