Режим переполоха. Преобразование входного текста в постфиксную форму записи, страница 5

1.  Постфиксной записью (ПФЗ) пустой цепочки символов e является e.

2.  Постфиксной записью идентификатора i является идентификатор i.

3.  Постфиксной записью константы c является константа c.

4.  Если E – произвольное выражение, то постфиксной записью выражения ( E ) будет ПФЗ(E):

( a + b * c )        =>     abc * +

5.  Если E – выражение вида 2, 3 или 4, то постфиксной записью выражения – E (изменение знака значения E) будет ПФЗ(E) –:

=>     x –     ( или 0 x –)

6.  Если E – выражение вида 2, то постфиксной записью выражений ++E, – – E,  E ++ и E– – является ПФЗ(E) + +
и ПФЗ(E)– – соответственно. (Если такое выражение может встречаться как составная часть другого выражения, то это определение неверно, его нужно дорабатывать).

7.  Если E 1 , E 2 , … E k– выражения вида 2…9, то постфиксной записью выражения ● (E 1 , E 2 , … E k) является ПФЗ(E 1) ПФЗ(E 2) ... ПФЗ(Ek) ●, где ● – знак любой k-арной операции (функции с k аргументами), а ПФЗ(E 1), ПФЗ(E 2) … ПФЗ(Ek) – постфиксные записи выражений E 1 , E 2E k соответственно.

GetClientRect(hWnd,myRect)          =>     hWnd myRect GetClientRect

(Доработка пункта 6: ПФЗ(++E) = ПФЗ( incPre(&E) ) = E & incPre, ПФЗ(E++) = E & incPost)

8.  Если E 1 и E 2 – выражения вида 2…7, то постфиксной записью выражения E 1 ●  E 2 является ПФЗ(E 1) ПФЗ(E 2) ●, где ●  – знак любой бинарной операции (присваивания, сложения, вычитания, умножения, …), а ПФЗ(E 1) и
ПФЗ(E 2) – постфиксные записи выражений E 1 и E 2 соответственно.

9.  Если E 1 , E 2 , E 3 – выражения вида 2…8, то постфиксной записью выражения E 1 ¨ E 2E 3 (где ¨ и ● – знаки бинарных операций) является ПФЗ(E 1) ПФЗ(E 2) ¨ ПФЗ(E 3) ●, если приоритет знака операции ¨ не меньше приоритета знака операции ●, и ПФЗ(E 1) ПФЗ(E 2) ПФЗ(E 3) ● ¨ – в противном случае.

( a * b + c )        =>     ab*c  +

10.  Если E 1 выражение вида 2, а E 2 – выражение вида 2…9, то постфиксной записью выражения E 1E 2 ; является ПФЗ(E 1) ПФЗ(E 2) ●, где ●  – знак операции присваивания ( такой как =, +=, *=, …).

x=( a * b + c ) / d ;      =>     x a b * c + d / =

Расширим грамматику Ga1 до грамматики операторов присваивания и добавим действия для преобразования в ПФЗ:

0. Z : P u

1. P : { PutToPFR(CurrentLexem); } i = S { PutToPFR(“=”); }

2. S : S + T { PutToPFR(“+”); }

3. S : T

4. T : T * F { PutToPFR(“*“); }

5. T : F

6. F : ( S )

7. F : { PutToPFR(CurrentLexem); } i

8. F : { PutToPFR(CurrentLexem); } c

Преобразование управляющих конструкций
языка программирования в постфиксную форму записи

Operator : while ( Expression ) Block

ПФЗ( while ( Expression ) Block ) =

Label1: ПФЗ( Expression ) Label2 JmpFПФЗ( Block ) Label1 Jmp Label2:

Должна быть обеспечена уникальность меток.

Используется счетчик операторов цикла WhileCount и стек для хранения номеров операторов цикла wStack:

Operator : while

{ wStack.Push(++WhileCount); PutToPFR(“Label1” + Top() + “:”);}

( Expression )

{ PutToPFR(“Label2” + wStack.Top()); PutToPFR(“JmpF”); }

Block

{ PutToPFR(“Label1” + wStack.Top()); PutToPFR(“Jmp”);

PutToPFR(“Label2” + wStack.Pop() + “:”); }

При наличии многих разных управляющих конструкций (циклы, переключатели, условные операторы) можно использовать разные счетчики и разные «базовые» части меток, а можно преобразовывать все такие операторы с использованием одного счетчика (и одной и той же «базовой» части меток).


СЕМАНТИЧЕСКИЙ АНАЛИЗ

 


x = ( a + b ) * ( cd ) ;

x a b + c d – * =

Операция

Имя операнда 1

Имя операнда 2

Имя результата

+

b

a

¯

+

d

c

¯

*

­

­

¯

=

­

x