Пентады формируются после создания ПФЗ каждого блока. Временные переменные для хранения результатов арифметических и логических вычислений заносятся в таблицу идентификаторов соответствующих блоков. Пентада состоит из 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());
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.