Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория языков программирования методов трансляции.-1.pdf
Скачиваний:
13
Добавлен:
05.02.2023
Размер:
1.36 Mб
Скачать

220

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

Во время компиляции в соответствии с прикладной реализацией идентификатора, например х в х + 4, необходимо:

1)найти в таблице символов запись, соответствующую определяющей реализации (int x) идентификатора;

2)поместить в нижний стек статические характеристики, соответст-

вующие идентификатору.

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

10.4. Проблемы, связанные с типами

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

1)Распроцедуриваниепереход от procedure real к real.

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

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

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

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

6)Чистка, например переход от real к void.

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

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

SOFT => deprocedure |

221

deprocedure SOFT

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

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

MEEK => deprocedure | deprocedure MEEK | dereference | dereference MEEK.

Другими словами, в раскрытой позиции можно выполнять распроцедуривание и разыменование любое число раз и в любом порядке, например:

pointer procedure poiter int в вид int

Для сильной позиции (например, правая часть присвоения или параметр в вызове процедуры) правила таковы:

STRONG => dereference STRONG | deprocedure STRONG | unit |

unit ROW | widen |

widen widen | widen ROW | widen widen ROW | ROW |

ROW => row | row ROW

Вид данных до выполнения приведений называется априорным, а после выполнения - апостериорным. В случае сильных и раскрытых синтаксических позиций известны и априорный и апостериорный виды. Для других позиций известен лишь априорный вид и некоторая информация об апостериорном виде, например о том, что он должен начинаться со struct или pointer struct, или о том, что он не должен начинаться с proc, как в левой части присвоения.

Компилятор, применяя соответствующую грамматику, генерирует последовательность приведений из априорного вида к известному либо к подходящему апостериорному виду. Если нельзя найти никакой последовательности приведений, программа синтаксически неправильная.

222

С другой стороны, если подходящая последовательность существует, компилятор, применяя приведения по порядку, генерирует код времени прогона.

Еще один вид приведения - чистка. Чистка представляет собой особую форму приведения и происходит в тех местах, где стоит точка с запятой

x=y;

Еще одна сложность связана с выбирающим предложением. В предложении

x + if b then 1 else 2.3

во время компиляции необходимо знать тип(вид) правого операнда знака «+». Все варианты выбирающего предложения должны приводить к общему виду, называемому объектным. Этот процесс называется уравнением, и его правила подразумевают, что последовательность сильных приведений можно применять во всех вариантах, кроме одного, в котором используется лишь последовательность приведений, уместных лишь для синтаксической позиции выбирающего предложения. В вышеприведенном примере выбирающее предложение находиться в крепкой синтаксической позиции, которая не допускает расширения. Однако внутри выбирающего предложения один вариант допускает сильное приведение, что может повлечь за собой расширение. В этом случае объектным видом окажетсяreal, и первый вариант следует расширить, а второй нежелательно подвергать приведению.

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

10.5. Время компиляции и время прогона

Как отмечалось ранее, генератор кода во время компиляции обращается к нижнему стеку и генерирует код операций, которые будут выполняться во время прогона. Что именно должно быть сделано во

223

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

Для повышения эффективности выдаваемого кода при компиляции можно проделать дополнительную работу, которую показывают компиляцией. В оптимизацию входит удаление кодов из циклов там, где это не влияет на значение программы, исключение возможности вычисления идентичных выражений более одного раза и. Особоет.д

внимание уделяется возможности избежать перезаписи сложных структур данных во время прогона.

Контрольные вопросы

1.Технология создания промежуточного кода. Виды промежуточного кода.

2.Алгоритм преобразования арифметического выражения в префиксную и постфиксную форму.

3.Формализация записи промежуточного кода.

4.Структуры данных для генерации промежуточного кода.

5.Алгоритм генерации промежуточного кода для арифметических выражений.

6.Таблица блоков, ее назначение.

7.Генерация кода для присвоения.

8.Генерация кода для условных зависимостей.

9.Генерация кода для описания идентификаторов.

10.Генерация кода для циклов.

11.Генерация кода для входа и выхода из блока.

12.Генерация кода для прикладной реализации.

13.Проблемы генерации кода, связанные с типами.

14.Работа генератора кода во время компиляции и во время прогона.