Analiza Składniowa Wstępująca

Slides:



Advertisements
Podobne prezentacje
Lingwistyka Matematyczna
Advertisements

Schemat blokowy M START KONIEC
Grażyna Mirkowska PJWSTK 15 listopad 2000
Wykład 10 Metody Analizy Programów Specyfikacja Struktur Danych
Wykład 06 Metody Analizy Programów System Hoare
Wykład 6 Najkrótsza ścieżka w grafie z jednym źródłem
ALGORYTM Co to jest algorytm?
Badania operacyjne. Wykład 2
ALGORYTMY I STRUKTURY DANYCH
Elementarne struktury danych Piotr Prokopowicz
Lingwistyka Matematyczna
Generator analizatorów składniowych
Metoda pierwszeństwa operatorów
ZŁOŻONOŚĆ OBLICZENIOWA
ALGORYTMY GEOMETRYCZNE.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 8: Wykorzystanie procedur i funkcji © Jan Kaczmarek.
Języki formalne i gramatyki
Tablice.
Materiały pomocnicze do wykładu
Dr Anna Kwiatkowska Instytut Informatyki
Zależności funkcyjne.
Kod Graya.
Podstawy programowania
POJĘCIE ALGORYTMU Pojęcie algorytmu Etapy rozwiązywania zadań
O relacjach i algorytmach
Podstawy układów logicznych
ANALIZA LEKSYKALNA. Zadaniem analizatora leksykalnego jest przetwarzanie danych pochodzących ze strumienia wejściowego a także rozpoznawanie ciągów znaków.
ANALIZA METODĄ WSTĘPUJĄCĄ
IV OTWARTE MISTRZOSTWA OPOLA W PROGRAMOWANIU ZESPOŁOWYM
Gramatyki Lindenmayera
TABLICE C++.
Obserwatory zredukowane
A. Sumionka. Starodawna gra marynarska; Gra dwu i wieloosobowa; Gracze wykonują ruchy naprzemian; Złożona ze stosów, w których znajduje się pewna ilość
Zadanie programowania liniowego PL dla ograniczeń mniejszościowych
II Zadanie programowania liniowego PL
Zadanie programowania liniowego PL dla ograniczeń mniejszościowych
Języki i automaty część 5.
Języki i automaty część 3.
Algorytmy.
Elżbieta Fiedziukiewicz
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Translatory Copyright, 2006 © Jerzy R. Nawrocki Wprowadzenie do informatyki Wykład 11.
Gramatyki i translatory
II Zadanie programowania liniowego PL
Podstawy języka Instrukcje - wprowadzenie
Podstawy Techniki Cyfrowej
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Algorytmy i Struktury Danych
Gramatyki Lindenmayera
Zagadnienia AI wykład 2.
Grafika i komunikacja człowieka z komputerem
Języki formalne i gramatyki Copyright, 2005 © Jerzy R. Nawrocki Teoretyczne podstawy.
I T P W ZPT 1 Kodowanie stanów to przypisanie kolejnym stanom automatu odpowiednich kodów binarnych. b =  log 2 |S|  Problem kodowania w automatach Minimalna.
Języki formalne Copyright, 2006 © Jerzy R. Nawrocki Wprowadzenie do informatyki Wykład.
ANALIZA SKŁADNIOWA.
ANALIZA METODĄ WSTĘPUJĄCĄ. ANALIZA WSTĘPUJĄCA Dla danej gramatyki G oraz S=>* , to wówczas:  Jeśli  zawiera tylko terminale, to  nazywamy zdaniem;
GRA CHOMP. Czym jest chomp? Jest to gra dla dwóch osób, rozgrywana na prostokątnej tablicy, zwanej „tabliczką czekolady”
Y A C C Generator analizatorów składniowych. GENERATOR YACC Zadaniem generatora YACC jest wygenerowanie kodu źródłowego analizatora składniowego (domyślnie)
Autor: Michał Salewski
Systemy wspomagające dowodzenie twierdzeń
Warstwowe sieci jednokierunkowe – perceptrony wielowarstwowe
Metody sztucznej inteligencji – technologie rozmyte i neuronoweReguła propagacji wstecznej  Dr hab. inż. Kazimierz Duzinkiewicz, Katedra Inżynierii Systemów.
Gramatyki Lindenmayera
Wstęp do programowania Wykład 9
Zarządzanie projektami
Gramatyki Lindenmayera Powstanie Deterministyczny L-system.
Pojęcia podstawowe c.d. Rachunek podziałów Elementy teorii grafów
Liczbami naturalnymi nazywamy liczby 0,1,2,3,..., 127,... Liczby naturalne poznaliśmy już wcześniej; służą one do liczenia przedmiotów. Zbiór liczb.
ALGORYTMY I STRUKTURY DANYCH
POJĘCIE ALGORYTMU Wstęp do informatyki Pojęcie algorytmu
Zapis prezentacji:

Analiza Składniowa Wstępująca Automat ze stosem Przykład gramatyki Automat rozpoznający Gramatyki LR(k) 8 marca 2004 Wykład 5 Andrzej Salwicki

Automat ze stosem Definicja Automat ze stosem jest uporządkowaną siódemką A= (T, Q, R, q0 , F, S, s0) Q jest zbiorem stanów automatu, q0 jest stanem początkowym, F Q jest akceptującym podzbiorem stanów. Zbiory T i Q są rozłączne. T jest zbiorem symboli wejściowych. S jest zbiorem symboli wpisywanych na stos, s0 jest symbolem - początkową wartością stosu. Kazdy element zbioru R ma postać qa  'q' gdzie  i ' są elementami S* , q i q' elementami ze zbioru Q, a jest elementem T lub a = , a  jest elementem T*. 1

Automat ze stosem c.d. Automat ze stosem akceptuje napis  T , jeśli s0q0q dla pewnego q ze zbioru F. Jeśli kazde zdanie jest zakończone znakiem $, to automat A definiuje język L(A) = { | s0q0$q$, q F,   } Automat jest maszyną ze skończonym zbiorem Q stanów wewnętrznych i ze stosem, który jest skończony ale nie ma ograniczenia jego długości. Konfiguracja s1 ... snq oznacza, ze automat jest w stanie q,  jest nieprzeczytaną jeszcze częścią analizowanego tekstu wejściowego, s1 ... sn jest zawartościąstosu, (sn jest na wierzchołku stosu, s1 na dnie stosu). Twierdzenie Dla kazdej gramatyki bezkontekstowej G istnieje automat ze stosem A, taki, ze L(A) = L(G). 1

Budujemy automat dla gramatyki G Niech G = (T, N, P, S) będzie gramatyką bezkontekstową. Definiujemy automat A=(T, {q}, R, q, {q}, V, ) gdzie V=T N, R jest zbiorem zdefiniowanym następująco: R = {x1...xnq  X | X  x1...xnP}{qttq | tT}{Sqq} Ten automat akceptuje dany napis z L(G) wytwarzając odwrócone prawostronne wyprowadzenie takiego napisu z symbolu początkowego S. 1

Wybrana gramatyka Gramatyka G3 T = {+, * , (, ), i} symbole terminalne N = {E, T, F} symbole nieterminalne P= { E ::=T, E ::= E + T, produkcje T ::= F, T ::= T * F, F ::= i, F ::= ( E ) } S = E symbol startowy Zbudujemy odpowiedni dla niej automat ze stosem. 1 13 marca 2002

Gramatyka i automat Gramatyka G T = {+, * , (, ), i} N = {E, T, F} P= { E ::=T, E ::= E + T, T ::= F, T ::= T * F, F ::= i, F ::= ( E ) } Start = E Automat AG T = {+, * , (, ), i} S = {+, * , (, ), i, E, T, F} R= { Tq Eq, E+Tq  Eq, Fq Tq, T * Fq Tq, iq Fq, ( E )q Fq, q+  +q, q* *q, q(  (q, q)  )q, qi  iq, Eq  q } Q = {q} Cel = E 1

Stos i F T E E+ E+i E+F E+T E+T* E+T*i E+T*F E+T E Przebieg analizy Stos i F T E E+ E+i E+F E+T E+T* E+T*i E+T*F E+T E Stan Wejście q i+i*i q +i*i q +i*i q +i*i q +i*i q i*i q *i q *i q *i q i q q q q q Wyprowadzenie prawostronne i+i*i shift F+i*i reduce T+i*i reduce E+i*i reduce shift shift E+F*i reduce E+T*i reduce shift shift E+T*F reduce E+T reduce E reduce 1

W tym przykładzie wszystko przebiegło gładko W tym przykładzie wszystko przebiegło gładko. Skąd mamy czerpać gwarancję, że tak będzie zawsze, dla każdej gramatyki i dla każdego napisu wejściowego. Zauważmy, że możliwe są konflikty, gdy w danej konfiguracji automat może dokonać wyboru spomiędzy kilku przejść. Prawie zawsze automat ma do wyboru przejście przesuwające z wejścia na stos postaci qt tq, lub przejście redukujące. Ten konflikt możemy rozstrzygnąć w ogólny sposób dając pierwszeństwo przesunięciom nad redukcjami. Nadal jednak mogą się zdarzyć gramatyki o takich własnościach, które spowodują nieefektywność procesu analizy składniowej. 1

Nieco teorii

Notacja k-głowa napisu  =df pierwsze min(k, ||+1) symboli napisu , przyjmujemy oznaczenie k: FIRSTk() =df zbiór wszystkich terminalnych k-głów napisów dających się wyprowadzić z napisu  EFFk(w) =df zbiór wzystkich napisów z FIRSTk() dla których w prawostronnym wyprowadzeniu  , w ostatnim kroku nie zastosowano produkcji anulującej A   FOLLOWk() =df zbiór wszystkich terminalnych k-głów, które mogą wystąpić po  Prawostronne wyprowadzenie X * Y oznaczamy X R Y Indeks k pomijamy gdy k=1

Formalne definicje FIRSTk() =df { takie, ze k} EFFk() =df FIRSTk() FIRSTki  takie, że R FOLLOWk() =df { V* takie, ze S k: }

Tablica Wejście S t o s W y j ś c i e actions goto Program automatu LR 1

Konfiguracje Analiza wstępująca przeprowadzona przez ten automat konstruuje wyprowadzenie od symbolu startowego do ciągu źródłowego, w odwróconej kolejności. Konfiguracja -istotna tu jest informacja nie o stanie wewnętrznym automatu, lecz para () gdzie S* oznacza zawartość stosu, a * oznacza nieprzeczytaną jeszcze część tekstu wejściowego. Pary opisujące konfiguracje automatu można podzielić na klasy równowazności: 1

Klasy redukcji Definicja Dla p = 1, ...,n niech Xp -> p będzie p-tą produkcją gramatyki bezkontekstowej G=(T, N, P, S). Klasy redukcji Rj, j=0,...,n są zdefiniowane następująco: R0 = {() | , , takie, ze S A, A R', } Rp = {() | p, SR p} gdzie A R'oznacza relację “A Roraz ostatni krok w tym wyprowadzeniu nie jest anulujący: B ” 1

Przejścia automatu wyznaczone przez klasy redukcji Klasy redukcji zawierają wszystkie pary napisów, kóre mogą pojawić się podczas analizy wstępującej wykonywanej przez opisany automat ze stosem. Ponadto, klasa redukcji, do której nalezy para charakteryzuje przejście automatu wykonywane wtedy gdy para pojawia się jako konfiguracja bieząca automatu. Istnieją trzy mozliwości: (1) ()R0 , nie ma na stosie pojedynczej frazy p; stosuje się przejście qt -> tq dla t= pierwszy symbol z  (jest to przejście z przesunięciem, ang. shift), (2) ()Rp , 1pn . Pojedyncza fraza jest całkowicie na stosie i wykonuje się przejście redukujące. Dla p=1 jest wykonywane jest przejście akceptujące Sq -> q. (3) ()Rp , 0jn . Dalsze przejścia nie są mozliwe. Błąd! 1

Gramatyki LR(k) Definicja Dla pewnego k >0, zbiory Rj,k, dla j=0,...,n nazywamy klasami k- stosowymi gramatyki G jeśli Rj,k = {() | Rj takie, ze  = k:} k: to początek , k symboli Gramatyka bezkontekstowa G jest typu LR(k) dla danego k > 0, jeśli dla dowolnych wyprowadzeń: SR A V*T*, A-> P SR 'B''''V*'T*, B-> P (||+k): = (|'|):'' implikuje, ze ', A =B,  Twierdzenie Gramatyka bezkontekstowa jest typu LR(k) wtedy i tylko wtedy gdy jej klasy k-stosowe są parami rozłączne. 1

Twierdzenie powyzsze można wykorzystać do testowania własności LR(k) poprzez obliczanie przecięć klas k-stosowych. Kłopot polega na tym, że klasy te mogą być nieskończone, mogą zawierać nieskończenie wiele par (). Długość zawartości stosu jest przecież nieograniczona. Okazuje się jednak, że dla każdej klasy k-stosowej Rj,k mozemy podać gramatykę regularną Gj taką, ze L(Gj) = {() | () Rj,k}. Pozostaje tylko skorzystać z algorytmu sprawdzającego czy dane dwa języki regularne są rozłączne. Twierdzenie Niech G będzie gramatyką bezkontekstową i niech k>0. Zakładamy, ze & T N . Istnieje zbiór gramatyk regularnych Gj, dla j=0,...,n taki, ze L(Gj) = {() | () Rj,k}. 1

Kazdy stan automatu ze stosem można reprezentować trójką (p, j ) gdzie p jest numerem zastosowanej produkcji, 0<j<np jest liczbą juz przeanalizowanych symboli prawej strony produkcji Xp -> xp,1, ... ,xp,np a  jest zbiorem k-głów napisów, które mogą wystąpić za napisem wyprowadzonym z Xp. Taką trójkę nazywamy sytuacją i będziemy stosować następującą notację [X->] gdzie  = xp1, ... , xp,j, = xp,j+1, ... ,xpnp Kropka zaznacza pozycję analizy wewnątrz prawej strony. W większości przypadków  zawiera pojedynczy napis - piszemy go bez nawiasów. 1

W = {[X   ; ]  X   P ,  FOLLOWk(X)} Gramatyki Gj regularne generujące klasy k-stosowe, są oparte na sytuacjach W = {[X   ; ]  X   P ,  FOLLOWk(X)} te sytuacje są symbolami nieterminalnymi gramatyk regularnych (stanami odpowiedniego automatu). Najpierw określimy zbiór gramatyk, które generują klasy k-stosowe, ale nie muszą być regularne Gj' = (V  {&, $}, W, P' P”  Pj, [S -> . s;$]) alfabet końcowy nieterminale produkcje symbol startowy Produkcje z P' P” budują składnik  klasy k-stosowej. Stanowią one skończony opis napisów nieskończonej długości. Produkcje z Pj dołączają składnik , kończąc klasę k-stosową. P' = {[ X   ;  ] ->  [X   ; ]    V} 1

P”= {[ X   ; ] [B  ; ]  B  P,  EFFk()} P0 = {[X   ;  ]  &    EFFk()} Pp = {[Xp  ˝p. ;] &} p=1, ..., n Przypomnijmy, ze długości napisów t i w są ograniczone do k symboli. Zatem liczba mozliwych napisów &t i &w jest skończona. Jeśli napisy te potraktować jako pojedyncze symbole terminalne, to produkcje z P' i z Pj , j=0, 1, ... ,n są dopuszczalne w gramatyce regularnej. Produkcje z P” nie są dopuszczalne w gramatyce regularnej poniewaz mają postać A -> B, A, B N. Gramatyka Gj' nie jest więc regularna. Można ją jednak przepisać tak by nie zawierała produkcji typu P”. Zastosujemy domknięcie symbolu nieterminalnego H(A) = {A} {B | C->B P, C  H(A)} 1

Procedura przepisywania gramatyki jest następująca: 1. Wybierz A N, dla którego H(A)  {A}. 2. Niech P:= P - {A  B : BN} 3. Niech P := P {A : B    P, BH(A), N } Algorytm kończy się gdy nie mozna dokonać wyboru w kroku 1. Twierdzenie Dla każdej gramatyki G typu LR(k) istnieje deterministyczny automat ze stosem A taki, że L(A) = L(G) 1

Gramatyka P={SX, XY, XbYa, Yc, Yca} Przejścia R={ q0bc q0q3c, q0c$ q0q4$, q3ca q3q6a, q4a$ q4q7$, q5a$ q5q8$, q6aa q6q9a, q0q2$ q0q1$, q0q4$ q0q2$, q3q6a$ q3q5a$, q0q4q7$ q0q2$, q0q3q5q8$ q0q1$, q3q6q9a$ q3q5a$ } Stany q0: [SX;$] q4: [Yc.;$] [X.Y;$] [Yc.;$] [X.bYa;$] [Y.c;$] q5: [XbY.a;$] [Y.ca;$] q6: [Yc.;a$] q1: [SX.;$] [Yc.a;a$] q2: [XY.;$] q7:[Yca.;$] q3: [Xb.Ya;$] q8:[XbYa.;$] [Y.c;a$] q9: [Yca.;$] [Y.ca;a$] 1

Tworzenie parsera LR(0) Gramatyka 0 S' ::= S$ 1 S ::= ( L ) 2 S ::= x 3 L ::= S 4 L ::= L , S Początkowy stan automatu: stos pusty, na wejściu: zdanie i $. Oznaczamy ten stan przez S'-> . S$ (kropka wskazuje pozycję ) W tym stanie gdy wejście rozpoczyna się od S , tzn. od jakiejkolwiek prawej strony produkcji dla S S'  . S $ S  . x S  . ( L ) 1 To jest stan 1. Stan ten utozsamiamy z pewnym zbiorem sytuacji.

Tworzenie parsera LR(0) Przesunięcie symbolu Co się stanie gdy w stanie 1 przesuniemy x. W nowym stanie 2 znajdzie się sytuacja S ->x . , Reguły S-> S$ i S -> ( L ) nie mają znaczenia gdy przeczytano x. A więc stan 2 to jedna tylko sytuacja A jeśli w stanie 1 przeczytamy ( lewy nawias? Nowa sytuacja to S  ( . L ) , wiemy, ze na stosie jest lewy nawias, a na wejście jest ciąg wyprowadzony z L a potem prawy nawias. Jakie sytuacje odpowiadają temu nowemu stanowi 2 S  x . 3 L  ( . L ) L  . L , S L  . S S  . ( L ) S  . x

Tworzenie parsera LR(0) Akcje przejścia Co się stanie gdy z S wyprowadzimy pewien ciąg symboli? Cała prawa strona produkcji będzie zdjęta ze stosu i parser wykona akcję przejścia dla symbolu S i stanu 1 wchodząc do stanu 4 Redukcje W stanie 2 kropka jest na końcu pewnej sytuacji. Oznacza to, ze na wierzchołku stosu jest cała prawa strona odpowiedniej produkcji S  x gotowa do redukcji. W takim stanie parser powinien wykonać akcję redukcji r2 tzn. zastosować drugą produkcję. W tym przypadku x zostanie zastąpione przez S. 4 S'  S . $

Tworzenie parsera LR(0) Dwie operacje są nam potrzebne by wyznaczać stany, a to: Domknięcie i Przejście. Domknięcie(I)= repeat for each item A  . X in I for each production X   I := I {X  .} until I does not change return I Przejście(I,X)= J :=  ; for each item A  . Xin I J := J X .  return Domknięcie(J)

Algorytm konstrukcji parsera LR(0) Powiększ gramatykę dodając produkcję S' S $. T będzie zbiorem stanów, E zbiorem krawędzi (shift albo przejścia) T := Domknięcie({S' . S $}); E := ; repeat for each state I in T for each item A . X in I J := Przejście(I, X); T := T {J}; E := E  {I X J }; until E oraz T nie zwiększają się w tej iteracji; Dla symbolu $ nie obliczamy Przejście(I, $); zamiast tego tworzymy stan akceptuj.

Algorytm konstrukcji parsera LR(0) c.d. Teraz wyznaczamy redukcje. R := {}; for each state I in T for each item A  in I R := R 

Przykład S'  . S $ S  . x S  . ( L ) S  x . 1 2 8 9 S'  . S $ S  . x S  . ( L ) S  x . x x L  L , . S S  . ( L ) S  . x S L  L , S . 3 ( S  ( . L ) L  . S L  . L , S S  . ( L ) S  . x ( , ( S 5 S  ( L . ) L  L . , S L 4 S'  S . $ ) 6 S S  ( L ) . 7 L  S .

Przykład c.d. Tablica przejść automatu LR(0) dla przykładowej gramatyki 0 S' ::= S$ 1 S ::= ( L ) 2 S ::= x 3 L ::= S 4 L ::= L , S actions goto

Tworzenie parsera SLR (str. 1/3) Przykład: gramatyka S  E$, E  E + T, E T, T -> x. Graf przesunięc i przejśćutworzony wg LR(0) 1 2 S  . E $ E  . T + E E  . T T  . x E E  T . $ 3 T E  T . + E E  T . 4 , E  T = . E E  . T + E E  . T T  . x T x 5 T  x . E 6 E  T + E .

Tworzenie parsera SLR (str. 2/3) Tablica parsera, zauważ, że jest konflikt nowy algorytm SLR : stany obliczamy j.w. a redukcje tak: R := {}; for each state I in T for each item A  in I for each token X in FOLLOW(A) R := R {(I, X, A )};

Tworzenie parsera SLR (str. 3/3) Po zastosowaniu algorytmu SLR otrzymujemy tablicę:

Co by tu jeszcze? Nie zdążyłem opowiedzieć: O metodzie pierwszeństwa operatorów, O analizatorach LALR, O pożytkach płynących z zastosowania gramatyk niejednoznacznych , O wydobywaniu się z błędów.