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

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

Пример 1.

Грамматика:

  1. <S> a<A><B>c

  2. <S> ε

  3. <A> c<S><A>

  4. <A> <A>b

  5. <B> b<B>

  6. <B> a

Цепочка: acabac

Вывод: <S> a<A><B>c ac<S><A><B>c ac<A><B>c

Цепочка не является корректной, т.к. ее нельзя вывести из данной грамматики

Пример 2.

Грамматика:

  1. <S> a<A><B>c

  2. <S> ε

  3. <A> c<S><B>

  4. <A> <A>b

  5. <B> b<B>

  6. <B> a

Цепочка: acabac

Вывод: <S> a<A><B>c ac<S><B><B>c ac<B><B>c aca<B>c

acab<B>c acabac

Цепочка является корректной в данной грамматике.

Дерево – граф, у которого нет циклов и петель.

Дерево синтаксического разбора:

<S>

1

a<A><B>c

3 5

c<S><B> b<B>

2 6 6

ε a a

Выписываем листья в порядке слева сверху вниз: acabac

Можно получить и другое дерево:

<S>

a<A><B>c

<A>b a

c<S><B>

ε a

При его обходе получаем все ту же цепочку: acabac.

оба дерева дают корректные цепочки, а это плохо, т.к. грамматика неоднозначна.

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

  1. Праволинейная грамматика.

Праволинейная – если правая часть каждого правила содержит не более одного нетерминального символа, и этот является самым правым символом правила.

Грамматика называется праволинейной, если она содержит только правила вида А→а, А→аВ.

Преобразование в праволинейную грамматику:

Пример 1

Пример 2

Задана грамматика:

  1. <S> a<A>

  2. <S> bc

  3. <S> <A>

  4. <A> abb<S>

  5. <A> c<A>

  6. <A> ε

Задача: построить автомат.

2,3,4 правила нуждаются в преобразовании.

2. . Обозначение «ε» тут несущественно. Можно записать любой символ.

4.

3. - здесь просто переписываем все случаи чему равно <A>

В результате получаем следующую грамматику:

  1. <S> a<B>

  2. <S> b<cε>

  3. <cε> c<ε>

  4. <ε> ε

  5. <S> a<bbS>

  6. <bbS> b<bS>

  7. <bS> b<S>

  8. <S> c<A>

  9. <S> ε

  10. <A> a<bbS>

  11. <A> c<A>

  12. <A> ε

Что можно записать следующей таблицей:

a

b

c

<S>

<A>,<bbS> - недетерминированность

<cε>

<A>

допустимо

<cε>

-

-

<ε>

-

<ε>

-

-

-

допустимо

<bbS>

-

<bs>

-

-

<A>

<bbS>

-

<A>

допустимо

<bs>

-

<S>

-

-

  1. Лишние нетерминалы.

Пример 1.

  1. <S> a<S>a

  2. <S> b<A>d

  3. <S> c

  4. <A> c<B>d

  5. <A> a<A>d

  6. <B> d<A>f

Проблема заключается в зацикливании между <A> и <B>.

Бесплодные (мертвые) нетерминалы – нетерминалы, которые не порождают ни одной терминальной цепочки.

Свойство 1. Если все символы правой части правила продуктивны, то продуктивны и символы в левой части.

<S> - продуктивный («плодовитый») символ

<A>,<B> - не продуктивные символы

Алгоритм проверки на продуктивность:

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

  2. Если найдено такое правило, то в список продуктивных терминалов заносится нетерминал, который стоит в левой части

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

заносится в список продуктивностей.

  1. Повторяем эту операцию до тех пор, пока не будут проверены все правила грамматики. Если после проверки правил остались какие-то нетерминалы, которые не занесены в список продуктивных являются бесплодными (мертвыми).

Пример 2.

  1. <S> a<S>b

  2. <S> c

  3. <A> b<S>

  4. <A> a

<A> является недостижимым терминалом. Нетерминал, который не появится ни в одной цепочке, которая выводится со стартового терминала называется недостижимым.

Свойство 2. Если нетерминал в левой части правила является достижимым, то достижимы все символы в правой части.

Алгоритм проверки на достижимость:

  1. Образовать список достижимых терминалов, внеся в него стартовый терминал

  2. Если найдено правило, левая часть которого уже имеется в списке, то включить в список нетерминалы, имеющиеся в правой части

  3. Если на шаге 2 список не пополняется новыми нетерминалами, то получен список всех достижимых нетерминалов. Нетерминалы, не попавшие в него считаются недостижимыми

  1. Транслирующие грамматики. Перевод в польскую запись c использованием транслирующих грамматик.

Кс грамматика с символами действия - транслирующая

Лукасевич в 30-е гг. XX века предложил польскую запись (постфиксная и инфиксная форма записи).

Постфиксная запись: (a+b)*c ab+c*; -a+b a-b+

Грамматика, позволяющая формировать выражения в польской записи:

  1. <операнд> <операнд><операнд>+

  2. <операнд> <операнд><операнд>*

  3. <операнд> I

Грамматика перевода (арифметических выражений):

  1. <E> <E>+<T>{+}

  2. <E> <T>

  3. <T> <T>*<P>{*}

  4. <T> <P>

  5. <P> (<E>)

  6. <P> a{a}

  7. <P> b{b}

  8. <P> c{c}

Символы, находящиеся в фигурных скобках { } называются символами действия. Они описывают процедуры, которые должны выполняться в этом месте.

Нетерминальными символами здесь являются все символы, стоящие в < >. А терминальными: a,b,c,+,*.

Сокращения: E – expression, T – term, P – prefix.

Словарь: {+,*,(,),a,b,c}

Пример: ((a+b*c)+a)

<E>

<T>

<P>

(<E>)

<E>+<T> {+}

<T> <P>

<P> a {a}

(<E>)

<E>+<T> {+}

<T> <T>*<P> {*}

<P> <P> с {c}

a {a} b{b}

При обходе символов действия получаем: {a}{b}{c}{*}{+}{a}{+}

a bc* + a+

Вывод: перед нами транслирующая грамматика. Ее отличительная сторона: кроме терминальных и нетерминальных символов имеются символы действия. Проделанная операция называется переводом. С помощью грамматики мы можем произвести перевод.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]