Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бАКАЛАВР_РАБОТА.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.13 Mб
Скачать

4.3.3 Модифицированныйметодразбора

После того как мы расширили грамматику добавлением нетерминалов, указывающих семантические действия, можно выполнять трансляцию непосредственно в процессе синтаксического анализа путём добавления дополнительного стека, для хранения частей уже созданного синтаксического дерева, ирасширения стека синтаксического анализатора таким образом, чтобы он хранил семантические действия[1].

Семантические действия заключаются в снятии, если необходимо, с вершины семантического стека узлов – составляющих, и в создании нового узла и помещении его на вершину стека. Все семантические действия выполняются, когда на вершине стека синтаксического анализатора оказываются соответствующие им нетерминалы. Таким образом,к моменту снятия со стека последнего символа тела выводимой продукции, все дочерние узлы узла заголовка этой продукции будут находиться на вершине семантического стекев обратном порядке (справа налево).

Модифицированный алгоритм разбора представлен на рис. 4.8.Входными данными для модифицированного алгоритма также служит входной поток токенов и таблица синтаксического анализа M, выходными данными – построенное синтаксическое дерево, иначе сообщение об ошибке. Изначально стартовый символ грамматики Programнаходится на вершине стека. В случае обнаружении хотя бы одной синтаксической ошибки, семантические действия игнорируются.

Рисунок 4.8 ­– Модифицированный алгоритм предиктивного синтаксического анализа

4.3.4 Семантический анализ. Таблица символов

После стадии синтаксического анализа, на выходе которой будет построенное абстрактное синтаксическое дерево, будет идти непосредственно стадия семантического анализа.Эту стадию также называют статическим анализом, так как она ищет только те ошибки, которые непосредственно вытекают из входной программы, в отличие от динамического анализа, который анализирует программу во время её выполнения.

Статический анализ семантических соглашений может сообщить об ошибке, которая была не обнаружена на ранних стадиях языкового процессора. Это вызвано тем, что некоторые особенности входного языка являются контекстно-чувствительными (не контекстно-свободными).

Выделены следующие виды семантических проверок:

  1. корректность типаоперанда в операторе или операции, напримерпеременной при индексации и т.п.

  2. уникальность идентификаторов;

  3. отсутствие необъявленных идентификаторов;

  4. специфические проверки, например полнота системы уравнений и др.

Таким образом, семантический анализ преследует две цели. Первая – это, конечно, семантическая корректность. Вторая цель – это подготовить абстрактное синтаксическое дерево к стадии кода генерации. Поэтому в ходе семантического анализа создаётся таблица символов, в которую записывается информация об идентификаторах, используемых в программе. Далее эта информация используется при проверках корректности типа и при генерации выходной программы.

Прежде чем рассматривать алгоритм построения таблицы опишем её структуру. Таблица символов представляет ассоциативный массив. Ключевым полем является имя идентификатора, а полем данных –тип программного объекта, обозначаемого этим идентификатором.

В программе выделено семь основных типов объектов:

  1. массивы (ArrayType)

  2. переменные (VarType)

  3. счётчики (CountType)

  4. вещественные константы (ConstFloatType)

  5. целочисленные константы (ConstIntType)

  6. макро определение (MacroType)

  7. макро определение с параметром (MacroIndexType)

На рис. 4.9 приведена иерархия классов представляющих типы объектов с обозначением их элементов данных, где ObjType это абстрактный класс, от которого унаследованы все остальные классы.

Рисунок 4.9 – Иерархия классов представляющих типы программных объектов

Как видно из рисунка помимо просто указания типа объекта в этих структурах данных хранятся дополнительная информация, связанная с программным объектом, например в типе массива хранится его размер(size) и число(first), с которого начинается нумерация элементов (по умолчанию равное единице).

В методах для работы с таблицей символов реализованы семантические проверки: на уникальность идентификатора при вставке нового элемента в таблицу и на необъявленные идентификаторы при поиске в таблице по ключу.

На рис. 4.10 представлен алгоритм построения таблицы символов. Входными данными является указатель на корневой узел синтаксического дерева, а выходными – построенная таблица символов, либо сообщение об ошибке.

Рисунок 4.10 – Алгоритм построения таблицы символов

Продолжение рисунка 4.10

Продолжение рисунка 4.10

При построении алгоритма учитывались следующие соглашения по структуре языка:

  1. константа может быть декларирована не явно, т.е. без указания ключевого словаconst. Таким образом, задание ГНУ без индекса пересекается с неявным определением константы;

  2. объявление переменных уравнения не обязательно, поэтому алгоритм должен с начало просмотреть все левые части уравнений и, если какая-нибудь переменная отсутствует в таблице символов, то добавить её;

  3. В левой части уравнений без индексов может стоять только идентификатор типа VarType.В левой части уравнений с индексами может стоять только идентификатор типа ArrayType.;

Поэтому алгоритм с начало добавляет в таблицу символы по мере разрешения противоречий. В первую очередь добавляются все идентификаторы, тип которых очевидно следует из их объявления. К таким идентификаторам относятся макро определения, явно определённые константы,массивы, счётчики. Далее алгоритм просматривает все левые части уравнений в программе и, если переменная отсутствует в таблице символов, то добавляет её, иначе проверяет на соответствие типу. Заключительной стадией является проход по операторам, отвечающим как за задание ГНУ, так и за определение константы. К этому моменту времени в таблице символов находятся уже все переменные, поэтому определение типа идентификатора однозначно: если он отсутствует в таблице символов, то относим его к константному типу.

К концу построения таблицы символов собрана вся информация об идентификаторах, она потребуется при последующих проверках на корректностьтипов переменных операторам.