Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Рекурсивный спуск с возвратами

Алгоритм устранения леворекурсивности

Леворекурсивные грамматики

LL(k)-свойство накладывает большие ограничения на грамматику. Иногда имеется возможность преобразовать грамматику так, чтобы получившаяся грамматика обладала свойством LL(1). Такое преобразование далеко не всегда удается, но если удалось получить LL(1)-грамматику, то для построения анализатора можно использовать метод рекурсивного спуска без возвратов.

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

E → E + T | E – T | T

T → T * F | T / F | F

F → num | (E)

Терминалы множества FIRST(T) принадлежат также множеству FIRST(E+T), поэтому нельзя однозначно определить последовательность вызовов процедур, которую необходимо выполнить при анализе входной цепочки. Проблема заключается в том, что нетерминал E встречается на первой позиции правой части правила, левая часть которого также E. В такой ситуации нетерминал E называется непосредственно леворекурсивным.

Нетерминал A КС-грамматики G называется леворекурсивным, если в грамматике существует вывод A =>* Aw.

Грамматика, имеющая хотя бы одно леворекурсивное правило, не может быть LL(1) -грамматикой.

С другой стороны, известно, что каждый КС-язык определяется хотя бы одной нелеворекурсивной грамматикой.

Пусть G = (N, T, P, S) – КС-грамматика и правило A→Aw1 | Aw2 | … | Awn | v1 | v2 | … | vm представляет собой все правила из P, содержащие A в левой части, причем ни одна из цепочек vi не начинается с нетерминала A.

Добавим к множеству N еще один нетерминал A' и заменим правила, содержащие A в левой части, на следующие:

A → v1 | v2 | … | vm | v1A’ | v2 A’ | … | vm A'

A’ → w1 | w2 | … | wn | w1 A’ | w2 A’ | … | wn A'

Можно доказать, что полученная грамматика эквивалентна исходной.

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

E → T | TE'

E' → +T | +TE'

T → F | FT'

T'→ *F | *FT'

F → (E) | num

Нетрудно показать, что получившаяся грамматика обладает свойством LL(1).

Еще одна подобная проблема связана с тем, что два правила для одного и того же нетерминала начинаются одними и теми же символами.

Например,

S → if E then S else S

S → if E then S

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

S → if E then S S’

S' →

S'→ else S

Для полученной грамматики может быть реализован метод рекурсивного спуска.

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

Для этого лексический анализатор представляется в виде объекта, у которого помимо традиционных методов scan, next и т. д., есть также копирующий конструктор. Затем во всех ситуациях, где может возникнуть неоднозначность, перед началом разбора надо запомнить текущее состояние лексического анализатора (т. е. сделать копию лексического анализатора) и продолжить разбор текста, считая, что имеем дело с первой из возможных в данной ситуации конструкций. Если этот вариант разбора заканчивается неудачей, то надо восстановить состояние лексического анализатора и пытаться заново разобрать тот же самый фрагмент с помощью следующего варианта грамматики и т. д. Если все варианты разбора заканчиваются неудачно, то сообщается об ошибке.

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

<== предыдущая лекция | следующая лекция ==>
Ll(k)-грамматика | LR(k)-анализатор означает, что
Поделиться с друзьями:


Дата добавления: 2014-01-11; Просмотров: 1218; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.013 сек.