Архив3 / Kursach_po_SPO / Курсач по СПО / Курсач / Выбор и обоснование алгоритмов
.doc
3. Выбор и обоснование алгоритмов
Создание приложения - компилятора с подмножества языка Pascal сопровождается выполнением определенных этапов разбора. Это лексический, арифметический, синтаксический и семантический разборы входного и генерация кода выходного текста. Рассмотрим их подробнее.
3.1 Алгоритм лексического разбора
Формирование содержимого таблиц идентификаторов, литералов, терминалов - имеет место в начальной части программы, в процессе создания таблицы стандартных символов. Файл, содержащий исходный текст подмножества языка Pascal, читается построчно в цикле до признака конца файла. Далее происходит посимвольный анализ прочитанной строки и сбор лексем. Данный анализ предусматривает сбор комментариев, выделенных в начале строки знаком «{» и в конце строки «}». Естественно, что комментарии не играют ни какой роли при построении таблиц и транслировании исходного текста программы на язык Assembler. При получении признака необходимости наличия полученной лексемы в той или иной таблице (терминалов, литералов, идентификаторов, стандартных символов), лексема записывается в одну из них. Затем происходит вывод полученных таблиц на экран для наглядности и получения подробной информации о содержании вышеуказанных таблиц. Все эти процедуры проводятся с помощью специальных подпрограмм, которые проверяют наличие текущей собранной лексемы в соответствующих массивах. Если наличие подтвердилось, то процедуры просто пополняют таблицу стандартных символов, если нет – то происходит пополнение обоих таблиц.
3.2 Алгоритм синтаксического разбора
Синтаксический разбор осуществляется методом LL (Left Input Left Output) – разбора. Сначала необходимо составить грамматику языка.
После того, как мы преобразовали нашу грамматику в грамматику вида LL(k) можно осуществлять нисходящий LL – разбор.
Текущую сканируемую лексему часто называют текущим символом. Вначале текущий символ – это первая (самая левая) лексема входной строки.
Если текущий узел дерева разбора помечен терминалом и этот терминал совпадает с текущим символом, мы должны продвинуться как в дереве разбора, так и во входной строке. Как только в дереве рассматривается узел с нетерминалом, выполняют процедуру выбора продукции для этого не терминала. Все процедуры для не терминалов расписаны в грамматике, поэтому известно, по какой из веток нужно идти.
3.3 Алгоритм генерации ассемблерного кода
Транслятор выполняет генерацию результирующего кода поэтапно, на основе законченных синтаксических конструкций входной программы. Компилятор выделяет законченную синтаксическую конструкцию из текста исходной программы, порождает для нее фрагмент результирующего кода и помещает в текст результирующей программы. Затем он переходит к следующей синтаксической конструкции. Так продолжается до тех пор, пока не будет разобрана вся исходная программа. В качестве анализируемых законченных синтаксических конструкций выступают блоки операторов, описания процедур и функций. Чтобы транслятор мог построить код результирующей программы для синтаксической конструкции входного языка, часто используется метод, называемый синтаксически управляемым переводом — СУ-переводом.
Идея СУ-перевода основана на том, что синтаксис и семантика языка взаимосвязаны. Это значит, что смысл предложения языка зависит от синтаксической структуры этого предложения. Идея СУ-перевода заключается в том, что каждому правилу входного языка компилятора сопоставляется одно или несколько (или ни одного) правил выходного языка в соответствии с семантикой входных и выходных правил. То есть при сопоставлении надо выбирать правила выходного языка, которые несут тот же смысл, что и правила входного языка.