нисходящие распознаватели.ppt
- Количество слайдов: 22
1. Рекурсивный спуск - Основные положения - Пример - Достоинства и недостатки - Проблемы 2. Правила факторизации - Основные положения - Пример 3. Левая рекурсия - Леворекурсивность - Самолеворекурсивность - Основная идея избавления от левой рекурсии 4. LL(1) - грамматика - Основные положения - Условие LL(1)-грамматики - Пример 5. Правила построения LL(1) - Основные положения - Пример построения LL(1) - Схема разбора - Достоинства и недостатки Вопросы к лекции
Основные положения Процессор грамматического разбора, основанный на методе рекурсивного спуска, состоит из отдельных процедур. Процедура разбора старается во входном потоке найти подстроку, которая может быть интерпретирована, как правая часть правила для нетерминала, связанного с данной процедурой. В процессе работы она может вызывать другие подобные процедуры или даже рекурсивно саму себя, для поиска других нетерминальных символов. себя Если процедура находит соответствие нетерминальному символу, то она символу заканчивает свою работу, и передает в вызывающую ее программу признак успешного завершения и устанавливает указатель текущей лексемы на первый символ после распознанной подстроки. Иначе она заканчивается признаком неудачи, или же вызывает процедуру выдачи диагностического сообщения и процедуру восстановления.
--- демонстрация по щелчку мыши--- Пример Рассмотрим процедуру для оператора READ. Грамматика для оператора : READ(
Достоинства простота и скорость написания транслятора; соответствие грамматики и анализаторов. Это увеличивает вероятность правильности написания программы. Недостатки большое число вызовов процедур, отсюда относительно медленный анализатор; большой объем полученного анализатора; данный метод способствует включению в синтаксический анализ процедур семантического анализа и генерации кода. С одной стороны, это хорошо, так как оператор разбирается полностью в одном месте. А с другой стороны, это плохо, так как транслятор становится машинозависимым, и это делает его не мобильным.
Проблемы Первая проблема - сам по себе метод не исключает возвратов, т. е. для нетерминала, имеющего несколько правых частей, приходится решать, какую альтернативу необходимо выбрать.
Основные положения Правила факторизации (левой факторизации) заключаются в том, что общие части грамматических правил выносятся за скобку. Эти правила называют также и “вынесением левого множителя”. Принцип левой факторизации можно выразить в символической форме следующим образом: если грамматика содержит n правил . . . n где - нетерминал, а и i для 1 i n - цепочки нетерминалов и терминалов, то эти правила можно заменить на следующие n+1 правила: <В> . . . n где <В>- нетерминальный символ, не входящий в исходную грамматику. Грамматика, полученная такой заменой, порождает тот же язык, что и исходная грамматика, и о ней говорят, что она получена левой факторизацией.
Пример Рассмотрим грамматику с правилами: A BCD A axy A аxz заменяем Применим к данной грамматике правила левой факторизации. A BCM A ax. N M M D N y N z
Леворекурсивность Нетерминал называется леворекурсивным, если, применяя к нему одно или более леворекурсивным правил, можно вывести цепочку, начинающуюся этим же нетерминалом. Правило называется леворекурсивным, если оно используется на первом шаге леворекурсивным такого вывода. Пример леворекурсивности, но не самолеворекурсивности показан в следующих правилах: 1. a 2. b 3. c 4. d Нетерминалы и леворекурсивны, правила 1 и 4 не леворекурсивны
Самолеворекурсивность Правило называется самолеворекурсивным, если его первый символ правой части и самолеворекурсивным левая часть – это один и тот же символ. Такое правило должно быть также и леворекурсивным, так как его правая часть сама является цепочкой, начинающейся с левой части, и требуемый вывод состоит из 0 шагов. Самолеворекурсивность иллюстрируется правилом 1, приведенном ниже. 1. a 2. b где является первым символом правой части и левой частью.
Идея избавления от левой рекурсии Грамматику с левой рекурсивностью всегда можно переделать в грамматику с правой рекурсией. Основная идея при этом состоит в том, чтобы смотреть на рекурсивный нетерминал как на порождающий некоторую цепочку, за которой следует список из одного или более элементов. Например: i (1 i n) j (1 j m) j i Заменим левосторонюю рекурсию на правосторонюю, применив приведенное выше преобразование. Получим следующие правила, не содержащие левосторонней рекурсии:
Основные положения Название “LL(1)” объясняется тем, что автомат начинает просматривать входную цепочку слева (Left) и обнаруживает появление правила по самому левому (Leftmost) символу цепочки, выводимой из этого правила, причем это решение принимается по одному текущему символу. Например: IF THEN ELSE Эта грамматика не может быть LL(1) грамматикой, так как с IF начинаются обе альтернативы. Применив факторизацию получим: IF THEN <нечто> ELSE <нечто> ε где <нечто> - это новый нетерминал, который в грамматике больше нигде не встречается.
Условие LL(1)-грамматики Для каждого нетерминала и его альтернативы определяем множество терминальных символов, с которых может начинаться цепочка, выводимая из данного нетерминала по данной альтернативе. Это множество терминальных символов называется множеством символов предшественников Например: A α | P(A, α) – множество терминальных символов, с которых может начинаться цепочка, выводимая по альтернативе α; т. е. P(A, α) FIRST+ для А P(A, ) – множество терминальных символов, с которых может начинаться цепочка, выводимая по альтернативе правила А; т. е. P(A, ) FIRST+ для А Необходимым условием того, что грамматика обладает свойством LL(1) является непересекаемость множества символов предшественников для альтернатив каждого правила. Далее продолжение
--- демонстрация по щелчку мыши--- Например Рассмотрим грамматику : Е G T U F TG +TG | FU *FU | (E) | Так как слева терминал (+) – вносим его в После G множество в правиле конец направляющее Так как из предложения. G выводится е (пустое , ┴ищем вносим в e множество), вхождение направляющее множество, но т. к. Gданного нетерминала в правых – входит в Е, ищем где После Е в правилах Е e встречается терминал частях других правил вносим в направляющее id множество ) Нетерминал G имеет две альтернативы. Направляющее множество: для (G, +TG) -> {+} для (G, e) -> { ), ┴} end
Основные положения Для каждого нетерминального символа, находящегося в левой части строится строка таблицы, в которую вносится имя нетерминала, множество направляющих символов для этого нетерминала и указатель на группу строк соответствующей правой части правила. Если нетерминал имеет несколько альтернатив, то для него строятся соответствующие альтернативам строки, в каждую вносится имя нетерминала, множество направляющих символов для этого нетерминала и альтернативы, указатель на группу строк соответствующей альтернативы. Каждому элементу из правой части отводится строка таблиц: Если символ терминальный, то в строку вносится символ, и указатель на следующую строку таблицы, если символ не последний в альтернативе, иначе указателю присваивается нулевое значение. Для нетерминала правой части строится строка таблицы, в которую вносится имя нетерминала, множество направляющих символов для этого нетерминала и указатель на строку, помеченную этим нетерминалом для левой части правила. Для пустого символа тоже создается строка, в которую вносится пустой символ, множество направляющих символов и указателю присваивается нулевое значение.
--- демонстрация по щелчку мыши--- Пример построения LL(1) < PROG > < VAR > 20 NULL 21 19 24 NULL 25 st
--- демонстрация по щелчку мыши--- Схема разбора Стек: PROG Shik VAR a , b begin st END 1
Достоинства распознавателей, основанных на LL(1) грамматике. в отличие от рекурсивного спуска в методе нет возвратов. Это детерменированный метод; время разбора пропорционально длине входной программы; имеются хорошие диагностические характеристики, и существует возможность исправления ошибок, так как распознавание ведется по одному символу; таблица разбора меньше, чем соответствующая таблица разбора в других методах. Недостатки распознавателей, основанных на LL(1) грамматиках относится то, что не все классы языков описываются LL(1) грамматиками.
КУРС ЛЕКЦИЙ ПО ТЯП Условие LL(1)-грамматики Если из нетерминала А выводится пустое множество: А -> ε В этом случае рассматривается множество отношения FOLLOW для А, т. е. все терминальные символы, которые могут следовать за А в правых частях правила грамматики. Введем определение направляющего множества символов для нетерминала и альтернативы N(A, α)={ P(A, α) для α-> *ε FOLLOW A для α-> *ε } Необходимым условием того, что грамматика обладает свойством LL(1) является непересекаемость направляющих множеств символов для альтернатив каждого правила. К началу LL(1)-грамматикой называется КС-грамматика, если для любого КС-грамматика правила, имеющего альтернативы, направляющие множества альтернативы не пересекаются.
КУРС ЛЕКЦИЙ ПО ТЯП Схема разбора Обработка строк таблицы LL(1): Для левой части правила: проверка входного символа на попадание в направляющее множество данного нетерминала и переход по указателям в случае, если входной символ совпадает с одним из направляющих символов. В противном случае – ошибка (error). Для терминала: проверка на совпадение входного символа с терминальным, если нет, то – ошибка (error); сдвиг по входной цепочке; переход по указателю, если указатель имеет нулевое значение, то переход по адресу, находящемуся в верхушке стека. Для нетерминала: проверка входного символа на совпадение с одним из символов направляющего множества; в стек заносится адрес следующей строки, соответствующей следующему за нетерминалом символу правой части правила. Если такого символа нет, т. е. символ последний во входной цепочке, то в стек ничего не заносится; переход по указателю.
КУРС ЛЕКЦИЙ ПО ТЯП Схема разбора Обработка строк таблицы LL(1): Для пустого символа: проверка входного символа на совпадение с одним из символов направляющего множества; переход по указателю, находящемуся в верхушке стека. Для левой части правила, имеющей несколько альтернатив: входной символ проверяется на вхождение в направляющее множество сначала первой альтернативы; если входной символ не входит в это направляющее множество, то переход на следующую строчку, соответствующей следующей альтернативе и т. д. ; если входной символ не входит в направляющее множество последней альтернативы, тогда ошибка (error); если входной символ совпал с одним из символов направляющего множества одной из альтернатив, то переход по указателю соответствующей строки.
КУРС ЛЕКЦИЙ ПО ТЯП Схема разбора Модификация LL(1)-таблицы: Модификация LL(1)-таблицы производится в ходе ее обработки. Основные поля новой таблицы: номер строки, направляющее множество (для каждого символа), сдвиг по входной цепочке (есть он или нет), переход (номер строки, на который происходит переход), стек (вносится адрес строки символа), ошибка (необходима для определения перехода по альтернативе), конечное состояние (конец разбираемой цепочки). № направляющее 1 2 множество PROG сдвиг нет да переход стек ошибка 2 3 нет да да конечное состояние нет Алгоритм заканчивается успешно, если входная цепочка разобрана и признана принадлежащей разбираемому языку, если стек пустой, входной символ соответствует концу цепочки и разбор заканчивается на строке, соответствующей конечному состоянию. В противном случае разбор заканчивается с сообщением об ошибке.
КУРС ЛЕКЦИЙ ПО ТЯП 1. 2. 3. 4. 5. 6. Основные достоинства и недостатки рекурсивного спуска. Озвучьте правило факторизации. Какой нетерминал можно назвать леворекурсивным. Какое правило называют самолевокурсивным. Какую грамматику называют LL(1) грамматикой. Достоинства и недостатки распознавателей, основанных на LL(1) грамматике.


