- •Предисловие
- •Глава 1 введение в проблематику конструирования компиляторов
- •1.1. Понятие компилятора и его структура
- •1.2. Применение компиляторов и задачи их разработки
- •Глава 2 способы задания формальных языков
- •2.1. Математический аппарат теории
- •Формальных языков, перевода и компиляции
- •1) AR*a для всех aÎa;
- •2.2 Цепочки и языки
- •2.3 Грамматики
- •2.4. Распознаватели
- •2.5 Регулярные выражения и синтаксические диаграммы
- •2.6. Автоматы с магазинной памятью (мп - автоматы )
- •2.7. Соответствия между способами описания языков
- •Глава 3 основы теории перевода
- •3.1. Определение перевода
- •3.2. Модели простейших трансляторов
- •3.2.1. Конечные преобразователи
- •3.2.2. Преобразователи с магазинной памятью
- •Глава 4 конструирование сканеров
- •4.1. Общая характеристика процесса сканирования
- •4.2. Описание лексем в языке расширенных регулярных выражений
- •4.3. Построение недетерминированного конечного автомата по расширенному регулярному выражению
- •4.4. Преобразование недетерминированного конечного автомата в детерминированный
- •Замечание. Среди состояний могут оказаться недостижимые состояния . Состояние р называется достижимым , если существует такая цепочка w , что (q0, w) *(p , e ). ¨
- •4.5. Преобразование синтаксической диаграммы в конечный автомат
- •4.6. Представление результатов сканирования
- •4.7. Методики конструирования сканеров
- •Глава 5 конструирование однопроходных нисходящих анализаторов
- •5.1. Определение синтаксического разбора
- •5.2. Нисходящий и восходящий разборы
- •5.3. Ll(k) - грамматики
- •5.4. Предсказывающие алгоритмы разбора
- •5.5. Алгоритмы построения управляющих таблиц для левых анализаторов
- •5.6. Приведение грамматик к ll - форме
- •Глава 6 основы генерации кода
- •6.1. Перевод и генерация кода
- •6.2. Представления промежуточной программы
- •6.3. Преобразование промежуточной программы в ассемблерный код
3.2. Модели простейших трансляторов
3.2.1. Конечные преобразователи
Введем простейший транслятор - конечный преобразователь.
Преобразователь - это просто распознаватель, выдающий на каждом такте выходную цепочку (она может быть пустой). Конечный преобразователь получится, если конечному автомату (распознавателю) позволить выдавать на каждом такте цепочки выходных символов (рис.3.1). В п.4.3 мы будем пользоваться конечным преобразователем как моделью лексического анализатора.
Для большей общности рассмотрим в качестве основы конечного преобразователя недетерминированный конечный автомат, способный делать е - такты.
Определение. Конечным преобразователем называется шестерка
где Q - конечное множество состояний;
S - конечный входной алфавит;
- конечный выходной алфавит;
d - отображение множества в множество конечных подмножеств множества Q;
- начальное состояние;
- множество заключительных состояний. ¨
Определим конфигурацию преобразователя М как тройку (q,x,y),
где - текущее состояние управляющего устройства;
*- оставшаяся непрочитанной часть входной цепочки;
y - часть выходной цепочки, выданная вплоть до текущего момента.
Определим бинарное отношение м (или , когда ясно о каком М идет речь) на конфигурациях, соответствующее одному такту работы преобразователя М , следующим образом:
для всех таких, что , будем писать
Обычным образом определяются отношения .
Цепочку у назовем выходом для цепочки х, если (q0,x,e) *(q,e,y) для некоторого .
Переводом, определяемым преобразователем M (обозначается ), называется множество
*(q,e,y), qÎF}.
Для представления функции переходов конечного преобразователя удобно использовать графы переходов, как это делалось для представления КА. На каждой дуге графа кроме входного указывается и выходной символ, соответствующий данному переходу.
Пример 3.2. Построим конечный преобразователь, который распознает арифметические выражения, порождаемые правилами
S ® a+S|a-S|+S|-S|a ,
и устраняет из этих выражений избыточные унарные операции.
Пусть M = ({q0,q1,q2,q3,q4},{a,+,-},{a,+,-}, d,q0,{q1}),
где d определяется графом (рис. 3.2).
Рис. 3.2
Д ля входа -а+-а-+-а последовательность тактов преобразователя М такова:
(q0,- a + - a - + - a,e) (q4, a + - a - + - a,e)
(q1,+ - a - + - a,- a)
(q2,- a - + - a,- a)
(q3, a - + - a,- a )
(q1,- + - a,- a- a)
(q3,+ - a,- a - a)
(q3, - a,- a - a)
(q2, a,- a - a)
(q1,e,- a - a + a)
Отсюда ясно, что М отображает цепочку -а+-а-+-а в цепочку -а-а+а, поскольку q1- заключительное состояние.
3.2.2. Преобразователи с магазинной памятью
Теперь введем другой важный класс трансляторов, называемых преобразователями с магазинной памятью. Эти преобразователи получаются из автоматов с магазинной памятью, если их снабдить выходом и разрешить на каждом такте выдавать выходную цепочку конечной длины (рис.3.3).
Рис. 3.3
Определение. Преобразователем с магазинной памятью (МП - преобразователем) называется восьмерка P=(Q,S,G,D,d,q0,Z0,F), где все символы имеют тот же смысл, что и при определении МП -автомата, за исключением того, что D - конечный выходной алфавит, а d - отображение множества в множество конечных подмножеств множества Q´G *´D* . ¨
Определим конфигурацию преобразователя Р как четверку (q,x,a,y), где q,x и a те же, что у МП-автомата, а у - выходная цепочка, выданная вплоть до настоящего момента.
Если d(q,a,Z) содержит (r,a,z), то будем писать :
(q,ax,Zg, у ) (r,x, ag, уz)
Это бинарное отношение представляет такт работы МП-преобра-зователя.
Пример.3.3 Рассмотрим МП - преобразователь
,
где d - определяется равенствами:
Для входа +*ааа МП - преобразователь Р сделает такую последовательность тактов:
Таким образом, Р переводит цепочку +*ааа в цепочку аа*а+, опустошая магазин. Можно показать, что t(P)={(x,y) | x - префиксная польская запись арифметического выражения, y - соответствующая постфиксная польская запись}
МП - преобразователь является наглядной моделью синтаксического анализатора.