Metodicheskie_ukazania
.pdf
11
<T>,2 |
I |
M(<T>,i)=4 |
<X>,2 |
|
|
$ |
|
|
<F>,3 |
i |
M(<F>,i)=6 |
<Y>,3 |
|
|
<X>,2 |
|
|
$ |
|
|
i,4 |
i |
M(i,i)= «сдвиг» |
<Y>,3 |
|
|
<X>,2 |
|
|
$ |
|
|
<Y>,3 |
* |
M(<Y>,*)=5 |
<X>,2 |
|
|
$ |
|
|
*,6 |
* |
M(*,*)= «сдвиг» |
<T>,6 |
|
|
<X>,2 |
|
|
$ |
|
|
<T>,6 |
i |
M(<T>,i)=4 |
<X>,2 |
|
|
$ |
|
|
<F>,8 |
i |
M(<F>,i)=6 |
<Y>,8 |
|
|
<X>,2 |
|
|
$ |
|
|
i,9 |
i |
M(i,i)= «сдвиг» |
<Y>,8 |
|
|
<X>,2 |
|
|
$ |
|
|
<Y>,8 |
$ |
M(<Y>,$)=8 |
<X>,2 |
|
|
$ |
|
|
<X>,2 |
$ |
M(<X>,$)=7 |
$ |
|
|
$ |
$ |
M($,$)=«допуск» |
В результате анализа получено синтаксическое дерево разбора:
<S>
│
┌─<E>─┐
┌<T>┐ <X> <F> ┌<Y>┐ │ │ * │ Λ
i ┌<T>┐
11
12
<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.
1.2.3. Синтаксический анализ для LR(1)-грамматики
Алгоритм синтаксического анализа на основе LR(k)-грамматики относится к классу алгоритмов восходящего разбора.
Строкам управляющей таблицы М (LR-таблица разбора) ставятся в соответствие состояния, в которых может находиться анализатор, столбцам – элементы множества {V T $}. Каждая запись рабочего стека представляет собой пару: (символ, номер состояния). Перед началом работы алгоритма в рабочий стек заносится пара (Λ,1), где 1 – символ начального состояния анализатора. Возможные значения элементов таблицы и их интерпретация алгоритмом разбора приведены в таблице 2.
|
Таблица 2 |
Значение элемента |
Интерпретация алгоритмом разбора |
управляющей таб- |
|
лицы |
|
Номер n порождаю- |
Удаление из рабочего стека k записей (k - количество |
щего правила грам- |
символов в правой части правила номер n); имитация |
матики |
считывания в качестве следующего входного символа |
|
нетерминала левой части правила номер n; запись n в |
|
выходную ленту |
(«сдвиг», номер j |
Запись текущего входного символа в выходной стек и в |
состояния) |
паре с номером j – в рабочий стек; если этот символ не- |
|
терминал, установка указателей на него в ближайших к |
|
нему n записях выходного стека с пустыми указателями |
«допуск» |
Входная строка разобрана. Конец работы |
«ошибка» |
Входная строка ошибочна. Конец работы |
12
13
Для построения управляющей таблицы М может быть выполнена разметка порождающих правил грамматики номерами состояний анализатора. Номера состояний устанавливаются в правой части каждого правила: перед первым символом, между любыми двумя символами и после последнего символа. При этом номер состояния, непосредственно справа от которого находится нетерминал, следует распространять на позиции перед первыми символами всех правых частей правил для данного нетерминала (и т.д. рекурсивно). А если непосредственно слева от одного и того же символа в каких-либо правилах установлены одинаковые метки, то и непосредственно справа от этого символа в этих правилах следует поставить одну и ту же метку. Начальные позиции правых частей правил для аксиомы отмечаются номером начального состояния анализатора. После разметки грамматики выполняется построение таблицы М по следующему алгоритму.
1.Если символ А в правой части правила имеет непосредственно слева от себя метку m, а непосредственно справа от себя – метку j, то M(m,A) = («сдвиг»,j).
2.Если метка j размещается за последним символом правой части правила номер n, то определяется множество Q символов, которые в какой-либо сентенциальной форме могут следовать за нетерминалом левой части правила но-
мер n, и M(j,q)=n для всех q Q.
3.M(1,<S>)= «допуск», где 1 – символ начального состояния.
4.Оставшиеся незаполненными элементы таблицы M получают значение «ошибка».
Пример.
Разметим грамматику G(V,T,P,S):
1)<S>::= 1 <E>2
2)<E>::= 1,4 <T>3+ 4<E>5
3)<E>::= 1,4 <T>3
4)<T>::= 1,4,7 <F> 6* 7<T>8
5)<T>::= 1,4,7 <F>6
6)<F>::= 1,4,7 i 9
Тогда таблица М примет вид:
|
<S> |
<E> |
<T> |
<F> |
i |
+ |
* |
$ |
1 |
допуск |
сдвиг,2 |
сдвиг,3 |
сдвиг,6 |
сдвиг,9 |
|
|
|
2 |
|
|
|
|
|
|
|
1 |
3 |
|
|
|
|
|
сдвиг,4 |
|
3 |
4 |
|
сдвиг,5 |
сдвиг,3 |
сдвиг,6 |
сдвиг,9 |
|
|
|
5 |
|
|
|
|
|
|
|
2 |
6 |
|
|
|
|
|
5 |
сдвиг,7 |
5 |
7 |
|
|
сдвиг,8 |
сдвиг,6 |
сдвиг,9 |
|
|
|
8 |
|
|
|
|
|
4 |
|
4 |
9 |
|
|
|
|
|
6 |
6 |
6 |
Незаполненные элементы таблицы имеют значение «ошибка».
Проанализируем входную цепочку i*i c помощью алгоритма LR(1)- анализатора.
Рабочий стек |
Вх.символ |
М(А,а) |
13
14
Λ,1 |
i |
M(1,i)=сдвиг,9 |
i,9 |
* |
M(9,*)=6 |
Λ,1 |
|
|
Λ,1 |
<F> |
M(1,<F>)=сдвиг,6 |
<F>,6 |
* |
M(6,*)=сдвиг,7 |
Λ,1 |
|
|
*,7 |
i |
M(7,i)=сдвиг,9 |
<F>,6 |
|
|
Λ,1 |
|
|
i,9 |
$ |
M(9,$)=6 |
*,7 |
|
|
<F>,6 |
|
|
Λ,1 |
|
|
*,7 |
<F> |
M(7,<F>)=сдвиг,6 |
<F>,6 |
|
|
Λ,1 |
|
|
<F>,6 |
$ |
M(6,$)=5 |
*,7 |
|
|
<F>,6 |
|
|
Λ,1 |
|
|
*,7 |
<T> |
M(7,<T>)=сдвиг,8 |
<F>,6 |
|
|
Λ,1 |
|
|
<T>,8 |
$ |
M(8,$)=4 |
*,7 |
|
|
<F>,6 |
|
|
Λ,1 |
|
|
Λ,1 |
<T> |
M(1,<T>)=сдвиг,3 |
<T>,3 |
$ |
M(3,$)=3 |
Λ,1 |
|
|
Λ,1 |
<E> |
M(1,<E>)=сдвиг,2 |
<E>,2 |
$ |
M(2,$)=1 |
Λ,1 |
|
|
Λ,1 |
<S> |
M(1,<S>)=допуск |
В результате анализа получено синтаксическое дерeво разбора:
<S>
│
<E>
14
15
│
┌─<T>─┐
││ │
<F> * <T>
││
i<F>
│
i
Ввыходном стеке это дерево представляется в виде:
9 |
<S> |
0 |
8 |
<E> |
9 |
7 |
<T> |
8 |
6 |
<T> |
7 |
5 |
<F> |
8 |
4 |
i |
5 |
3 |
* |
7 |
2 |
<F> |
7 |
1 |
i |
2 |
Последовательность номеров примененных правил (правый разбор): 665431
1.2.4. Синтаксический анализ для грамматики простого предшествования
Алгоритм синтаксического анализа на основе грамматики предшествования относится к классу алгоритмов восходящего разбора.
Строкам и столбцам управляющей таблицы М (матрицы отношений предшествования) ставятся в соответствие элементы множества T V $ (в строке - символ в вершине рабочего стека, в столбце - входной символ). Каждую запись рабочего стека представим парой: (символ, знак отношения предшествования символа предыдущей записи стека с данным символом). Перед началом работы алгоритма в стек записывается пара ($,0).
Возможные значения элементов таблицы и их интерпретация алгоритмом разбора приведены в таблице 3.
|
Таблица 3. |
Значение |
Интерпретация значения алгоритмом разбора |
элемента |
|
таблицы |
|
< |
Запись текущего входного символа в выходной стек и в паре со |
|
знаком «<» - в рабочий стек; если этот символ - нетерминал, |
|
установка указателей на него в ближайших к нему n - записях |
|
выходного стека с пустыми указателями, где n - количество сим- |
|
волов в правой части правила для этого нетерминала. |
= |
Запись текущего входного символа в выходной стек и в паре со |
|
знаком «<» - в рабочий стек; если этот символ - нетерминал, |
|
установка указателей на него в ближайших к нему n - записях |
|
выходного стека с пустыми указателями, где n - количество сим- |
|
волов в правой части правила для этого нетерминала. |
15
16
>Удаление из рабочего стека записей (символы которых образуют цепочку w) со знаками отношения « =» до первого знака «<» включительно; если <A>::=w - правило с номером n заданной грамматики, имитация считывания <A> в качестве следующего входного символа и запись n в выходную ленту
«ошибка» Входная строка ошибочна. Конец работы
«допуск» Входная строка разобрана. Конец работы
Отношения предшествования Вирта-Вебера < , =, > для КС-грамматики G(V,T,P,S) определяются на множестве V T следующим образом:
1)X<Y, если в Р есть такое правило <A>::=rX<B>q, что Y является головным символом хотя бы одной из цепочек, выводимых из <B>;
2)X=Y, если в Р есть правило <A>::=rXYq;
3)X>a, если a- терминал, и в Р есть правило <A>::=r<B>Yq такое, что X является хвостовым символом хотя бы одной из цепочек, выводимых из <B>, а Y=at, или a является головным символом хотя бы одной из цепочек, выводимых из Y.
Для |
анализа входной цепочки |
методом |
предшествования удобно до- |
бавлять к ней левый и правый концевые |
маркеры ($). Будем считать, что $<X |
||
для всех X, |
являющихся головными символами |
цепочек, выводимых из <S>, |
|
и Y>$ для всех Y, являющихся хвостовыми символами таких цепочек. КС-грамматика G(V,T,P,S) называется грамматикой предшествования,
если она является приведенной, не содержит Λ-правил, и для любой пары символов из T V выполняется не более одного отношения предшествования Вирта-Вебера. Обратимая грамматика предшествования называется грамматикой простого предшествования.
Пример.
Анализируя грамматику G(V,T,P,S) из п.1.2.1, заметим, что она не удовлетворяет определению грамматики предшествования, поскольку <T> = + в соответствии с правилом 2) и <T> > + в соответствии с правилами 2) и 4). Чтобы избавиться от этого конфликта, преобразуем эту грамматику к грамматике G2(V2,T,P2,S) с правилами:
1)<S>::=<E>
2)<E>::=<X>+<E>
3)<E>::=<X>
4)<T>::=<F>*<T>
5)<T>::=<F>
6)<F>::=i
7)<X>::=<T>
Матрица отношений предшествования для грамматики G2 имеет вид:
|
<S> |
<E> |
<T> |
<F> |
<X> |
+ |
* |
i |
$ |
<S> |
|
|
|
|
|
|
|
|
> |
<E> |
|
|
|
|
|
|
|
|
> |
<T> |
|
|
|
|
|
> |
|
|
> |
<F> |
|
|
|
|
|
> |
= |
|
> |
<X> |
|
|
|
|
|
= |
|
|
> |
+ |
|
= |
< |
< |
< |
|
|
< |
|
16
17
* |
|
|
= |
< |
|
|
|
< |
|
i |
|
|
|
|
|
> |
> |
|
> |
$ |
< |
< |
|
< |
< |
|
|
< |
|
Незаполненные элементы матрицы соответствует парам символов грамматики, для которых не определены отношения предшествования. При использовании этой матрицы в качестве управляющей таблицы в алгоритме синтаксического анализа можно считать, что эти элементы cодержат значение
«ошибка», а M(<S>,$)= «допуск».
Проанализируем входную цепочку i*i с использованием метода предшествования.
Рабочий стек |
Вх.символ |
М(А,а) |
$,0 |
i |
M($,i)= «<» |
i,< |
* |
M(i,*)= «>» |
$,0 |
|
|
$,0 |
<F> |
M(<F>,$)= «<» |
<F>,< |
* |
M(<F>,*)= «=» |
$,0 |
|
|
*,= |
i |
M(*,i)= «<» |
<F>,< |
|
|
$,0 |
|
|
i,< |
$ |
M(i,$)= «>» |
*,= |
|
|
<F>,< |
|
|
$,0 |
|
|
*,= |
<F> |
M(*,<F>)= «<» |
<F>,< |
|
|
$,0 |
|
|
<F>,<. |
$ |
M(<F>,$)= «>» |
*,= |
|
|
<F>,< |
|
|
$,0 |
|
|
*,= |
<T> |
M(*,<T>)= «=» |
<F>,< |
|
|
$,0 |
|
|
<T> |
$ |
M(<T>,$)= «>» |
*,= |
|
|
<F>,< |
|
|
$,0 |
|
|
$,0 |
<T> |
M($,<T>)= «<» |
<T> |
$ |
M(<T>,$)= «>» |
$,0 |
|
|
$,0 |
<X> |
M($,<X>)= «<» |
<X> |
$ |
M(<X>,$)= «>» |
$,0 |
|
|
$,0 |
<E> |
M($,<E>)= «<» |
<E>,< |
$ |
M(<E>,$)= «>» |
17
18
$,0 |
|
|
$,0 |
<S> |
M($,<S>)= «<» |
<S> |
$ |
M(<S>,$)= «допуск» |
$,0 |
|
|
В результате анализа получено синтаксическое дерево разбора:
<S>
│
<E>
│
<X>
│
┌─<T>─┐
<F> │ <T>
│ * │
i<F>
│
i
Ввыходном стеке это дерево представляется в виде:
10 |
<S> |
0 |
9 |
<E> |
10 |
8 |
<X> |
9 |
7 |
<T> |
8 |
6 |
<T> |
7 |
5 |
<F> |
6 |
4 |
i |
5 |
3 |
* |
7 |
2 |
<F> |
7 |
1 |
i |
2 |
Последовательность номеров примененных правил (правый разбор): 6654731.
1.2.5. Нейтрализация ошибок при LL(1)- разборе
Для нейтрализации ошибки (коррекции входной строки) при LL(1)- разборе можно воспользоваться содержанием рабочего стека как предсказанием того, что может появиться в разбираемой строке. С этой целью после окончания работы алгоритма LL(1)-разбора по команде «ошибка» следует проверить все символы рабочего стека на возможность вывода из них цепочки, начинающейся с текущего символа входной строки. Если в рабочем стеке не найдется такого символа, то текущий символ входной строки следует удалить. Если же в рабочем стеке обнаружится нужный символ, то для всех символов, находящихся в рабочем стеке выше него, следует сгенерировать цепочки терминалов и вставить их во входную строку.
Пример.
Пусть анализатору, построенному в п. 1.2.2, предложена строка i*+i. В
18
19
соответствии с командой «ошибка» анализатор прекратит разбор в то время, как текущим входным символом окажется +, а в рабочем стеке останутся записи:
<T>,6
<X>,2
$
Из нетерминала <X> можно вывести строку с терминальным префиксом + (правило 3). Тогда для формирования корректной строки следует из нетерминала <T>, размещенного в стеке выше <X>, вывести строку терминалов и вставить ее во входную строку. Такой строкой может быть, например, просто символ I, и следовательно, входная строка i*+i будет исправлена на i*i+i.
1.2.6. Синтаксически-управляемый перевод
Переводом называется некоторое отношение между цепочками или некоторое множество пар цепочек.
Перевoдoм с языка L1 (подмножество T1*) на язык L2 (подмножество Т2*) назовем отношение Π из T1* в Т2*, для которого L1 - oбласть определения, а L2 - множество значений.
Одним из формализмов, используемых для определения переводов, является схема синтаксически-управляемого перевода (СУ-схема). Фактически такая схема представляет собой грамматику, в которой к каждому правилу присоединяется элемент перевода. Всякий раз, когда правило участвует в выводе входной цепочки, с помощью элемента перевода вычисляется соответствующая часть выходной цепочки.
Формально СУ -схема определяется пятеркой Π =(V,Tin,Tout,R,S),где V - конечное множество нетерминальных символов; Тin - конечный входной алфавит; Тout - конечный выходной алфавит; R - конечное множество правил вида
A::=α,β ,где α (V Tin)* , β (V Tout)* , и вхождения нетерминалов в цепочку β образуют перестановку вхождений нетерминалов в цепочку α; S - начальный
символ.
Грамматика Gin = (V,Tin,Pin,S), где Pin = {A::= α │ A::= α, β R), называ-
ется входной грамматикой, а грамматика Gout = (V,Tout,Pout,S), где Pout = {A::= β │ A::= α, β R) , называется выходной грамматикой СУсхемы Π.
При использовании для разбора входной строки какого-либо алгоритма восходящего разбора перевод, заданный СУ-схемой, может быть выполнен в три этапа: построение правого разбора (соответствующей последовательности номеров правил) алгоритмом восходящего разбора, обращение полученной последовательности номеров правил, генерация водной строки в соответствии с выходной грамматикой и обращенной последовательности правого разбора.
Пример.
Задана СУсхема Π = ({S,A},{0,1},{2,3},R,S),где R:
1)S::=0AS,SA2
2)S::=1,3
3)A::=0SA,AS2
4)A::=1,3
Правый разбор цепочки 00111 имеет вид: 24321. В соответствии с обращенным правым разбором (12342) выполним вывод выходной строки:
S=>SA2=>3A2=>3AS22=>31S22=>31322.
19
20
2. Задания на лабораторные работы
2.1. Программирование алгоритмов лексического анализа с использованием автоматных грамматик
1.Построить регулярную грамматику для заданного языка.
2.Построить конечный автомат для полученной грамматики.
3.Разработать и отладить лексический анализатор-препроцессор на основе построенной автоматной модели.
Варианты задания
Код варианта содержит два числа. Первое из них определяет номер варианта описания языка, второе - способ представления автоматной модели (1 - граф переходов и выходов, 2 - таблица переходов и выходов).
Таблица вариантов задания
Nвар |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Код |
1.1 |
2.1 |
3.1 |
4.1 |
5.1 |
6.1 |
7.1 |
8.1 |
9.1 |
10.1 |
|
|
|
|
|
|
|
|
|
|
|
Nвар |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Код |
1.2 |
2..2 |
3.2 |
4.2 |
5.2 |
6.2 |
7.2 |
8.2 |
9.2 |
10.2 |
Описания языков 1) Цепочка символов «а» произвольной длины, после которой следует символ
«b»;
цепочка символов «а» произвольной длины, после которой следует символ
«с»; |
|
цепочка символов «b» произвольной длины, после которой |
следуют «а» |
или «с». |
|
2) Цепочка пар символов «а» «b» произвольной длины, после |
которой сле- |
дует «b»; |
|
цепочка пар символов «b» «а» произвольной длины, после которой следу-
ет «с»; |
|
|
|
символ «с». |
|
|
|
3) Произвольная цепочка |
символов |
из |
«а»,«b»,«с», заканчивающаяся на |
«аbс»; |
|
|
|
произвольная цепочка |
символов |
из |
«а»,«b»,«с», заканчивающаяся на |
«сbа». |
|
|
|
4)Три подряд пришедших символа «а» в произвольной цепочке из «а» и «b», после которых следует «b»;
три подряд пришедших символа «b» в произвольной цепочке из «а» и «b», после которых следует «а»;
три подряд пришедших символа «b» в произвольной цепочке из «а» и «b», после которых следует «с».
5)Произвольное число символов «а» между двумя символами «b»; произвольное число символов «b» между двумя символами «с»;
20
