2. Элементы теории компиляции.
Компилятор – системная обрабатывающая программа, которая переводит исходную программу, написанную на языке высокого уровня, в машинную форму (объектную программу).
Объектная программа представляет из себя последовательность машинных кодов.
Работа компилятора состоит в изменении алфавита, лексики, синтаксиса при сохранении семантики (смысла).
Алфавит – множество допустимых символов, которое используется для построения конструкций языка.
Лексика – набор отдельных смысловых единиц языка (лексемы).
Лексема – минимальная конструкция языка, имеющая смысл.
К лексемам относятся имена переменных, служебные слова, константы, знаки операций, разделители и т.д.
3. Общая схема работы компилятора
Общая схема работы компилятора состоит из двух фаз:
1. фаза анализа
2. фаза синтеза
1. Фаза анализа начинается с работы лексического анализатора (сканера).
Она заключается в просмотре исходной программы выделение и классификация различных лексем и заполнение соответствующих таблиц для передачи на следующую стадию.
Следующий за сканером вступает в работу синтаксический анализатор (парсер). В нее сканер передает таблицу лексем. Парсер проверяет каждую лексему на правильность и последовательность, если оно построено по правилам, то переходит на следующий этап.
Следующая часть – семантический анализатор. Когда правильность конструкций установлена, запускается семантический анализатор. Проверка заключается в попытке интерпретации смысла конструкции. Достаточно часто синтаксически правильная конструкция является неправильной с точки зрения семантики.
Семантический анализатор для каждой синтаксической конструкции ставит в соответствие некоторое значение, которое может быть присвоено в одной из следующих форм:
2. Фаза синтеза начинается с распределения памяти по переменным программы.
Здесь просматривается таблица символьных имен и для каждого имени выделяет память, т.е. назначает начальный адрес размещения и размер области. Таким же путем выделяется память под промежуточные переменные.
Такое выделение памяти называется статическим выделением памяти.
Кроме статических переменных существуют динамические. Под них память выделяется следующим образом: в обратный код вставляются фрагменты кода, которые будут выполняться при выполнении программы. В результате формируется таблица распределения памяти.
Следующий этап – оптимизация кода. Обычно осуществляется в двух направлениях:
Существуют два подхода:
оптимизация на уровне машинных команд
оптимизация на уровне промежуточных кодов.
Do'stlaringiz bilan baham: |