Cтраница 2
Чем сложнее фаза генерации кода, тем проще становятся оставшиеся фазы компилятора. Так, например, если фаза генерации кода производит коды на языке ассемблера, в дальнейшем потребуется одно - или двупросмотровый ассемблер для получения объектного модуля на машинном языке. Если информация в таблице символов компилятора целиком и без изменений передается ассемблеру, может использоваться однопросмот-ровый ассемблер; если передаются только операторы DS и DC, необходим двупросмотровый ассемблер. [16]
Задача, которую должна решать фаза сборки, во многом зависит от того, что было сделано при выполнении фазы генерации кода. В другом случае, если фаза генерации кода оставляет команды и метки в символическом виде, фаза сборки должна: 1) разрешить все символьные ссылки; 2) вычислить адреса; 3) сгенерировать двоичные машинные команды; 4) выделить память и преобразовать литералы. [17]
Смещение может быть найдено из элемента В в таблице идентификаторов. Номер регистра базы выбирается произвольно; однако, фаза генерации кода должна производить код, который загружает в этот регистр базы адрес начала области статической памяти. [18]
Фазы лексического и синтаксического анализов почти не зависят от машины. Поэтому переносимые компиляторы реализуются по схеме: фаза лексического и синтаксического разбора - - генерация промежуточного представления - фаза генерации кода - - рабочая программа. Выбор удачного промежуточного представления определяет эффективность будущего компилятора и позволяет отделить машинонезависи-мую часть от генератора кода. Фактически любой процесс переноса, если он не основывается на использовании существующих языков программирования, предполагает использование промежуточного представления. [19]
Существуют две причины, по которым имеет смысл заводить такую матрицу: 1) первые четыре фазы компилятора могут быть сделаны машинно-независимыми; 2) это позволяет проводить машинно-независимую оптимизацию программы перед фазой генерации кода. Простая форма отдельного элемента матрицы предусматривает три поля, первое из которых содержит стандартный символ, представляющий либо терминальный символ, либо знак операции, остальные два элемента содержат стандартные символы аргументов. Фаза генерации кода использует эту матрицу, производя соответствующий объектный код. [20]
Литералы являются десятичными числами, а формат идентификаторов - числа с фиксированной точкой. Фаза генерации кода должна проверять в матрице не только операции, но и типы данных в операндах и в зависимости от способа их использования создавать соответствующие программы преобразования. [21]
Существуют две причины, по которым имеет смысл заводить такую матрицу: 1) первые четыре фазы компилятора могут быть сделаны машинно-независимыми; 2) это позволяет проводить машинно-независимую оптимизацию программы перед фазой генерации кода. Простая форма отдельного элемента матрицы предусматривает три поля, первое из которых содержит стандартный символ, представляющий либо терминальный символ, либо знак операции, остальные два элемента содержат стандартные символы аргументов. Фаза генерации кода использует эту матрицу, производя соответствующий объектный код. [22]
![]() |
Взаимодействие фаз лексического анализа, синтаксического анализа и фазы интерпретации. [23] |
Матрица - это основная база данных, используемая в фазе оптимизации. Для облегчения процесса исключения и добавления новых элементов матрицы каждый элемент содержит информацию о его местоположении в связанной цепочке элементов, которое задается с помощью прямого и обратного указателей. Это позволяет избежать необходимости реорганизации и перераспределения элементов матрицы, когда появляется новый элемент или исключается старый. Прямой указатель позволяет фазе генерации кодов просматривать матрицу в прямом направлении. Обратный указатель позволяет осуществлять обратный просмотр матрицы, что может понадобиться для целей оптимизации, например вынесения инвариантных вычислений за тело Цикла. [24]
Определим соответствующие программы интерпретации ( например, программу ENTER, которая задает границы массива, основание, точность) и напишем редукции. Заметим, что фаза интерпретации вносит информацию в таблицу идентификаторов в процессе обработки оператора декларации. Когда обрабатываются арифметические операторы, содержащие индексные переменные, фаза интерпретации должна завести в матрице элементы, которые позволят фазе генерации кода определить адреса. [25]