Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [ 50 ] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

Увеличить next на 1.

Выдать код для сравнения управляющей переменной с верхним пределом и перейти к L<next>, если управляющая переменная больше верхнего предела:

JUMPF L<next>, address (controlled variable), address (ulimit)

Поместить в стек значение next. Поместить в стек значение next - 1. Увеличить next на 1. А4. Генерировать код для увеличения управляющей переменной

PLUS address (controlled variable), 1

Удалить из стека номер (i). Генерировать код для перехода к L<i>

GOTO L<i>

Цикл

for i to 10 do something od генерирует код следующего вида:

MOVE «1», address (controlledvariable) MOVE address (ulimit), wostackpointer

SETLABEL L1

JUMPF L2 address (controlled variable), address ( uilimit) (something) PLUS address (controlled variable), 1

GOTO L1 SETLABEL L2

Действие А4 можно видоизменить, если приращение управляющей переменной будет не стандартным, равным 1, а иным, например в

for i by 5 to 10 do

Для этого, возможно, придется вычислять выражение и хранить его значение в рабочем стеке, чтобы использовать как приращение в Алголе 68 приращение вычисляется один раз перед входом с цикл, после чего его нельзя изменить. Аналогично в

for i from m + n to 20 do

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

Если в цикле содержится часть while, как, например, в

for i to 10 while a<b do действие А3 следует видоизменить, чтобы при принятии решения в выходе из цикла учитывались значения как части while, так и управляющей переменной, причем любая из этих проверок достаточна для завершения цикла.

5. Вход и вгход из блока

При входе в блок (последовательное предложение описаниями в Алголе 68) предположим, что во время предыдущего прохода получена определенная информация.



Она состоит из таблиц видов и символов, дающих типы или виды всех идентификаторов и т. п. Тогда при входе в блок нужно выполнить следующие основные действия:

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

2. Поместить в стек (idstack pointer). Поместить в стек (wostack pointer). Поместить в стек (block number). Все эти значения ссылаются на включающий блок и могут потребоваться вновь после того, как будет покинут блок, в который только что осуществлен вход

idstack pointer := 0 wostack pointer := 0

3. Генерировать код для исправления DISPLAY

BLOCK ENTRY block number

4. Увеличить номер блока на 1. Увеличить gbn (наибольший использованный до сих пор номер блока) на 1 и присвоить это значение номеру блока.

5. Прочитать информацию в виде и добавить ее в таблицу видов (если в языке имеются такие < сложные» виды, как в Алголе 68).

При выходе из блока требуется:

1.Обнавить таблицу блоков, задав размер стека идентификаторов и т.п. для покинутого блока.

2. Исключить информацию в виде таблицы символов для покинутого блока (см. разд. 8.1.).

3. Генерировать код для изменения дисплея

BLOCK EXIT block number

4. Удалить из стека (block number). Удалить из стека (wostack pointer). Удалить из стека (instack pointer). Уменьшить размер уровня блока на 1.

5. Поместить результат (при необходимости) в рамку вызывающего блока.

6. Прикладные реализации

Во время компиляции в соответствии в прикладной реализацией идентификатора, например x в

необходимо:

1. Найти в таблице символов запись, соответствующую определяющей реализации, например int х идентификатора.

2. Поместить в нижний стек статические характеристики значения, соответствующего идентификатору.

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



10.4. ПРОБЛЕМЫ, СВЯЗАННЫЕ С ТИПАМИ

При обсуждении работы генератора кода с определенными типичными конструкциями языков программирования высокого уровня мы почти не касались проблем, связанных с типами, которые могут быть относительно простыми, как в Фортране или Бейсике, и довольно сложными, как Алголе 68 или ПЛ/1. В компиляторе Алгола 68 половины кода может приходиться на обращение с видами.

Кто-то однажды сказал, что беда Алгола 68 состоит в том, что приходится изучать все приведения, какие только иметь место. Возможно, это - правильно, но вывод о наличии большого числа приведений (или автоматических изменений видов) по меньшей мере неверной. По сравнению с ПЛ/1, где автоматически преобразования вида, такие, как целый в литерный или литерный в Алголе 68 крайне ограничен. В нем возможно шесть приведений:

1. Распроцедуривание, например переход от вида proc real к виду real.

2. Разыменование, например переход от вида ref real к виду real.

3. Объединение, например переход от вида real в виду union (real, char).

4. Векторизация, например переход от вида real к виду [ ] real.

5. Обобщение, например переход от вида int к виду real.

6. Чистка, например переход от вида int к виду void.

Возможность осуществления приведения зависит от синтаксической позиции. Например, в левой части присваивания может иметь место только распроцедуривания (вызов процедуры без параметров), а в правой части - любое из шести привидений. Например, если x имеет вид ref real и а - ref int, то прежде чем произойдет присваивание

x := a,

а необходимо сначала разыменовать, а затем обобщить.

В зависимости от того, какие приведения могут выполняться в синтаксических позициях, последние называют мягкими, слабыми, раскрытыми, крепкими или сильными. Например, левая часть присваивания является мягкой (допускается только распроцедуривание), а правая часть - сильной (допускается любое приведение). Кроме ограничения типов приведений, разрешаемых в заданной синтаксической позиции, существуют правила, определяющие порядок осуществления различных приведений. Например, объединение может произойти только один раз и не должно следовать за векторизацией. Можно определить грамматику, которая генерирует все допустимые последовательности приведений в заданной синтаксической позиции, например

SOFT deprocedure

deprocedure SOFT

Любое предложение, генерируемое посредством SOFT, представляет собой допустимую последовательность приведений в мягкой синтаксической позиции (т. е. в левой части присваивания).

Для раскрытой позиции (например, индекс в А [i]) справедливы следующие правила:

MEEK deprocedure

deprocedure MEEK dereference dereference MEEK



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [ 50 ] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69