Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и преобразования.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
89.6 Кб
Скачать

Получение множества посл (Last).

Множество ПОСЛ рассматривается для термов и правил. Неформально это множество представляет собой набор терминалов, которыми могут заканчиваться все сентенциальные формы, выводимые их терма A (для терма). Для правила это множество термов, которыми может заканчиваться цепочка выводимая из правой части правила.

Формально множество ПОСЛ(A) для терма определяется так:

ПОСЛ(A) = { a | a in Vt, A=>wa }

Для правила множество ПОСЛ(R) определяется похожим образом:

ПОСЛ(R) = { a | a in Vt, R=>wa }

Для получения этого множества используются объекты класса getLast.

FormalGrammar::ptr a_fg = new FormalGrammar(a_fileName); cout<<"FG "<<a_fg->toString(); getLast a_gl(a_fg); SetOfTerms::ptr a_st = p_gl(a_fg->getStartSymbol()); cout<<"Last(S)="<<a_st->toString();

Получение множества След (Follow).

Множество СЛЕД рассматривается для термов. Неформально это множество представляет собой набор термов, которые могут встретиться следом за термом A в какой-нибудь сентенциальной форме.

Формально множество СЛЕД(A) для терма определяется так:

СЛЕД(A) = { a | a in Vt, S=>wAv, a in ПЕРВ(v) }

Для получения этого множества используются объекты класса getFollow.

FormalGrammar::ptr a_fg = new FormalGrammar(a_fileName); cout<<"FG "<<a_fg->toString(); getFollow a_gf(a_fg); SetOfTerms::ptr a_st = p_gf(a_fg->getStartSymbol()); cout<<"Follow(S)="<<a_st->toString();

ЛЛ1-грамматики

ЛЛ1 грамматики являются одними из самых простых грамматик с точки зрения сложности разбора. Однако очень много языковых конструкций могут быть описаны с их помощью. Анализ для ЛЛ1 грамматик интуитивно понятен и не требует сложных объяснений.

Анализ ЛЛ1 грамматик строит дерево разбора сверху вниз и называется нисходящим. Это означает, что алгоритм пытается сначала построить верхушку синтаксического дерева, спускаясь постепенно к листьям.

Неформально можно так описать ЛЛ1 грамматики. Грамматика, для которой на каждом шаге разбора можно сделать вывод о том, какое правило следует применить, зная лишь первый символ не прочитанной части входной цепочки называется ЛЛ1 грамматикой.

Это определение можно пояснить, рассмотрев алгоритм разбора ЛЛ1 грамматик. Для анализа цепочки используется стек, в который помещают символы из полного словаря грамматики. Начальная конфигурация анализатора подразумевает, что в стеке находится лишь стартовый символ грамматики. Зная первый символ входной цепочки мы сразу должны определить, чем мы заменим верхний символ в стеке (т.е. правой частью какого правила мы заменим символ S в стеке). Сразу становится ясно, что если в грамматике два правила S::=a w и S::=a v и входная цепочка начинается символом a, то мы не сможем определить, каким правилом в стеке заменить начальный символ.

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