Wykład 6. Gramatyki atrybutowe

Transkrypt

Wykład 6. Gramatyki atrybutowe
AGK 2008 Gramatyki atrybutowe
1
Wykład 6.
Gramatyki atrybutowe1
Jak wiadomo, gramatyki bezkontekstowe nie wystarczają do zdefiniowania
języków programowania, opisują one jedynie ich część składniową. Opis języka
powinien zawierać równieŜ część semantyczną, opisującą znaczenie (interpretację)
poszczególnych konstrukcji języka a takŜe wyraŜające pewne warunki kontekstowe
języka, których spełnienie gwarantuje, Ŝe pewne programy są poprawne.
W kompilatorach wykorzystuje się model opisu semantycznego sterowanego
składnią. Chodzi o to, by proces konstruowania drzewa wywodu był ściśle związany z
konstrukcją obiektu semantycznego przyporządkowanego temu drzewu.
Mówiąc inaczej, znaczenie drzewa wywodu budowanego z produkcji gramatyki
bezkontekstowej powstaje przez zastosowanie pewnych reguł semantycznych
związanych z tymi produkcjami.
Technika ta pochodzi od Knutha i jest podstawą praktycznych rozwiązań przy
projektowaniu kompilatorów. Jej podstawą jest system złoŜony z gramatyki
bezkontekstowej i atrybutowej specyfikacji semantycznej nazywany gramatyką
atrybutową.
Zanim wprowadzimy
formalną definicje gramatyki atrybutowej ustalimy, Ŝe
poniewaŜ naszych zainteresowań będą drzewa wywodu gramatyki bezkontekstowej,
wygodnie będzie utoŜsamiać kaŜdą produkcję z prostym drzewem etykietowanym
symbolami alfabetu gramatyki.
Tak więc produkcję
X0X1X2...XN będziemy utoŜsamiać z etykietowanym i
uporządkowanym drzewem na poniŜszym rysunku:
1
P. Dembiński, J. Małuszyński
Warszawa 1981
„Matematyczne metody definiowania języków programowania”, WNT,
AGK 2008 Gramatyki atrybutowe
(a)
1 X1
2
0 X0
(b)
0 X0
1ε
2 X2
N XN
.......
.
Drzewo produkcji przy N > 0
Drzewo produkcji przy N=0
W ten sposób kaŜde drzewo wywodu ma jednoznaczny rozkład na zbiór
drzew, z których kaŜde jest izomorficzne z pewną produkcją rozpatrywanej
gramatyki.
Nieformalnie,
gramatyka
atrybutowa
to
system
złoŜony
z
gramatyki
bezkontekstowej oraz zbiorów tzw. reguł semantycznych, związanych z produkcjami
gramatyki bezkontekstowej.
Reguły
semantyczne
określają
sposób
obliczania
wartości
pewnych
atrybutów w wierzchołkach drzew wywodu tej gramatyki. Znaczenie przypisane
drzewu moŜna określić w ten sposób jako wartość pewnego atrybutu (wartości
pewnych atrybutów) obliczonego (obliczonych) dla korzenia tego drzewa.
Przykład.
Rozpatrzmy prostą gramatykę generującą język ciągów zerojedynkowych. Za
znaczenie kaŜdego takiego ciągu będziemy uwaŜać liczbę, którą on reprezentuje w
notacji dwójkowej.
W myśl poprzednich uwag reguły semantyczne tej gramatyki
powinny wyznaczyć tę liczbę jako wartość pewnego atrybutu w korzeniu kaŜdego
drzewa wywodu tej gramatyki.
Odpowiednim atrybutem jest w tym przypadku L
Produkcje gramatyki bezkontekstowej i odpowiadające im reguły semantyczne
przedstawia poniŜszy rysunek.
AGK 2008 Gramatyki atrybutowe
3
PRODUKCJE
REGUŁY SEMANTYCZNE
N0 L1
L(0) = L(1);
W(1) = 0;
L(0) = L(1)+L(2);
W(1) = W(0) + 1;
W(2) = W(0)
L(0) = L(1);
W(1) = w(0);
L0 L1 C2
L0 C1
C0 0
C0 1
L(0)= 0
L(0)=2w(0)
Indeksy przy symbolach nieterminalnych oznaczają wierzchołki drzewa
produkcji, tzn. produkcja L LC jest zapisana jako L 0 L 1 C 2 dla oznaczenia, Ŝe L
etykietuje wierzchołek 0 i 1 w produkcji, a C wierzchołek 2.
Stąd reguły semantyczne moŜna odczytywać jako zapis pewnego warunku,
który musi być spełniony przez wartości atrybutów w odpowiednich wierzchołkach.
Głową gramatyki jest symbol N.
Atrybuty: L (liczba) i W (wykładnik) mogą przyjmować wartości ze zbioru
nieujemnych liczb całkowitych.
Na poniŜszym rysunku znajduje się drzewo wywodu dla ciągu 101 oraz
odpowiedni zbiór reguł semantycznych, wyznaczony podczas analizy syntaktycznej.
L0 L1 C2 odpowiadają dwie
Przykładowo w drzewie wywodu produkcji
produkcje: L1 L2 C3 i L2 L4 C5
dlatego w zbiorze reguł będą reguły związane
z tymi produkcjami, odpowiednio: L(1) = L(2)+L(3) i W(2) = W(1) + 1; W(3) = W(1)
oraz L(2) = L(4)+L(5) i W(4) = W(2) + 1; W(5) = W(2).
Obliczając wartości atrybutów L i W we
wszystkich wierzchołkach drzewa,
otrzymamy, Ŝe L(0) = 5, czyli wartość dziesiętną analizowanego ciągu 101.
AGK 2008 Gramatyki atrybutowe
2
4
0
N
L(0) = L(1) ;
W(1) = 0
L(1) = L(2) + L(3); W(2) = W(1) + 1
W(3) = W(1)
1
L
L(2) = L(4) + L(5) W(4) = W(2) +1
W(5) = W(2)
L(3) = 2 W( 3 )
L
3
C
L(4) = L(7)
L(5) = 0
L(7) =2 W( 7 )
4
L
5
C
6
W(7) = W(4)
1
L(0) = 5
7
C
9
1
8
0
L(1) = 5,
L(2) = 4,
L(3) = 1,
L(4) = 4,
L(5) = 0,
L(7) = 4,
W(1) = 0
W(2) = 1
W(3) = 0
W(4) = 2
W(5) = 1
W(7) = 2
Aby zdefiniować formalnie gramatyki atrybutowe wprowadzimy następujące
parami rozłączne zbiory symboli:
At – atrybuty
Fn – symbole funkcyjne n-argumentowe, n=0,1,2, ... przy czym F0 oznacza
symbole stałych
W – wierzchołki.
Zbiór Term określamy jako najmniejszy zbiór słów nad alfabetami At, W i Fn
n=0, 1, 2, ... , taki, Ŝe
(1) F0 ∈ Term
(2) JeŜeli a∈At i w∈W to a(w) ∈ Term
(3) JeŜeli f∈Fn , n = 0,1,2, ... oraz t1, t2,...,tn ∈Term to f(t1, t2,...,tn) ∈ Term
Regułą semantyczną nazywamy parę termów, którą będziemy zapisywać w postaci
równania: t1 = t2.
AGK 2008 Gramatyki atrybutowe
Interpretacja I
5
to odwzorowanie, które
(a) dla kaŜdego a∈At przyporządkowuje dziedzinę wartości DaI oraz
(b) dla kaŜdego symbolowi funkcyjnemu f∈ Fn, n=0,1,2, ... przyporządkowuje
n-argumentową funkcję: f I : D1× D2×...× Dn D0
W praktyce termy zapisujemy w naturalny sposób, np. t(a
przy czym termy a
j (ij)
1 ( i 1 ),...,
a
k (ik)
będą traktowane jako zmienne.
Wartość termu t
w interpretacji I jest zdefiniowana przez nadanie
konkretnych wartości z dziedziny Da j I zmiennym a
j (ij)
.
Niech p będzie produkcją gramatyki bezkontekstowej. Reguła semantyczna
t1 = t2 jest regułą semantyczną produkcji p, jeŜeli kaŜdy wierzchołek występujący w
termach t1, t2 jest wierzchołkiem p.
Definicja.
Gramatyką atrybutową nazywamy systemem GAT = (G, {RS(p)}p∈P, I),
przy czym:
G = (N, ∑, P, S) – jest gramatyka bezkontekstowa,
{RS(p)}
p∈P
– jest zbiorem reguł semantycznych dla produkcji P
I – jest interpretacją dla zbioru RS(p).
)
AGK 2008 Gramatyki atrybutowe
6
Gramatyki atrybutowe w sensie Knutha.
Wprowadzimy teraz definicję gramatyki atrybutowej w sensie Knutha.
Niech
G =(N, ∑, P, S) – będzie gramatyką bezkontekstową,
At – zbiór atrybutów.
KaŜdemu symbolowi nieterminalnemu X∈N przyporządkujemy skończony zbiór
atrybutów At(X)⊂ At .
Zbiór At(X) dzielimy na dwa rozłączne zbiory atrybutów syntezowalnych
AtS (X) i atrybutów dziedziczonych AtD (X).
At(x)= AtD (X) ∪ AtS (X)
Mówiąc ogólnie atrybuty syntezowalne (dziedziczone) to te, których wartość w
wierzchołku drzewa wywodu zaleŜy od wartości atrybutów w wierzchołkach będących
następnikami (poprzednikami) danego wierzchołka.
Definicja
Gramatyka atrybutowa GAt = ( G, {RS(p)}p∈∈P, I ) jest gramatyką w sensie
Knutha, jeŜeli dla kaŜdej produkcji
p: X0 X1 ... Xnp , zbiór reguł semantycznych
RS(p) składa się z reguł postaci: a0(i0) = t (a1(i1), ... ,ak(ik)),
1. dla kaŜdego j = 0,1,...,k,
przy czym:
Xi j jest wystąpieniem symbolu nieterminalnego po
prawej stronie produkcji p (czyli 0 ≤ ij ≤ np
i Xij ∈N)
2. jeśli i0 = 0, to a0 ∈ AtS (X0) oraz dla kaŜdego a ∈ AtS(X0), istnieje dokładnie
jedna reguła powyŜszej postaci , dla której a = a0 i i0 = 0.
3. jeŜeli i0 ≠ 0 to a0 ∈ AtD(X0) oraz dla kaŜdego wystąpienia Xk, 1 ≤ k ≤ np,
symbolu nieterminalnego X po prawej stronie produkcji p i kaŜdego atrybutu
dziedzicznego,
a ∈ AtD(X) istnieje dokładnie jedna reguła powyŜszej postaci taka, Ŝe a = a0
i i0 =k.
Innymi słowy, w zbiorze RS(p) istnieje dokładnie jedna reguła Ŝądanej postaci dla
kaŜdego syntezowanego atrybutu lewej strony produkcji i kaŜdego dziedziczonego
AGK 2008 Gramatyki atrybutowe
7
atrybutu dowolnego wystąpienia symbolu nieterminalnego po prawej stronie
produkcji p.
RozwaŜmy teraz dowolne drzewo wywodu gramatyki G. Niech w będzie
dowolnym wierzchołkiem tego drzewa etykietowanym pewnym symbolem X oraz
niech a∈At (X).
Przy powyŜszych załoŜeniach o gramatyce atrybutowej, w zbiorze równań
(reguł) semantycznych tego drzewa istnieje dokładnie jedno równanie postaci:
a(w0) = t(a1(w1), ... , ak(wk)).
Powiemy, Ŝe wartość zmiennej a(w) jest określona przez układ równań
i równa się v, tzn. wartość atrybutu a w wierzchołku w jest określona, jeŜeli
przedtem
określone
są
przez
układ
równań
v1,...,vk
wartości
zmiennych
a1(w1),...,ak(wk) i v jest wartością termu t przy interpretacji I dla v1,..., vk.
Innymi słowy, po to, Ŝeby obliczyć a(w), musimy najpierw obliczyć
a(w1),...,a(wk). Powiemy, Ŝe a(w) bezpośrednio zaleŜy od a(wi)
Przechodnie
domknięcie
tej relacji
daje
nam
relację
dla i = 1,..., k.
zaleŜności
zmiennych
występujących w układzie (równań) semantycznych związanych z drzewem wywodu.
Definicja.
Gramatyka atrybutowa w sensie Knutha jest poprawna (jej reguły są dobrze
określone), jeŜeli dla kaŜdego drzewa wywodu, kaŜdego jego wierzchołka w
i kaŜdego atrybutu a∈At(X), gdzie X etykietuje w, wartość a(w) jest określona przez
układ równań tego drzewa.
W terminach relacji zaleŜności znaczy to, Ŝe Ŝadna zmienna a(w) występująca
w układzie równań dla drzewa wywodu nie jest zaleŜna od samej siebie. Czyli graf
skierowany relacji zaleŜności dla tego układu równań nie zawiera cykli.
Knuth podał algorytm, rozstrzygający poprawność gramatyk atrybutowych na
podstawie reguł semantycznych gramatyki atrybutowej.
Idea tego algorytmu opiera się na spostrzeŜeniu, Ŝe kaŜdy graf relacji
zaleŜności zmiennych w równaniach jest złoŜony z podgrafów, które odpowiadają
grafom relacji zaleŜności dla reguł semantycznych poszczególnych produkcji
gramatyki.
AGK 2008 Gramatyki atrybutowe
PoniŜej
przedstawiano
8
przykład
grafu
zaleŜności
dla
układu
równań
poprzedniego przykładu oraz grafy relacji zaleŜności dla reguł semantycznych
produkcji przykładowej gramatyki.
ZauwaŜmy na koniec, Ŝe problem dobrej określoności gramatyki atrybutowej
Knutha jest istotny gdy w gramatyce tej występują atrybuty dziedziczone.
Z drugiej strony wiadomo, Ŝe nie są one konieczne – teoretycznie wystarczają
atrybuty syntezowane. JednakŜe, jak pokaŜą kolejne przykłady dzięki atrybutom
dziedziczonym reguły semantyczne mają naturalną i prostszą postać.
Dla gramatyk atrybutowych
dobrze określonych w sensie Knutha i
zawierających oba rodzaje atrybutów jeśli dane słowo jest akceptowane otrzymujemy
drzewo wywodu, którego wierzchołki zawierają wartości atrybutów.
Obliczanie wartości tych atrybutów w terminach drzew sprowadza się
wykonania procedury przechodzenia w głąb od korzenia drzewa wywodu.
Procedure Przech_wglab (n : node);
Begin
For each dziecka ‘c’ wezła ‘n’ od lego do prawego do
Begin
Oblicz_atrybuty_dziedziczone( wezła c);
Przech_wglab ( c );
End;
Oblicz_atrybuty_syntezowane( wezła n)
End;
AGK 2008 Gramatyki atrybutowe
rys. Graf zaleŜności atrybutów dla produkcji
9
AGK 2008 Gramatyki atrybutowe
10
Zastosowanie gramatyk atrybutowych do definiowania semantyki
języków programowania
Przykład1. WyraŜenie warunków kontekstowych języka.
W tym przykładzie rola reguł semantycznych i atrybutów sprowadza się do
tego, aby kaŜdego drzewa wywodu gramatyki bezkontekstowej generującego
przykładowy język programowania moŜna było zdecydować, czy programy przezeń
generowane spełniają pewne warunki kontekstowe, w szczególności, czy zachodzi
poprawność wyraŜeń i deklaracji oraz zgodność uŜycia zmiennych z ich deklaracjami
w programach.
Przed podaniem
reguł semantycznych wprowadzone
zostaną atrybuty
i dziedziny ich wartości.
Atrybuty
Dziedziny wartości
tekst
Słowa nad alfabetem języka
typ
{int, boolean}
Ot
Funkcje przyporządkowujące zmiennym
wartości ze zbioru {int, boolean}
dekl, zm
Zbiory zmiennych
Wartością atrybutu tekst jest znak lub ciąg znaków alfabetu, który określa
identyfikator w programie. Atrybut typ decyduje o poprawności wyraŜeń i ich uŜycia
w programie ze względu na ‘otoczenie’, czyli wartość atrybutu Ot. Ten ostatni zostaje
zdeterminowany przez deklaracje.
Związek między otoczeniem i typem wyraŜenia w produkcji
<wyr>0 <zm>1, opisuje reguła: typ(0) = Ot(0) (tekst(1)),
która mówi, Ŝe typ wyraŜenia będącego zmienną musi być równy zadeklarowanemu
typowi tej zmiennej.
Podobnie reguła
typ(2) = Ot(0) (tekst(1)),
dla instrukcji przypisania
<ins>0 <zm>1:= <wyr>2, wiąŜe typ zmiennej po lewej stronie z typem wyraŜenia
po prawej stronie instrukcji przypisania.
AGK 2008 Gramatyki atrybutowe
11
Atrybut typ nie dopuszcza ponadto innych wyraŜeń niŜ logiczne w instrukcjach
if-then-else i while oraz eliminuje błędne uŜycie operatorów w wyraŜeniach.
Atrybut dekl okresla zbiór zmiennych zadeklarowanych w programie, a
atrybut zm zbiór zmiennych uŜytych.
AGK 2008 Gramatyki atrybutowe
12
Reguła dekl(1) = zm(2) związana z produkcją:
<prog>0 begin <dkl>1 ; <ins>2 end,
wyklucza programy, w których zbiory te są róŜne.
Przykład 2. Translacja języka PJP na język pośredni.
Docelowym językiem programowania będzie w tym przypadku język, którego
instrukcje są jednej a następujących postaci:
1. (n, if, E, m) – skocz do m pod warunkiem E
2. (n, x:= E , m) – wykonaj przypisanie i skocz do m
3. (n, skocz, m) – skocz bezwarunkowo do m
4. (n, stop) – zakończ wykonanie,
gdzie: x ∈ Ident, E ∈ Exp w sensie języka PJP oraz m i n są liczbami naturalnymi.
Do zbioru atrybutów dokładamy kolejne atrybuty:
Atrybuty
Dziedziny semantycznie
tłm
Zbiory instrukcji postaci 1-4 (jak wyŜej)
ep, ek
Liczby naturalne
Nowe reguły semantyczne dla przykładowej gramatyki podaje tabela 2.2,
występuje w nich takŜe wcześniej wprowadzony atrybut tekst.
Znaczeniem kaŜdego programu w języku PJP będzie wartość atrybutu tłm -
tłumaczenie - w korzeniu drzewa wywodu tego programu.
Atrybut tekst słuŜy do „przepisywania" odpowiednich tekstów wyraŜeń i
podstawień języka PJP.
AGK 2008 Gramatyki atrybutowe
13
Zastosujemy reguły semantyczne z tabeli 2.2 do drzewa wywodu : (w tym przypadku
jednoznacznie wyznaczonego) następującego prostego programu:
begin
x:integer; i:integer;
x := l ;
while (i > O ) do x := (2 * x); i := (i - 1); od;
end;
AGK 2008 Gramatyki atrybutowe
14
Zbiór reguł dla powyŜszego programu:
tłm(5) = {(ep(5), x:= 1, ek(5))} ;
ek(5) = ep(5) +1;
tłm(6) = {(ep(6), x:= (2*x) , ek(6))} ;
ek(6) = ep(6) +1;
tłm(7) = {(ep(7), i:= (i-1) , ek(7))} ;
ek(7) = ep(7) +1;
tłm(4) = tłm(6) ∪ tłm(7);
ep(6) = ep(4); ep(7) = ek(6); ek(4) =ek(7);
tłm(3) = tłm(4) ∪ {(ep(3), if, i>0, ep(4)),
(ep(3), if, not (i>0), ek(3)),
(ek(4), skocz, ep(3)) };
tłm(2) = tłm(5) ∪ tłm(3);
ek(3) = ek(4)+1; ep(4) = ep(3) +1;
ep(5) = ep(2); ep(3) = ek(5); ek(2) = ek(3);
tłm(1) = tłm(2) ∪ {(ek(2), stop)};
ep(2) =1;
Wartość atrybutu tłm zostanie jednoznacznie wyznaczona, poniewaŜ mamy do
czynienia z poprawną atrybutową gramatyką w sensie Knutha. Atrybuty syntetyczne
tej gramatyki to tekst, ek, i tłm, natomiast ep - atrybut dziedziczny.
Po obliczeniu atrybutów ep i ek w wierzchołkach drzewa wywodu zadanego
programu otrzymamy:
n
ep
ek
2
1
6
3
2
6
4
3
5
5
1
2
6
3
4
7
4
5
AGK 2008 Gramatyki atrybutowe
15
Zatem wartość atrybutu tłm w korzeniu drzewa wywodu będzie następującym
zbiorem instrukcji języka docelowego:
(1,
(2,
(2,
(3,
(4,
(5,
x := l,
if, (i>0),
if, ~(i>0),
x :=(2*x),
i:=(i-l),
skocz,
2)
3)
6)
4)
5)
2)
Patrząc na otrzymany wynik nieco inaczej, moglibyśmy traktować go jako zbiór
równań semantycznych przyporządkowany programowi, gdzie poszczególne elementy
składowe instrukcji oznaczają konfiguracje sterowania i obiekty bazowe dziedziny
interpretacji.
Z jednej strony ich niesprzeczność oznacza w tym przypadku, poprawność
semantyczną przykładowego programu, z drugiej równania te są opisem semantyki
przykładowego języka.