- •Упрощенная модель компилятора. Проходы компилятора.
- •3. Проходы компиляторов
- •Задача идентификации. Транслитерация.
- •Методы лексического анализа.
- •Использование автомата для решения задачи идентификации слов (различные классы лексем).
- •Контекстно-свободные грамматики. Основные определения.
- •Задание кс грамматики. Способы задания грамматик: синтаксические диаграммы, форма Бекуса-Наура.
- •Выводы. Деревья синтаксического разбора.
- •Праволинейная грамматика.
- •Лишние нетерминалы.
- •Атрибутные грамматики. Наследуемые и синтезируемые атрибуты.
- •1 Синтезируемые атрибуты
- •2 Наследуемые атрибуты
- •Использование автоматов с магазинной памятью для нисходящего разбора.
- •Общие правила построения нисходящего распознающего автомата.
- •Распознающий автомат для s - грамматик.
- •Ll(1) - грамматики. Множество выбора.
- •Метод рекурсивного спуска.
- •Обработка ошибок при нисходящем разборе.Обнаружение и нейтрализация ошибок.
- •Восходящие методы синтаксического разбора. Метод перенос-свертка.
- •Задачи семантического анализа. Семантические соглашения.
Ll(1) - грамматики. Множество выбора.
LL = Left Leftmost означает, что решение принимается по самому левому терминалу
(1) означает, что решение принимается только по одному терминалу.
LL(1)-грамматика:
<S> <A>b<B> {a,e,b,c}
<S> d {d}
<A> <C><A>b {a,e}
<A> <B> {c,b}
<B> c<S>d {c}
<B> ε {d,b, }
<C> a {a}
<C> ed {e}
Продуктивные нетерминалы: <C>, <B>, <S>, <A>
Достижимые нетерминалы: <S>, <A>, <B>, <C>
1. <A>
3 4
<C> <B>
7 8 4,6 4,5
a e b c
ПЕРВ(<A>) = {a,e,b,c}
b получаем таким образом:
пр.4: <A> <B>
пр.6: <B> ε
пр.1: <A> удаляется, остается b
3. ПЕРВ(<A>) = {a,e}
6.
ПЕРВ(ε) = {пустое множество}
СЛЕД(<B>) = {d,b, }
d: <B> c<S>d c<A>b<B>d
b: <S> <A>b<B> <B>b<B>
: на <B> может закончиться
ВЫБОР(пр.6) = ПЕРВ(ε) СЛЕД(<B>)
4. (такая ситуация не рекомендуется)
ПЕРВ(<B>) = {c}
СЛЕД(<A>) = {b}
ВЫБОР(пр.4) = ПЕРВ(<B>) СЛЕД(<A>)
Контекстно-свободная грамматика называется LL(1)-грамматикой тогда и только тогда, когда множества выбора правил с одинаковой левой частью не пересекаются.
Входные символы: {a,b,c,d,e, }
Магазинные символы: <S>, <A>, <B>, <C>, b, d,
|
a |
b |
c |
d |
e |
|
<S> |
#1 |
#1 |
#1 |
#2 |
#1 |
отвергнуть |
<A> |
#3 |
#4 |
#4 |
отвергнуть |
#3 |
отвергнуть |
<B> |
отвергнуть |
#6 |
#5 |
#6 |
отвергнуть |
#6 |
<C> |
#7 |
отвергнуть |
отвергнуть |
отвергнуть |
#8 |
отвергнуть |
b |
отвергнуть |
вытолкнуть, сдвиг |
отвергнуть |
отвергнуть |
отвергнуть |
отвергнуть |
d |
отвергнуть |
отвергнуть |
отвергнуть |
вытолкнуть, сдвиг |
отвергнуть |
отвергнуть |
|
отвергнуть |
отвергнуть |
отвергнуть |
отвергнуть |
отвергнуть |
допустить |
#1: Заменить(<B>b<A>), Держать
#2: Вытолкнуть, Сдвиг
#3: Заменить(b<A><C>), Держать
#4: Заменить(<B>), Держать
#5: Заменить(d<S>), Сдвиг
#6: Вытолкнуть, Держать
#7: Вытолкнуть, Сдвиг
#8: Заменить(d), Сдвиг
Метод рекурсивного спуска.
Основная идея: каждому нетерминальному символу грамматики соответствует процедура, которая распознает все цепочки, порождаемые этими нетерминалами. Процедуры вызывают друг друга в процессе синтаксического разбора. Если в правой части стоит нетерминал, который стоит в левой части, то процедура разбора может вызывать сама себя.
Пример: <A> <S>b<A> // хорошее правило
<A> <A>b<S> // плохое правило – эффект левой рекурсии, может потенциально привести к зацикливанию
Грамматика:
<S> a<A>{x}<S> {a}
<S> b{z} {b}
<A> c{y}<A><S>{V}b {c}
<A> {w} СЛЕД(<A>)={a,b}
Символы действия, которые обрамляют первое действие в правиле, не будут заноситься в магазин.
Пример: <S> {x}c{y}<A> - здесь {x} и {y} не попадут в магазин
3 нетерминала 3 процедуры:
PM (главная процедура) |
P<S> |
P<A> |
1. Вход=1-ая лексема цепочки 2. Вызов P<S> 3. Если Вход= , то Допустить иначе «Отвергнуть» |
1. Если Вход=a, то вызов P1 2. Если Вход=b, то вызов P2 3. Если Вход=c, то «Отвергнуть» 4. Если Вход= , то «Отвергнуть» 5. P1: Сдвиг, Вызов P<A>, Выполнить(x), Вызов P<S>, Возврат 6. P2: Сдвиг, Выполнить(z), Возврат |
1. Если Вход=a, то вызов P4 2. Если Вход=b, то вызов P4 3. Если Вход=c, то вызов P3 4. Если Вход= , то «Отвергнуть» 5. P3: Сдвиг, Выполнить(y), Вызов P<A>, Вызов P<S>, Выполнить(V), Проверить, Если Вход=b, то «Сдвиг» иначе «Отвергнуть», Возврат 6. P4: Выполнить(w), Возврат |
