
- •1.2.1. Первичные понятия
- •1.2.2. Примеры, иллюстрирующие первичные понятия
- •1.2.3. Пустой язык
- •1.3.1. Грамматики типа 0
- •1.3.2. Грамматики типа 1
- •1.3.3. Грамматики типа 2
- •1.3.4. Грамматики типа 3
- •1.3.5. Вывод в кс-грамматиках и правила построения дерева вывода
- •1.3.7. Левый и правый выводы
- •1.5.1. Рекомендации по построению грамматик
- •Лексический анализатор должен читать символы из входного файла, строить записи, называемые токенами, и передавать их синтаксическому анализатору, как это показано на рисунке 6.1.
- •3.5. Функции перв, след и выбор.
- •5.4. Атрибутные преобразователи ( ап )
- •5.4.1. Представление правил lat-грамматики в магазине.
- •5.4.2. Построение инструкций ап.
1.3.7. Левый и правый выводы
Среди всевозможных выводов наибольший интерес представляют следующие два типа выводов.
Определение. Если при построении вывода цепочки при каждом применении правила заменяется самый левый нетерминальный символ, то такой вывод называется левым или левосторонним выводом . Если при построении вывода , всегда заменяется самый правый нетерминальный символ промежуточной цепочки, то вывод называется правым или правосторонним выводом . |
Например, приведенный выше вывод цепочки i * i + i в грамматике Г1. 9 является левосторонним выводом. Следует отметить, что различным выводам цепочки i+i в грамматике Г1. 9 соответствует одно и то же синтаксическое дерево.
Определение. Цепочка языка L(Г) называется неоднозначной, если для её вывода существует более чем одно синтаксическое дерево. Если грамматика Г порождает неоднозначную цепочку, то она называется неоднозначной.
5. Преобразование грамматик. Необходимость преобразований.
В принципе еще 7-10 билеты все преобразования, возможно, нужны вкратце.
При построении грамматик, задающих конструкции языков программирования, часто приходится прибегать к их преобразованию, чтобы порождаемый язык приобрел нужную структуру.
Преобразование КС-грамматик
Исключение леворекурсивных правил. Определение. Правило вида <A> <A> , где A VA , (Vт VA) * , называется праворекурсивным, а правило вида <A> <A> - леворекурсивным. |
Утверждение. Для каждой КС-грамматики Г, содержащей леворекурсивные правила, можно построить эквивалентную грамматику Г', не содержащую леворекурсивных правил. |
Способ построения эквивалентной грамматики заключается в следующем. Допустим, что исходная грамматика Г содержит правила: <A> <A> 1 | <A> 2 | ... |<A> m| , где ни одна цепочка не начинается с <A> и (Vт VA) * . Введем новый нетерминал <A'> и преобразуем правила так:
<A> 1 | 2 |...| n | 1<A'> | 2<A'>|...| n<A'>, <A'> 1 | 2 |...| m| 1<A'> | 2<A'>|...| m<A'>.
Заменяя все правила с левой рекурсией в Г описанным способом, получим грамматику Г', причем L(Г)=L(Г') , поскольку каждая цепочка, выведенная в грамматике Г, может быть построена в грамматике Г'. Рассмотрим построение выводов в Г и Г'. В грамматике Г вывод цепочки имеет вид:
< A> <A> 1 <A> 1 1 <A> 1 1 1 1 1 1 1,
в грамматике Г' эта же цепочка выводится так: <A> 1<A'> 1 1<A'> 1 1 1<A'> 1 1 1 1.
Чтобы показать технику преобразования, рассмотрим пример. Требуется преобразовать грамматику Г1. 9 (рассмотренную ранее), которая задана схемой: Г1. 9: R={<E> <E> + <T> | <T>, < T> <T> * <F> | <F>, <F> ( <E> ) | a}.
Следуя описанному способу, правила <E> <E> + <T> | <T> преобразуем в правила <E> <T> | <T><E'> и <E'> +<T> | +<T><E'> , а правила <T> <T> * <F> | <F> преобразуем в правила <T> <F> | <F><T'> и <T'> F> | * <F><T'>. В результате получаем грамматику Г'1. 9, имеющую схему:
Г'1. 9 : R'= { <E> < T>,
<E> <T><E'>, < E'> + <T>, <E'> + <T><E'>, <T> <F>, <T> <F><T'>, <T'> * <F>, <T'> * <F><T'>, < F> a, <F> (<E>) },
не содержащую леворекурсивных правил.
6. Приемы построения грамматик.