Cтраница 1
Генерирование кода аналогично формированию и макрорасширению. Самым трудным является процесс синтеза. Его сложность не столь уж существенна, но она отражает необходимость выбора для выхода из синтезатора таких операций, которые намного отличаются от операций, подразумеваемых исходным языком. Экономические соображения заставляют нас находить эффективные последовательности операций в существующих машинах, а это затруднительно. Во многих случаях экономически выгоднее выбирать относительно сложные и управляемые языком операции и осуществлять выполнение программы интерпретирующим образом. Экономия времени компиляции и основной памяти часто возмещает нам потери в эффективности выполнения программы. [1]
Приводит к генерированию кода проверки семантических элементов программных выражений. [2]
Последним выполняется процесс генерирования кода, который использует результаты синтаксического анализатора и создает программу на машинном языке, пригодную к выполнению. [3]
Последний можно использовать для генерирования дуального кода. [4]
Данный ключ приводит в действие и отменяет генерирование кода проверки границ. При указании R все выражения с индексированными строками и массивы проверяются на предмет нахождения индекса внутри их границ, а все операторы присваивания скалярным и переменным величинам типа диапазон проверяются на принадлежность заданным границам. Если обнаруживается нарушение диапазона, то программа завершает свою работу, выводя сообщения об ошибке времени выполнения. Приведенная в действие проверка границ замедляет работу программы и увеличивает ее размер. [5]
Этим ключом осуществляется выбор одной из двух моделей генерирования кодов вычислений с плавающей запятой, имеющихся в Турбо Паскале. При указании режима N - генерируется код для программного выполнения всех вещественно-числовых вычислений. [6]
В зависимости от режима приводится в действие или отменяется генерирование кода проверки переполнения стека. При указании S компилятор генерирует в начале каждой процедуры или функции код, который проверяет, достаточное ли место в стеке выделено для локальных переменных. Если в стеке места недостаточно, то обращение к процедуре или функции, скомпилированное с указанием S, приводит к завершению работы программы, которая при этом выводит сообщение об ошибке времени выполнения. [7]
Все четыре логически последовательных процесса - сканирование, анализ, синтез и генерирование кода - могут быть или синхронными и взаимосвязанными, или последовательными и раздельными. Критерием выбора обычно служит объем имеющейся основной памяти. [8]
Когда заполнение таблицы литералов и таблицы символов-завершено, можно перейти ко второму просмотру ( рис. 3.4), цель которого состоит в вычислении аргументов и в генерировании кодов. Для того чтобы сгенерировать правильный адрес в-команде, нужно знать, какой регистр следует использовать в качестве базового. Для определения смещения нужно знать содержимое этого базового регистра. Конечно, ассемблер не располагает информацией о содержимом базового регистра во время выполнения программы; но значения относительно начала программы ему известны. Поэтому ассемблер вводит в качестве-содержимого его относительное значение. Это значение используется для вычисления смещения. В результате обработки псевдокоманд USING заполняется таблица базовых регистров, приведенная выше. [9]
В разделе 2.2 мы указывали, что программу можно частично интерпретировать, исходя из конструкций непосредственных составляющих, ассоциируя их значения с каждым правилом грамматики. Стек, содержащий последовательные конфигурации, является стеком разбора. Мы можем получать одноадресный код, не пользуясь промежуточной польской строкой, а помещая информацию о синтезе в стеки параллельно и синхронно со стеком разбора и применяя тот же основной алгоритм генерирования кода. [10]
В табл. 3.4 2 показаны три стека: стек разбора, стек имени / значения и стек имени символа. В центральном столбце приведен необработанный входной текст. В последнем столбце даны примечания к процессу порождения одноадресного кода. Эти действия описывают алгоритм генерирования кода, аналогичный алгоритму, предложенному в конце раздела 3.3. Никакой попытки формализации алгоритма не предпринято; ожидается, что читатель получит достаточное представление об этом из раздела 3.3 и табл. 3.4.2, чтобы применять этот алгоритм для решения последующих примеров. [11]