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

4do4

Ключ лексемы

Индекс слова в группе

Значение

tmp_33

60

null

tmp_32

59

null

tmp_31

58

null

tmp_30

57

null

x52

54

null

x51

51

null

out3

56

null

out2

55

null

new

53

null

out1

52

null

tmp_38

65

null

tmp_37

64

null

tmp_36

63

null

tmp_35

62

null

tmp_34

61

null

2vars2

Ключ лексемы

Индекс слова в группе

Значение

d

67

null

c

66

null

Таблица констант

Ключ лексемы

Индекс слова в группе

0.5

4

5

6

4

2

3

7

2

0

1

3

0

1

8

5


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

Преобразование в ПФЗ типовых конструкций:

Наименование конструкции

Конструкция

ПФЗ

Присваивание

let a b

a ПФЗ(b) let

Арифметические операции (op – знак арифметической операции)

a op b

ПФЗ(a) ПФЗ(b) op

Логические выражения (op – знак логической операции)

a op b

ПФЗ(a) ПФЗ(b) op

Полный условный оператор

if (условие) Блок 1

else Блок 2

ПФЗ(условие) Label0 GF ПФЗ(Блок 1) Label1 GO Label0: ПФЗ(Блок 2) Label1:

Неполный условный оператор

if (условие) Блок

ПФЗ(условие) Label0 GF ПФЗ(Блок 1) Label0:

Постфиксная запись создаётся для блоков типа vars и  do. Постфиксная запись текущего блока сохраняется в вектор StrPFR. В конце обработки каждого блока происходит добавление созданной для текущего блока постфиксной записи в таблицу PFR по имени блока и очистка вектора StrPFR. В конце работы синтаксического анализатора в таблице PFR накапливается постфиксная запись всей программы на заданном варианте языка. При вхождении синтаксического анализатора в новый блок, его имя заносится в вектор NameBlock, который использоется лишь для наглядности вывода постфиксной записи и других данных на экран. Определение векторов приведено ниже:

//стэк для знаков опереций

final Stack StackOp = new Stack();

//стек для хранения номера текущего условия

final Stack StackIf = new Stack();

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

final Vector StrPFR = new Vector();

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

final Hashtable PFR = new Hashtable ();

//вектор для хранения имени всех блоков типа vars и do программы(используется для визуализации результата)

final Vector NameBlock = new Vector();

Для добавления в ПФЗ идентификатора или константы используется оператор:

StrPFR.add(currentLexem.textOfWord);

Для добавления в ПФЗ оператора let:

StrPFR.add("let");

Приоритетность арифметических операций сохраняется в ПФЗ. Это организовано за счёт включения более приоритетных операций в грамматику ниже, чем менее приоритетных. Поэтому операции * и / находятся ниже + и -, а определение скобочных выражений лежит ещё ниже. Для временного хранения знаков операций используется стэк StackOp. Операции, выполняемые с ним, приведены ниже:

StackOp.push (currentLexem.textOfWord); -- занесение знака операции в стэк

StrPFR.add(StackOp.pop ()); -- извление знака операции из стэка и добавление в ПФЗ

            Так как ПФЗ условного оператора использует метки, то формирование ПФЗ программы должно включать в себя формирование уникальных меток. Для этого в классе синтаксического анализатора была определена переменная-счётчик числа условных операторов: