- •Содержание
- •Введение
- •1 Организация таблицы идентификаторов
- •1.1 Исходные данные
- •1.2 Назначение таблицы идентификаторов
- •1.3 Метод простого рехэширования
- •1.4 Метод бинарного дерева
- •1.5 Результат выполнения программы
- •2 Проектирование лексического анализатора
- •2.1 Исходные данные
- •2.2 Назначение лексического анализатора
- •2.3 Схема распознавателя
- •2.4 Результат выполнения программы
- •3 Построение дерева вывода
- •3.1 Исходные данные
- •3.2 Синтаксический анализатор
- •3.3 Таблицы предшествования
- •Матрица предшествования исходной грамматики
- •3.4 Результат выполнения программы
- •3.5 Вывод
- •Заключение
- •Список литературы
- •Приложение а – Листинги программы
2.2 Назначение лексического анализатора
Лексический анализатор (или сканер) – это часть компилятора, которая читает литеры программы на исходном языке и строит из них слова (лексемы) исходного языка. На вход лексического анализатора поступает текст исходной программы, а выходная информация передается для дальнейшей обработки компилятором на этапе синтаксического анализа и разбора.
В основном лексические анализаторы выполняют исключение из текста исходной программы комментариев и незначащих пробелов, а также выделение лексем следующих типов: идентификаторов, строковых, символьных и числовых констант, ключевых (служебных) слов входного языка.
2.3 Схема распознавателя
Распознаватель лексем языка для данной грамматики задан конечным детерминированным автоматом, схема которого представлена на рисунке 2.1.
Рис. 2.1 – Схема распознавателя
h– начальное состояние автомата
S– конечное состояние автомата
Заданные правила могут быть записаны в форме Бэкуса-Наура.
G(VT,VN,P,S)
VT– множество терминальных символов;
VN– множество нетерминальных символов;
P– множество правил;
S– целевой символ.
Регулярная грамматика входного языка имеет вид:
G (
{0,1, p, r, o ,g, e, n, d, t, h, l, s, b, I, w, ‘+’, - , ‘++’, ‘;’, ‘(‘, ‘)’, = , ‘>’ , ‘<’ },
{h, A, B, C, D, E, H, G, K, L, M, R, N, O, P, I, J, Q, V, W, X, Y, Z, T, U, F, AA, AM, AB, AC, AD, AG, AF, AH, AI, AE, AK, AL, AJ, AN, AO, AP, AQ, AR, AT, AU, AV, AW, AX, FF, RR}
P, S
)
P:
S → prog L end.
L → O | L;O | L;
B→ B or C | C
D → G | not D
G → E < E | E>E | E=E | (B)
K → G then O
M → K else O
Q → G do O
O → if M | if K| begin L end | while Q | c:=E
E → E-F | E+F | E++|
F → (E) | c | g
2.4 Результат выполнения программы
Результаты разбора входных выражений на лексемы представлен на рисунке 2.2
Рис. 2.2 – Результаты разбора входных выражений на лексемы
Спроектированный лексический анализатор выполняет лексический анализ входного текста в соответствии с заданной грамматикой и порождает таблицу лексем с указанием их типов. Программа выводит также сообщения о наличие во входном тексте ошибок. Этот алгоритм послужит в дальнейшем базой для построения дерева вывода в 3 части курсовой работы.
3 Построение дерева вывода
3.1 Исходные данные
Программа выполняет лексический анализ входного, порождает таблицу лексем и выполняет синтаксический разбор текста по заданной грамматике с построением дерева разбора. Текст на входном языке задается в виде символьного (текстового) файла. Программа должна выдавать сообщения о наличие во входном тексте ошибок.
Лексический анализатор выделяет в тексте лексемы языка. Полученная после лексического анализа цепочка во второй части программы рассматриваться в соответствии с алгоритмом разбора. После построения цепочки вывода на ее основе строится дерево разбора.
Длину идентификаторов и строковых констант считать ограниченной 32 символами.
Исходная грамматика имеет вид:
S → prog L end.
L → O | L;O | L;
B→ B or C | C
C→ C and D | D
D → G | not D
G → E < E | E>E | E=E | (B)
K → G then O
M → K else O
Q → G do O
O → if M | if K| begin L end | while Q | c:=E
E → E-F | E+F | E++|
F → (E) | c | g
3.2 Синтаксический анализатор
Перед синтаксическим анализатором стоят две основные задачи: проверить правильность конструкций программы, которая представляется в виде уже выделенных слов входного языка, и преобразовать ее в вид, удобный для дальнейшей семантической (смысловой) обработки и генерации кода. Одним из таких способов представления является дерево синтаксического разбора.
Программирование работы недетерминированного МП-автомата - это сложная задача. Разработанный алгоритм, позволяет для произвольной КС-грамматики определить, принадлежит ли ей заданная входная цепочка (алгоритм Кока-Янгера-Касами).
Доказано, что время работы этого алгоритма пропорционально n3, гдеn– длина входной цепочки. Для однозначной КС-грамматики при использовании другого алгоритма (алгоритм Эрли) это время пропорциональноn2. Подобная зависимость делает эти алгоритмы требовательными к вычислительным ресурсам. На практике и не требуется анализ цепочки произвольного КС-языка – большинство конструкций языков программирования может быть отнесено в один из классов КС-языков, для которых разработаны алгоритмы разбора, линейно зависящие от длины входной цепочки.
КС-языки делятся на классы в соответствии со структурой правил их грамматик. В каждом из классов налагаются дополнительные ограничения на допустимые правила грамматики.
Одним из таких классов является класс грамматик предшествования. Они используются для синтаксического разбора цепочек с помощью алгоритма “сдвиг-свертка”. Выделяют следующие типы грамматик предшествования:
простого предшествования;
расширенного предшествования;
слабого предшествования;
смешанной стратегии предшествования;
операторного предшествования.