double arrow

Как должна выглядеть ОПС, чтобы реализовать цикл while

3

While E do R

Пример

While x<y do begin x:=x+1; … end

X y < m1 if x x 1 +:= … m0 j

Дополним грамматику:

A→ if E then *1 RL| while*4 E do*1 R*5

E→S<S|… E→(S)F’T’<S<|aDF’T’<S<

L→λ*2| else *3 R*2

R→A| begin P end |aD:=S| if …| while

Семантические программы: (для их реализации нужен независимый стек, т.е. у нас уже 3 стека, count - номер очередного символа обратной польской строки, который должен выводиться )

*1

count→в 3й стек,

пусто→ОПС,

jf →ОПС

*2

count→ ОПС[3й стек]

*3

(Count+2)→ОПС[3й стек]

count→ ОПС[3й стек]

пусто→ ОПС,

j → ОПС

пример:

if a<b then x:=a else x:=b

ab< m1 jf xa:= m2 j xb:=

| |

M1 M2

*4

В дополнительный 3ий стек записать номер счетчика count

*5

(count+2)→по ссылке из 3-го стека в ОПС

(По ссылке 3-го стека) →ОПС

j →ОПС

пример

while a<b do a:=a+1

ab < m1 jf aa1 +:= m0 j

| |

M0 m1

Цикла while вполне достаточно, поэтому не будем рассматривать реализацию (генерацию) цикла for и других…

Дополним грамматику операторами read и write.

A→ read H* read | write S *write

Где H→aD (скалярная переменная, индекс или пусто)

Разберемся теперь с описаниями переменных.

B→ program V; R _|_

B – вся программа

Описание может быть не одно, а несколько. V – возможная группа описания, U – одиночное описание (описывает либо вещественные либо целые переменные)

V→V;U

U→ int**1 a**2W| real aW

W→λ**5|[a**3]**4

Замена (исправленная грамматика, для анализатора LL(1)):

V→ int aW U’| real aW U’

U’→;U U’|λ

Описания могут быть и пустыми (например, если программа состоит только из оператора вывода). Тогда получаем

V→ int aW U’| real aW U’| λ

U’→;U U’|λ

**1

Тип – целый

**2

Имя a→в таблицу целых переменных (эта таблица – массив целых, где будут храниться значения этой переменной. Там же можно хранить, например, и само имя)

Для простых переменных этих двух программ достаточно, но для массивов – мало.

**3

Константа а →размер массива

**4

Размер → в таблицу

**5

0-размер →в таблицу

Мы рассмотрели действия для целых. Для вещественных те же действия, только отличается 1ый шаг. Ну и в таблице соответственные изменения.

  имя значение количество Ссылки для массивов
         
         
      >0  

Для работы с массивами – Ссылки для массивов, плюс в 4ую семантическую программу пишем:

Выделение памяти, в таблицу (номер переменной, размер в байтах)

Т.е. на выходе не только ОПС, но и сформированные таблицы переменных (т.е. таблицы, содержащие формат данных)

На выходе из синтаксического анализатора получим:

1. Длина констант типа int

2. Таблица констант типа int

3. Длина констант типа real

4. Таблица констант типа real

5. Длина переменных типа int

6. Таблица переменных типа int

7. Длина переменных типа real

8. Таблица переменных типа real

9. Длина ОПС

10. ОПС

При реализации процедур и функций у нас в языке появляются Описания и Вызовы.

Вызовы функций – операнды в формулах.

Вызов процедур как и во всех языках.

В момент вызова процедуры или функции должна работать автономная программа со своим локальным блоком памяти. Все фактические параметры и внутренние переменные локальны для конкретного вызова. Т.е. нужно предусмотреть выделение блока памяти по типу стека (для локальных переменных) при каждом вызове. И этот стек можно совместить с основным стеком вычислений, которые использует интерпретатор.

Тогда ОПС может иметь такой вид:

Pr(a,b,c,d);

Если считать что в момент вызова порядок операндов не меняется, то:

Pr – имя процедуры, операнд

Нужно предусмотреть счетчик количества параметров в вызове процедуры (4).

Pr abcd 4 сall точка возврата

Сall – универсальная процедура вызова

«Возврат из процедуры» – операция, должна стоять в конце процедуры, должна привести стек в такой вид, который был до вызова.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  


3

Сейчас читают про: