Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебные пособия / ТЯПиМТ / Методические указания к л.р..doc
Скачиваний:
80
Добавлен:
02.04.2015
Размер:
348.16 Кб
Скачать

1.2.2. Cинтаксический анализ для ll(1)-грамматики

Алгоритм синтаксического анализа на основе LL(k)-грамматики относится к классу алгоритмов нисходящего разбора. Строкам управляющей таблицы М для грамматики G(V,T,P,S) ставятся в соответствие элементы множества {VT$} ($-маркер дна стека), столбцам – элементы множества {T$}($ - маркер правого конца строки). Перед началом работы алгоритма в рабочий стек заносятся символы $ и S. Возможные значения элементов таблицы и их интерпретация алгоритмом разбора приведены в таблице 1.

Таблица 1

Значение элемента управляющей таблицы

Интерпретация алгоритмом разбора

Номер n порождающего правила грамматики

Удаление символа из рабочего стека; запись этого символа в выходной стек; запись правой части правила номер n в рабочий стек справа налево, начиная с последнего символа; запись n в выходную ленту

«выброс»

Удаление символа из рабочего стека, запись его в выходной стек; считывание следующего символа входной строки

«допуск»

Входная строка разобрана. Конец работы

«ошибка»

Входная строка ошибочна. Конец работы

Для построения управляющей таблицы М по заданной LL(1)-грамматике G(V,T,P,S) можно воспользоваться следующим алгоритмом.

1.Если <A>::=r – правило номер n заданной грамматики, то M(<A>,a)=n для всех a, являющихся терминальными префиксами цепочек, выводимых из r. Если r – пустая строка (для ее обозначения будем использовать символ Λ), то М(<A>,b)= n для всех b, являющихся терминальными символами, которые могут встречаться непосредственно справа от <A>, т.е. символов-следователей для нетерминала <A>.

2.M(a,a)= «сдвиг» для всех a, принадлежащих Т.

3.M($,$)= «допуск».

4.Оставшиеся незаполненными элементы таблицы М получают значение «ошибка».

Для грамматики, обладающей свойством LL(1), терминальные префиксы цепочек, выводимых из альтернативных правых частей правил для одного нетерминала, и символы-следователи этого же нетерминала должны быть различны. При построении управляющей таблицы это является гарантией того, что в одну клетку таблицы помещается не более одного правила грамматики в соответствии с п.1 алгоритма. В некоторых случаях не LL(1)-грамматика может быть преобразована к виду LL(1). Так например, два или более правил для одного нетерминала, имеющие одинаковые начальные символы, могут быть объединены в одно правило по следующей схеме.

До преобразования:

<A>::=aα|aβ| Λ

После преобразования:

<A>::=a<Z>| Λ

<Z>::=α|β

Еще одним приемом, позволяющим привести грамматику к виду LL(1), является устранение левой рекурсии по следующей схеме.

До преобразования:

<A>::=<A>α|a

После преобразования:

<A>::=a<Z>

<Z>::=α<Z>| Λ

Пример.

Грамматика G(V,T,P,S) рассмотренного в п.1.2.1 примера не обладает свойством LL(1), поскольку обе правые части для нетерминала <E> (правила 2 и 3) порождают цепочки, начинающиеся одним и тем же терминалом i. То же можно сказать и о правилах для нетерминала <T>. Преобразуем грамматику G(V,T,P,S) к грамматике G1(V1,T,P1,S), обладающей свойством LL(1).Правила последней примут вид:

1) <S>::=<E>

2) <E>::=<T><X>

3) <X>::=+<E>

4) <T>::=<F><Y>

5) <Y>::=*<T>

6) <F>::=i

7) <X>::=Λ

8) <Y>::=Λ

В соответствии с приведенным алгоритмом теперь можно построить управляющую таблицу для LL(1)-анализатора:

i

+

*

$

<S>

1

<E>

2

<T>

4

<F>

6

<X>

3

7

<Y>

8

5

8

i

сдвиг

+

сдвиг

*

сдвиг

$

допуск

Незаполненные элементы таблицы имеют значение "ошибка".

Проанализируем входную цепочку i*i с помощью алгоритма LL(1)-анализатора. При этом, для облегчения формирования выходного стека, при записи символа в рабочий стек будем снабжать его указателем на символ, являющийся его предком в синтаксическом дереве разбора. Процесс анализа проиллюстрируем таблицей :

Рабочий стек

Вх. символ

М(А,а)

<S>.0

$

I

M(<S>,i)=1

<E>,1

$

I

M(<E>,i)=2

<T>,2

<X>,2

$

I

M(<T>,i)=4

<F>,3

<Y>,3

<X>,2

$

i

M(<F>,i)=6

i,4

<Y>,3

<X>,2

$

i

M(i,i)= «сдвиг»

<Y>,3

<X>,2

$

*

M(<Y>,*)=5

*,6

<T>,6

<X>,2

$

*

M(*,*)= «сдвиг»

<T>,6

<X>,2

$

i

M(<T>,i)=4

<F>,8

<Y>,8

<X>,2

$

i

M(<F>,i)=6

i,9

<Y>,8

<X>,2

$

i

M(i,i)= «сдвиг»

<Y>,8

<X>,2

$

$

M(<Y>,$)=8

<X>,2

$

$

M(<X>,$)=7

$

$

M($,$)=«допуск»

В результате анализа получено синтаксическое дерево разбора:

<S>

┌─<E>─┐

┌<T>┐ <X>

<F> ┌<Y>┐ │

│ * │ Λ

i ┌<T>┐

<F> <Y>

│ │

i Λ

В выходном стеке это дерево представляется в виде:

12

<X>

2

11

<Y>

8

10

i

9

9

<F>

8

8

<T>

6

7

*

6

6

<Y>

3

5

i

4

4

<F>

3

3

<T>

2

2

<E>

1

1

<S>

0

Последовательность номеров примененных правил (левый разбор): 124654687.

Соседние файлы в папке ТЯПиМТ