Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3. Синтаксический и семантический анализ.pdf
Скачиваний:
31
Добавлен:
12.01.2020
Размер:
446.5 Кб
Скачать

Синтаксический и семантическийанализ

На этапе синтаксического анализа нужно установить, имеет ли строка лексем структуру, заданную синтаксисом языка, и зафиксировать эту структуру. Следовательно, надо решить задачу разбора: дана строка лексем, и надо определить, выводима ли она в грамматике, определяющейсинтаксис языка.

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

Известно, что существует алгоритм, который по любой КС-грамматике и данной строке выясняет, принадлежит ли строка языку, порождаемому этой грамматикой. Но время работы такого алгоритма синтаксического анализа экспоненциально зависит от длины строки, что с практической точки зрения неприемлемо.

Синтаксический и семантическийанализ

Существуют, так называемые, табличные методы анализа, применимые ко всему классу КС-грамматик и требующие для разбора строки длины n времени cn3

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

Алгоритмы анализа, расходующие на обработку входной строки линейное время, применимы только к некоторым подклассам КС-грамматик. Рассмотрим один из таких методов.

Метод рекурсивного спуска

Пусть дана грамматика G = ({S, A, B}, {a, b, c, }, S, P), где

P: S AB A a | cA B bA

Надо определить, принадлежит ли строка caba языку L(G). Построим вывод этой строки:

S AB cAB caB cabA caba

Следовательно, строка caba принадлежит языку L(G).

Последовательность применений правил вывода эквивалентна построению дерева вывода методом "сверхувниз":

Метод рекурсивного

Метод рекурсивного спуска

Метод рекурсивного спуска (РС-метод) реализует этот способ практически "в

лоб": для каждого нетерминала грамматики создается своя процедура, носящая его имя; ее задача – начиная с указанного места исходной строки найти подстроку, которая выводится из этого нетерминала.

Если такую подстроку считать не удается, то процедура завершает свою работу вызовом процедуры обработки ошибки, которая выдает сообщение о том, что строка не принадлежит языку, и останавливает разбор.

Если подстроку удалось найти, то работа процедуры считается нормально завершенной и осуществляется возврат в точкувызова.

Тело каждой такой процедуры пишется непосредственно по правилам вывода соответствующего нетерминала: для правой части каждой продукции осуществляется поиск подстроки, выводимой из этой правой части.

При этом терминалы распознаются самой процедурой, а нетерминалы соответствуют вызовам процедур, носящих их имена.

Метод рекурсивного спуска

Пример

Совокупность процедур рекурсивного спуска для грамматики G = ({S, A, B}, {a, b, c, }, S, P), где

P: S AB A a | cA B bA

будет такой:

#include <stdio.h> int c;

FILE fp; / указатель на файл, в котором находится анализируемая строка /

void A();