Překladače 5. Syntaktická analýza Obsah: vstup a výstup syntaktické analýzy derivační strom, odvození z gramatiky determinismus, víceznačné gramatiky metoda shora dolů a zdola nahoru řešení nejednoznačnosti pomocné množiny FIRST a FOLLOW © Milan Keršláger http://www.pslib.cz/ke/slajdy 28. 3. 2012 http://creativecommons.org/licenses/by-nc-nd/3.0/
Syntaktická analýza druhá fáze zpracování zdrojového kódu vstup: posloupnost symbolů dodává lexikální analyzátor výstup: derivační strom postihuje strukturu programu syntaktické chyby nesprávná posloupnost symbolů: 13:=celkem if a=1 else y:=x then y=a+1
Derivační strom derivační strom derivace v gramatice G je orientovaný acyklický graf s jediným kořenem do všech všech uzlů vstupuje 1 hrana (kromě kořene) kořen je ohodnocen startovacím symbolem gramatiky koncové uzly stromu → terminální symbol nebo ε ε – prázdný řetězec ostatní uzly ohodnoceny neterminálními symboly koncové uzly čtené zleva doprava tvoří větnou formu v gramatice G v kterékoliv fázi konstrukce derivační strom tvoříme zleva doprava a shora dolů, proto není potřeba značit orientaci hran
Příklad Máme bezkontextovou gramatiku G s pravidly P: G = ({S},{n,i,+,*},P,S) P = S → S+S | S*S | n | i Odvodíme větu n+n*i třemi různými derivacemi: D1: S → S*S → S+S*S → n+S*S → n+n*S → n+n*i D2: S → S*S → S+S*S → S+S*i → S+n*i → n+n*i D3: S → S+S → S+S*S → n+S*S → n+n*S → n+n*i
Derivace D1 S → S*S → S+S*S → n+S*S → n+n*S → n+n*i S S * S S + S i n
Derivace D2 S → S*S → S+S*S → S+S*i → S+n*i → n+n*i S S * S S + S i n
Derivace D3 S → S+S → S+S*S → n+S*S → n+n*S → n+n*i S S + S n S * S n
Porovnání derivačních stromů * S S + S S + S i n S * S n n n i Derivace D1 a D2 Derivace D3
Determinismus pro tutéž větu může existovat více der. stromů viz výše D1 a D3 různé derivace mohou mít stejný der. strom viz výše D1 a D2 → nedeterministický postup naprosto nevhodné pro programování algoritmus musí být deterministický determinismus → jednoznačnost gramatiky programovací jazyky bohužel takové nejsou gramatiky pro ně jsou víceznačné
Gramatiky jedno- a víceznačné jednoznačná gramatika pro každý terminální řetězec generovaný gramatikou existuje jeden derivační strom špatně se hledají víceznačná gramatika existuje terminální řetězec patřící do jazyka gramatiky, ke kterému lze sestrojit více der. stromů jednoznačnost dosáhneme stanovením dodatečných podmínek pro vytvoření derivace levá derivace → v řetězci přepisujeme nejlevější neterminál pravá derivace → přepisujeme neterminál nejvíce vpravo
Metody syntaktické analýzy metodu syntaktické analýzy definujeme podle postupu konstrukce derivačního stromu: metoda shora dolů (Top-Down) konstruujeme od kořene k listům a zleva doprava metoda zdola nahoru (Bottom-Up) postupujeme od listů ke kořeni, také zleva doprava
Příklad S → AB 1 A → aAb | ab 2, 3 B → cB | c 4, 5 přepisovací pravidla čísla pravidel S → AB 1 A → aAb | ab 2, 3 B → cB | c 4, 5 pro obě metody odvodíme aabbcc stačí ukládat čísla použitých pravidel zjednodušení výstupu syntaktické analýzy není nutné mít v paměti celý strom volbou použité metody definujeme LP derivaci → posloupnost je jednoznačná
Metoda shora dolů pravidla: S → AB 1 A → aAb | ab 2, 3 B → cB | c 4, 5 S → AB → aAbB → aabbB → aabbcB → aabbcc levý rozklad: 1, 2, 3, 4, 5 byla použita levá derivace derivační strom na následujícím obrázku
Metoda zdola nahoru pravidla: S → AB 1 A → aAb | ab 2, 3 B → cB | c 4, 5 aabbcc → aAbcc → Acc → AcB → AB → S pravý rozklad je obrácená posloupnost pravidel protože zprava doleva, ale automat čte zleva doprava automat tedy postup obrací (než je potřeba ke generování věty) pravý rozklad: 3, 2, 5, 4, 1 (použita pravá derivace) derivační strom na následujícím obrázku
aabbcc → aAbcc → Acc → AcB → AB → S
Řešení nejednoznačnosti program musí být deterministický při analýze hledáme pravidla pro vznik větné formy existují však pravidla se stejnou levou stranou (!) vzniká otázka, jaké pravidlo má být použito máme dvě možnosti analýza s návratem vyzkoušíme jedno z pravidel a když problém, vrátíme se příliš pomalé deterministická analýza nahlížení na další vstupující znak nebo kontrola symbolu(ů) pod vrcholem zásobníku používá se běžně
Pomocné množiny FIRST(α) α je libovolná větná forma generovaná gramatikou G FIRST je množina terminálních symbolů, jimiž začínají řetězce derivované z α (terminály i neterminály) pokud existuje pravidlo α → *ε, pak ε patří do FIRST FOLLOW(A) A je neterminál gramatiky G FOLLOW je množina terminálních symbolů a, které se mohou vyskytovat bezprostředně vpravo od A existuje tedy derivace S → *βAaγ pokud je A ukončující, do FOLLOW též $ (konec vstupu) určuje se vždy pro všechny neterminály (mny. jsou vzájemně závislé)
FIRSTK a FOLLOWK pro složitější gramatiky k určuje délku terminálních řetězců řazených do hledané množiny bez indexu uvažujeme k=1 u vyšších čísel nese množina více informací FIRST(Ba) – začínající na c nebo a FIRST2(BA) – umí například omezit začínající na c tak, že víme, že to může být cc nebo ca, ale ne však cb