deterministick á sa zhora nadol

Post on 03-Feb-2016

59 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Deterministick á SA zhora nadol. Gramatiky a jazyky LL(k) a ich analýza. Gramatiky LL(k). Umožňujú deterministickú SA Umožňuje deterministickú SA zhora nadol – robí sa teda ľavá derivácia - PowerPoint PPT Presentation

TRANSCRIPT

Deterministická SA zhora nadol

Gramatiky a jazyky LL(k) a ich analýza

Gramatiky LL(k)

Umožňujú deterministickú SA Umožňuje deterministickú SA zhora nadol – robí

sa teda ľavá derivácia Cena za determinizmus je vyjadrená potrebou

poznať ďalších k symbolov zo vstupu za práve vyšetrovaným symbolom

Na základe tohoto – tzv. vopred prezretého reťazca pozostávajúceho z najviac k nasledujúcich symbolov dokáže rozšriešiť problém výberu zodpovedajúcej alternatívy pravej strany pravidla

Funkcia FIRST

Umožňuje určiť množinu reťazcov danej dľžky, ktoré možno generovať z VF, ktorá je jej argumentom

Nech G = (N, T, P, S) je BKG, k je celé kladné číslo, (N T )*. Potom pre G je FIRSTk ( ) = { w / w T*,

|w| k a *w, alebo |w| = k a *wx pre nejaké x}

Funckia FIRSTk ( ) dáva teda množinu všetkých terminálnych reťazcov, ktoré možno derivovať z a ich dĺžka je menšia ako k, alebo tvoria prefix dĺžky k VF, ktorú možno derivovať z .

Gramatika LL(k) df

BKG G = (N, T, P, S) je LL(k) ak pre každé dve ľavé derivácie tvaru

S *wA w *wx

S *wA w *wy

Pre ktoré

ak FIRSTk (x ) = FIRSTk (y )

tak =

Poznámky k definícii

Definícia hovorí, že ak je „ďalších k symbolov“ rovnakých, musí existovať iba jedna laternatíva pravej strany pravidla pre A.

Budeme hovoriť, že BKG je LL, ak je LL(k) pre nejaké k

Budeme hovoriť, že jazyk je LL ak ho možno špecifikovať gramatikou LL(k) pre nejaké k

Od derivácií k pravidlám G

Uvedená definícia LL gramatiky je príliš všeobecná na praktické využitie – je nereálne vyšetrovať všetky ľavé derivácie

Snahou je určiť vlastnosti LL gramatiky z jej pravidiel

Dopracujeme sa k tomu postupne

Vlastnosť LL a ľavé VF

BKG G = (N, T, P, S) je LL(k) ak pre každé dve rôzne pravidlá z P

A a A

a všetky ľavé VF wA platí

FIRSTk ( ) FIRSTk ( ) =

Od jednoduchých gramatík

BKG G = (N, T, P, S) bez e-pravidiel nazývame jednoduchá LL(1) ak pre každý neterminál A sa všetky jeho alternatívy začínajú rôznymi terminálnymi symbolmi

BKG G = (N, T, P, S) bez e-pravidiel je LL(1) ak pre všetky neterminály z N a zodpovedajúce pravidlo z P

A 1 | 2 | ... | n Platí

FIRST1(i ) FIRST1(j ) = pre i j

Ošetrenie e-pravidiel

Nech G = (N, T, P, S) je BKG, k je celé kladné číslo, (N T )*. Potom pre G je FOLLOWk ( ) = { w / S *,

w FIRSTk( ) }

Rozšírenie FIRST a FOLLOW

Funkcie FIRST a FOLLOW možno rozšíriť na množiny takto

Nech G = (N, T, P, S) je BKG a M (N T)*. Potom

FIRSTk(M) = {w / w FIRSTk( ), pre nejaké M }

FOLLOWk(M) = {w / w FOLLOWk( ), pre nejaké M }

LL(1) G

BKG G = (N, T, P, S) je LL(1) práve vtedy, ak pre každé dve pravidlá z P

A a A pričom platí, že

FIRST1 ( FOLLOW1(A) )

FIRST1 ( FOLLOW1(A) ) = Silná LL(k) gramatika – uvedená vlastnosť platí pre

ľubovolné celé k.

Podmienky pre LL(1)

BKG G = (N, T, P, S) je LL(1) práve vtedy, ak pre všetky neterminály A a zodpovedajúce pravidlá

A 1 | 2 | ... | n platí:

1. Ak i *w, w T+, j *u, u T+, tak FIRST1(i ) FIRST1(j ) = pre 1 i, j n, i j. Podmienka FIRST-FIRST

2. Ak i *e,t.j. e FIRST1(i ) pre niektoré i, potom FIRST1(j ) FOLLOW1(A ) = pre 1 j n, i j Podmienka FIRST-FOLLOW

Niektoré vlastnosti LL gramatík

Zľava rekurzívna G nie je LL(k) pre žiadne k

Ak G1 a G2 sú LL(k), potom je rozhodnuteľné, či sú ekvivaletné, teda či L(G1) = L(G2)

Transformácia LL(k) gramatík

Motív transformácie je hľadanie ekvivalentnej LL(k) gramatiky s čo najmenším k – zvyčajne k = 1.

Postup – cez odstraňovanie negatívnych vlastností Gramatiky programovacích jazykov to zvyčajne

umožňujú. Najčastejšie sa používajú dve transformácie - odstránenie ľavej rekurzie - faktorizáciaTieto transformácie zvyčajne postačujú

Odstránenie ľavej rekurzie

Gramatika je rekurzívna – zľava / sprava, ak obsahuje aspoň jeden neterminál rekurzívny – zľava /sprava

Neterminál A z G je rekurzívny, ak existuje derivácia A + A pre nejaké , (N T )*, pričom , nemôžu byť súčasne prázdne. Ak je prázdne , A je zľava rekurzívny, ak , tak sprava.

Samozrejme, že hľadáme ekvivaletnú gramatiku Odstránenie ľavej rekurzie je známe z úpravy

gramatiky na Greibachovej normálny tvar

Pravidlá transformácie

Nech G = (N, T, P, S) je BKG, v ktorej

A A1 | A2 | ... | An | 1| 2 | ... | m sú všetky pravidlá v P s neterminálom A na ľavej strane a

žiadne i pre i= 1, 2, ..., m nezačína neterminálom A. Potom gramatika G’ = (N {A ’}, T, P’, S) , v ktorej uvedené pravidlá nahradíme pravidlami

A 1| 2 | ... | m | 1A’| 2A’| ... | m A’

A’ 1 | 2 | ... | n | 1A’| 2A’| ... | nA’ je s G ekvivalentná, teda L(G’) = L(G)

Poznámky k transformácii

Uvedená transformácia odstraňuje ľavú rekurziu

Uvedená transformácia neodstraňuje rekurziu – ak G obsahuje rekurziu, tak zodpovedajúci jazyk je nekonečný a rekurzia je jediný spôsob jeho špecifikácie

Rekurziu nemožno zamieňať s cyklom (A + A)

Príklad

Majme gramatiku G:

G = ({E, T, F}, {+, *, a, (, ) }, P, E)

P: E E + T |T

T T * F | F

F ( E ) | a

Ľahko vidieť, že G je zľava rekurzívna

E E + T , T T * F

Urobíme transformáciu.

Príklad – transformácia G

E E + T |T

E T |T E’

E’ + T | +T E’

T T * F | F

T F | F T’

T’ * F | * F T’

F ( E ) | a

F ( E ) | a

E E + T |T

T T * F | F

F ( E ) | a

Poznámky k transformácii

Gramatika s tranformovanými pravidlami nie je zľava rekurzívna

Je LL(k) ? Je LL(1) ? Že nie je LL(1) vidieť už na prvý pohľad, lebo má

pravidlá, ktoré začínajú rovnakým terminálom Vidíme, že viaceré pravidlá majú spoločný prefix.

Jeho odstránenie umožňuje faktorizácia

Faktorizácia

Nech G = (N, T, P, S) je BKG, v ktorej

PA = { A 1 | 2 | ... | n } je podmnožina A – pravidiel, ktorých pravá strana má spoločný prefix , e. Potom gramatika G’ = (N {A ’}, T, P’, S) , kde P’ = P - PA { A A’, A’ 1 | 2 | ... | n } a

A’ je neterminálny symbol je s G ekvivalentná, L(G’) = L(G)

Poznámky

Interpretáciu faktorizácie si ľahko možno zapamätať, ak s pravidlom urobíme jednoduchú matematickú operáciu „vyňatia pred zátvorku“

A 1 | 2 | ... | n

A (1 | 2 | ... | n) A A’ A’ 1 | 2 | ... | n

Príklad

Vrátime sa ku gramatike v ktorej odstránili ľavú rekurziu. Zoberme iba pravidlá

E T |T E’

E T E’’

E’’ E’ | e

E’ + T | +T E’

E’ +T E’’’

E’’’ E’ | e

Príklad Cont

T F | F T’

T F T’’

T’’ T’ | e

T’ * F | * F T’

T’ * F T’’’

T’’’ T’ | e

F ( E ) | a

F ( E ) | a

Poznámky

Gramatiku po fakturizácii možno zjednodušiť, keďže viaceré pravidlá majú rovnakú pravú stranu (sú rovnako definoané)

Možno to urobiť jednoduchou substitúciou Okrem uvedených dvoch transformácií sú aj

ďalšie, ale tými sa zaoberať nebudeme. Pre programovacie jazyky vystačíme s uvedenými pravidlami

Príklad – zednodušenie pravidiel

Gramatika:1. E T E’ 2. E’ + T E’3. E’ e4. T F T’5. T’ * F T’6. T’ e7. F ( E )8. F a

Syntaktická analýza pre LL gramatiky Ide o SA zhora nadol – hovoríme tiež o vetnom

rozbore (zhora nadol) Modelom je ZA – ale deterministický Keďže stav ZA (je iba 1) nemal vplyv na

rozhodovaní „čo robiť“, ZA automat, ako model, sa reprezentuje formou procedúry – algoritmu a hovoríme o algoritme rozboru

Vzhľadom na podmienenosť determinizmu znalosťou ďalších k symbolov zo vstupu, algortimus sa nazýva k-prediktívny algoritmus rozboru A

Reprezentácia algoritmu rozboru

Reprezentácia vychádza zo ZA a používa: Vopred prezretý reťazec u vstupný a výstupný reťazec Zásobník Z : N T { } - je

začiatočný symbol Riadiacu tabuľku M – reprezentuje zo ZA Konfiguráciu algoritmu – na opis činnosti

Riadiaca tabuľka

M: Z x T*k {( , i), vylúčenie, prijatie, chyba}

Kde (N T )*

i je číslo pravidla s pravou stranou vylúčenie znamená – vylúčenie vrchu zásobníka

prijatie znamená úspešné ukončenie analýzy

chyba znamená neúspečné ukončenie analýzy

Konfigurácia

Pod konfiguráciou prediktívneho algoritmu rozboru sa rozumie trojica

( x, X, ) Kdex je doteraz nespracovaná časť vstupu,X je obsah zásobníka – X je vrchný symbol

zasobníka je doterajší výstup – postupnosť pravidiel (čísel)

použitých v ľavej derivácii doteraz spracovanej časti vstupu

Činnosť

Opisuje sa pomocou relácie prechodu Používa vopred prezretý reťazec u1. ( x, X, ) ( x, , i )

ak M(X,u)= (, i)2. ( ax, a, ) ( x, , ) ak

M(X,u)= vylúčenie3. (e, , ) konfigurácia prijatia

M( ,e) = prijatie4. (x, X, ) chybová konfigurácia ak

M(X, u) = chyba

Stupeň relácie prechodu, uzávery

Stupeň a uzávery relácie prechodu sú definované rovnako ako pri ZA

Začiatočná konfigurácia: (w, S, e) Koncová konfigurácia: (e, , ) Rozpoznanie: (w, S, e) * (e, , ) -

potom je ľavým rozborom Zápis: A(w) =

Syntaktická analýza pre LL(1) G – konštrukciaVstup: LL(1) gramatika G = (N, T, P, S) s očíslovanými

pravidlamiVýstup: tabuľka rozboru M1. Ak A P s číslom i, potom M(A, a) = ( ,

i) pre všetky a e, ktoré sú z FIRST1( ). Ak e FIRST1( ), tak M(A, b) =( ,i) pre všetky b FOLLOW1(A)

2. M(x, x) = vylúčenie pre všetky x T3. M( ,e) = prijatie4. M(X, x) = chyba vo všetkých ostatných prípadoch X N

T { }, x N {e}

Príklad

Vrátime sa zase ku gramatike, ktorú sme transformovali na LL(1)

1. E T E’ 2. E’ + T E’3. E’ e4. T F T’5. T’ * F T’6. T’ e7. F ( E )8. F a

Tabuľka MM + * ( ) a e

E (TE’, 1) (TE’, 1)

E’ (+TE’, 2) (e, 3) (e, 3)

T (FT’, 4) (FT’, 4)

T’ (e, 6) (*FT’, 5) (e, 6) (e, 6)

F (E, 7) (E, 8)

+ V

* V

( V

) V

a V

P

Zdôvodnenie

E: FIRST1(T E’) = {}.

T E’ FT’E’ (E)T’E’ teda “(“ je v {}

aT’E’ teda aj “a” je v {}

FIRST1(T E’) = {(, a} preto

M(E, () = (TE’, 1)

M(E, a) = (TE’, 1)

Zdôvodnenie Cont

E’: máme 2 pravidlá: E’ + T E’

FIRST1(+T E’) = {+}

E’ e FIRST1(e) = {e} musíme

preto vyčísliť FOLLOW1(E’) E TE’ teda tam patrí „e“ (prvý symbol za E’)E T E’ FT’E’ (E)T’E’ (TE’)T’E’ teda tam patrí aj

“)” (znova prvý symbol za E’)

FOLLOW1(E’) = {e, )}Analogicky zvyšok.

Výpočet hodnoty funkcie FIRST

Aj teraz budeme hľadať konštruktívny výpočet na základe pravidiel gramatiky

Najprv si zavedieme funkciu „sčítania“ reťazcov ⊕k

Využijeme obmedzenie dĺžky výsledného reťazca na dĺžku k. Preto aj operátor bude mať index udávajúci dĺžku výsledného reťazca

Operácia ⊕

Nech T je množina terminálnych symbolov a L1 T*, L2 T* . Potom nad L1a L2 operáciu ⊕k definujeme nasledujúcim spôsobom:

L1 ⊕k L2 = {w / w = xy ak | xy | k inak w pozostáva z prvých k symbolov reťazca xy, pre nejaké x L1a y L2 }

Vzťah funkcie FIRST a operácie ⊕k

Ak G = (N, T, P, S) je BKG a , (N T)*

Potom

FIRSTk( ) = FIRSTk() ⊕k FIRSTk()

Poznámka: Práve uvedenú vlastnoť funkcie FIRST a operácie ⊕k využívame na výpočet hodnoty funkcie FIRST

Výpočet hodnoty funkcie FIRST

Vstup:BKG G = (N, T, P, S) a reťazec , pričom ho budeme písať v tvare X1X2 ...Xn

Výstup: FIRSTk()

Postup: PredpokladFIRSTk() = FIRSTk(X1) ⊕kFIRSTk(X2) ⊕k ...⊕k FIRSTk(Xn)

Dôsledok: ak Xi T {e} tak FIRSTk(Xi) = {Xi}

V ďalšom skrátime zápis FIRSTk iba na F

Postup výpočtu

1. Fi(a) = {a} pre všetky a T, i 0

2. F0(A) = {x / x T*k a v P existuje pravidlo A x pre ktoré je | x | = k , alebo | x | k a = e}

3. Predpokladajme, že F0, F1, ... , Fi-1 je spočítané pre všetky A N. Potom Fi(A) = Fi-1(A) {x / A Y1Y2 … Yn P a x Fi-1(Y1) ⊕k Fi-1(Y2) ⊕k … ⊕k Fi-1(Yn) }

4. Pretože Fi-1(A) Fi(A) T*k pre všetky A a i, musíme v konečnom dôsledku prísť k takému i, že Fi-1(A) = Fi(A) pre veštky A N. Potom FIRSTk(A) = Fi(A)

Príklad

Zoberme znova gramatiku, ktorú sme transformovali na LL(1)

E T E’

E’ + T E’ | e

T F T’

T’ * F T’ | e

F ( E ) | a

Postup pre i= 0

i= 0: F0(E) =

F0(E’) = { +, e }

F0(T) =

F0(T’) = { *, e }

F0(F) = { (, a }

Postup pre i= 1

i= 1: F1(E) = F0(E) F0(T) ⊕1 F0(E’) =

F1(E’) = {+, e } F0(+) ⊕1 F0(T) ⊕1 F0(E’) F0(e)

= { +, e }

F1(T) = F0(T) F0(F) ⊕1 F0(T’) = { (, a }

F1(T’) = F0(T’) F0(*) ⊕1 F0(F) ⊕1 F0(T’) F0(e)

= { *, e }

F1(F) = F0(F) F0(() ⊕1 F0(E) ⊕1 F0()) F0(a) = { (, a }

Postup pre i= 2

i= 2: F2(E) = F1(E) F1(T) ⊕1 F1(E’) = { (, a }

F2(E’) = {+, e } F1(+) ⊕1 F1(T) ⊕1 F1(E’) F1(e)

= { +, e }

F2(T) = F1(T) F1(F) ⊕1 F1(T’) = { (, a }

F2(T’) = F1(T’) F1(*) ⊕1 F1(F) ⊕1 F1(T’) F1(e)

= { *, e }

F2(F) = F1(F) F1(() ⊕1 F1(E) ⊕1 F1()) F1(a) = { (, a }

Postup pre i= 3

F3(X) = F2(X) preto

FIRST1(E) = { (, a }

FIRST1(E’) = { +, e }

FIRST1(T) = { (, a }

FIRST1(T’) = { *, e }

FIRST1(F) = { (, a }

OK

top related