
лекции / СПО-фазы компилирования (окончание)
.doc2 Лексический анализатор (скаля) – читает исходную программу и выделяет в её тексте лексемы входного языка, которые заносит в таблицу лексем.
Например:
begin
for i:=1 to N do
fg;=fg*0.5
лексема |
тип |
значение |
begin for i := 1 to N do fg := fg * 0.5 |
ключевое слово ключевое слово идентификатор знак присвоения целочисленная константа ключевое слово идентификатор ключевое слово идентификатор знак присвоения идентификатор знак арифметической операции константа |
x1 x2 i:1 := 1 x3 N:2 x4 fg:3 := fg:3 * 0.5 |
(Таблица идентификаторов i, N, fg и т.д.)
Строится на основе КА, но должен также
а) четко определять границы лексем, т.е. выделять строки из входного потока символов для распознавания (как правило, границы лексем определяются по пробелам, символам комментариев, разделителям ( , ; и т.д.))
б) выполнять действия для сохранения информации об обнаруженной лексеме.
3 Синтаксический разбор – выявляет основные синтаксические конструкции входного языка, устанавливает их тип и проверяет правильность.
В нем исследуется таблица лексем, которая поступает на его вход. Синтаксический анализатор исследует только тип лексемы.
Строится на основе МП-автомата.
4 Семантический анализ – проверяет правильность текста исходной программы с точки зрения семантики входного языка, а также преобразует текст, в соответствии с семантикой входного языка.
Входные данные: таблица идентификаторов; результаты разбора синтаксических конструкций входного языка.
Этапы семантического анализа:
а) проверка соблюдения во входной программе семантических соглашений входного языка:
– каждая метка, на которую есть ссылка должна присутствовать;
– идентификатор должен быть описан один раз;
– типы должны быть согласованы между собой;
– число фактических параметров должно быть согласовано с числом и типом формальных параметров.
б) дополнение внутреннего представления программы в компиляторе операторами и действиями, неявно предусмотренными семантикой языка: связано с преобразованием типов операндов в выражениях и при передаче параметров в процедуры и функции.
Это выполняется с помощью библиотек функций преобразования типов, которые должны быть встроены во внутреннее представление программы в компиляторе.
в) проверка элементарных смысловых норм языков программирования, напрямую не связанные с входными языками.
Например: – каждая переменная должна хотя бы раз использоваться в программе;
– цикл должен быть завершен;
– выполнение операторов условий по каждой из своих ветвей и т.д.
5 Подготовка к генерации кода – выполнение предварительных действий, непосредственно связанных с синтезом текста результирующей программы, но еще не ведущие к порождению текста на выходном языке:
а) идентификация элементов языка – установление соответствия между объектами и их именами в тексте исходной программы:
– имена локальных переменных дополняются именами блоков, в которых они описаны;
– имена процедур и функций модифицируются в зависимости от типов их формирующих аргументов и т.д.
б) распределение памяти – установление соответствия лексических единиц исходной программы, адрес, размер и атрибуты области памяти, необходимой для этой лексической единицы.
Например: – для массивов – произведение числа элементов в массиве на размер памяти для одного элемента;
– для записей – сумма размеров памяти по всем полям структуры и т.д.
6 Генерация кода – порождение команд, составляющих предложения выходного языка и в целом результирующей программы.