Metody a nástroje syntaktické analýzy Šárka Vavrečková Ústav informatiky, FPF SU Opava sarka.vavreckova@fpf.slu.cz Poslední aktualizace: 14. října 2011
Vlastnosti syntaktické analýzy Úkoly syntaktické analýzy Úkolem syntaktického analyzátoru je zjistit, jak symboly patří k sobě, tedy sestavit syntaktickou strukturu programu. Symboly jsou zde jakýmisi slovy, ze kterých je třeba sestavit větu strukturu programu. Vstup: posloupnost symbolů Výstup: syntaktická struktura programu (derivační strom) Syntaktické chyby: souvisí se syntaktickou strukturou celého programu, chybná posloupnost symbolů (např. 25 := x + 1)
Vlastnosti syntaktické analýzy Úkoly syntaktické analýzy Úkolem syntaktického analyzátoru je zjistit, jak symboly patří k sobě, tedy sestavit syntaktickou strukturu programu. Symboly jsou zde jakýmisi slovy, ze kterých je třeba sestavit větu strukturu programu. Vstup: posloupnost symbolů Výstup: syntaktická struktura programu (derivační strom) Syntaktické chyby: souvisí se syntaktickou strukturou celého programu, chybná posloupnost symbolů (např. 25 := x + 1)
Definice Definice (Derivační strom) Derivační strom derivace podle gramatiky G je orientovaný acyklický graf, který má jediný kořen, do všech ostatních uzlů vstupuje právě jedna hrana, a dále má tyto vlastnosti: 1 Kořen stromu je ohodnocen startovacím symbolem gramatiky. 2 Listy jsou ohodnoceny terminálními symboly, všechny ostatní uzly jsou ohodnoceny neterminálními symboly. 3 Všechny koncové uzly v jakékoliv fázi konstrukce čtené zleva doprava tvoří větnou formu v gramatice G. 4 Jestliže uzly n 1, n 2,..., n k jsou bezprostřední následníci uzlu n, jsou ohodnoceny symboly 1, 2,..., k a uzel n je ohodnocen, pak v množině pravidel gramatiky existuje pravidlo 1 2... k. Není třeba značit orientaci hran.
Konstrukce G = ({S}, {n, i, +, }, P, S), P = {S S + S S S n i} Derivace D1: S S S => S + S S n + S S n + n S n + n i Derivace D2: S S S => S + S S S + S i S + n i n + n i Derivace D3: S S + S => S + S S n + S S n + n S n + n i D1, D2: S S S S + S i D3: S + S n S S S n n n i
Konstrukce G = ({S}, {n, i, +, }, P, S), P = {S S + S S S n i} Derivace D1: S S S => S + S S n + S S n + n S n + n i Derivace D2: S S S => S + S S S + S i S + n i n + n i Derivace D3: S S + S => S + S S n + S S n + n S n + n i D1, D2: S S S S + S i D3: S + S n S S S n n n i
Konstrukce G = ({S}, {n, i, +, }, P, S), P = {S S + S S S n i} Derivace D1: S S S => S + S S n + S S n + n S n + n i Derivace D2: S S S => S + S S S + S i S + n i n + n i Derivace D3: S S + S => S + S S n + S S n + n S n + n i D1, D2: S S S S + S i D3: S + S n S S S n n n i
Konstrukce G = ({S}, {n, i, +, }, P, S), P = {S S + S S S n i} Derivace D1: S S S => S + S S n + S S n + n S n + n i Derivace D2: S S S => S + S S S + S i S + n i n + n i Derivace D3: S S + S => S + S S n + S S n + n S n + n i D1, D2: S S S S + S i D3: S + S n S S S n n n i
Konstrukce G = ({S}, {n, i, +, }, P, S), P = {S S + S S S n i} Derivace D1: S S S => S + S S n + S S n + n S n + n i Derivace D2: S S S => S + S S S + S i S + n i n + n i Derivace D3: S S + S => S + S S n + S S n + n S n + n i D1, D2: S S S S + S i D3: S + S n S S S n n n i
Konstrukce Jednoznačnost gramatiky Definice (Jednoznačná a víceznačná gramatika) Gramatika je jednoznačná, pokud pro každý terminální řetězec, který lze v gramatice vygenerovat (tj. větu), existuje právě jeden derivační strom. Gramatika je víceznačná, pokud existuje terminální řetězec patřící do jazyka této gramatiky, ke kterému lze sestrojit více různých derivačních stromů. Zajištění jednoznačnosti podmínkou pro derivaci Když v každém kroku derivace přepisujeme vždy nejlevější neterminál (ten, který je ve větné formě nejvíce vlevo), používáme levou derivaci, když přepisujeme vždy neterminál nejvíce v pravo, používáme pravou derivaci.
Konstrukce Jednoznačnost gramatiky Definice (Jednoznačná a víceznačná gramatika) Gramatika je jednoznačná, pokud pro každý terminální řetězec, který lze v gramatice vygenerovat (tj. větu), existuje právě jeden derivační strom. Gramatika je víceznačná, pokud existuje terminální řetězec patřící do jazyka této gramatiky, ke kterému lze sestrojit více různých derivačních stromů. Zajištění jednoznačnosti podmínkou pro derivaci Když v každém kroku derivace přepisujeme vždy nejlevější neterminál (ten, který je ve větné formě nejvíce vlevo), používáme levou derivaci, když přepisujeme vždy neterminál nejvíce v pravo, používáme pravou derivaci.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 1 shora dolů (Top-Down), začínáme startovacím symbolem, podle levé derivace (vždy nejlevější symbol), pravidla gramatiky: ve stromě z neterminálu tvoříme podřetězec, na který se přepisuje, strom konstruujeme podle derivace zleva doprava, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 1 shora dolů (Top-Down), začínáme startovacím symbolem, podle levé derivace (vždy nejlevější symbol), pravidla gramatiky: ve stromě z neterminálu tvoříme podřetězec, na který se přepisuje, strom konstruujeme podle derivace zleva doprava, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 1 shora dolů (Top-Down), začínáme startovacím symbolem, podle levé derivace (vždy nejlevější symbol), pravidla gramatiky: ve stromě z neterminálu tvoříme podřetězec, na který se přepisuje, strom konstruujeme podle derivace zleva doprava, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 1 shora dolů (Top-Down), začínáme startovacím symbolem, podle levé derivace (vždy nejlevější symbol), pravidla gramatiky: ve stromě z neterminálu tvoříme podřetězec, na který se přepisuje, strom konstruujeme podle derivace zleva doprava, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 1 shora dolů (Top-Down), začínáme startovacím symbolem, podle levé derivace (vždy nejlevější symbol), pravidla gramatiky: ve stromě z neterminálu tvoříme podřetězec, na který se přepisuje, strom konstruujeme podle derivace zleva doprava, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Rozdělení Metody syntaktické analýzy Dvě základní metody Rozlišujeme podle směru konstrukce derivačního stromu metody 2 zdola nahoru (Bottom-Up). začínáme odspoda, od terminálního slova, podle pravé derivace, stavíme strom směrem k startovacímu symbolu, pravidla gramatiky: ve stromě nahrazujeme podřetězec neterminálem, který se na něj přepisuje, strom konstruujeme podle derivace pozpátku, zprava doleva, vstup čteme zleva doprava.
Příklad Příklad S B ab ab B cb c 1 2, 3 4, 5 Levá derivace: S B abb aabbb aabbcb aabbcc
Příklad S B abb aabbb aabbcb aabbcc S B
Příklad S B abb aabbb aabbcb aabbcc S S B B a b
Příklad S B abb aabbb aabbcb aabbcc S S B B a b S B a b a b
Příklad S B abb aabbb aabbcb aabbcc S S B B a b S S B B a b a b c B a b a b
Příklad S B abb aabbb aabbcb aabbcc S S B B a b S S S B B B a b a b c B a b c B a b a b a b c
Definice Definice výstupu Definice (Lineární rozklad, levý rozklad) Lineární rozklad věty v gramatice G je některá posloupnost čísel pravidel použitých v derivaci věty v gramatice G. Levý rozklad věty v gramatice G je posloupnost čísel pravidel použitých v levé derivaci této věty v gramatice G.
Definice Příklad S B ab ab B cb c 1 2, 3 4, 5 Levá derivace: S B abb aabbb aabbcb aabbcc Levý rozklad slova aabbcc je posloupnost 1, 2, 3, 4, 5.
Definice Definice analýzy Definice ( metodou shora dolů) metodou shora dolů je proces nalezení levého rozkladu dané věty.
Determinismus Řešení nedeterminismu α 1 α 2... α n 1. nalýza s návratem Postupně zkoušíme vhodná pravidla. Nejdřív první, pokračujeme dále ve výpočtu, a když se ukáže, že pravidlo nevyhovuje (dostaneme se do slepé uličky), vrátíme se zpátky a vyzkoušíme druhé pravidlo, když to nevyhovuje, tak třetí,... Pomalá, proto se moc nepoužívá. 2. Deterministická analýza Při výběru pravidla se řídíme dalšími informacemi. 1 kontrolujeme vstupní posloupnost symbolů a řídíme se tím, co později dostaneme na vstupu, 2 kontrolujeme obsah zásobníku (nejen ten symbol, který vyjímáme v každém kroku).
Determinismus Řešení nedeterminismu α 1 α 2... α n 1. nalýza s návratem Postupně zkoušíme vhodná pravidla. Nejdřív první, pokračujeme dále ve výpočtu, a když se ukáže, že pravidlo nevyhovuje (dostaneme se do slepé uličky), vrátíme se zpátky a vyzkoušíme druhé pravidlo, když to nevyhovuje, tak třetí,... Pomalá, proto se moc nepoužívá. 2. Deterministická analýza Při výběru pravidla se řídíme dalšími informacemi. 1 kontrolujeme vstupní posloupnost symbolů a řídíme se tím, co později dostaneme na vstupu, 2 kontrolujeme obsah zásobníku (nejen ten symbol, který vyjímáme v každém kroku).
Příklad Příklad S B ab ab B cb c 1 2, 3 4, 5 Pravá derivace: S B cb cc abcc aabbcc
Příklad S B cb cc abcc aabbcc a a b b c c
Příklad S B cb cc abcc aabbcc a a b b c c a a b b c c
Příklad S B cb cc abcc aabbcc a a b b c c a a b b c c B a a b b c c
Příklad S B cb cc abcc aabbcc a a b b c c a a b b c c B B B a a b b c c a a b b c c
Příklad S B cb cc abcc aabbcc a a b b c c a a b b c c S B B B B B a a b b c c a a b b c c a a b b c c
Definice Definice (Pravý rozklad) Pravý rozklad věty v gramatice G je obrácená posloupnost čísel pravidel použitých v pravé derivaci této věty v gramatice G.
Definice Příklad S B ab ab B cb c 1 2, 3 4, 5 Pravá derivace: S B cb cc abcc aabbcc V derivaci jsme použili postupně pravidla 1, 4, 5, 2, 3, pravý rozklad věty aabbcc posloupnost čísel 3, 2, 5, 4, 1.
Definice Definice ( metodou zdola nahoru) metodou zdola nahoru je proces nalezení pravého rozkladu dané věty.
Determinismus Řešení nedeterminismu pravidla, jejichž pravé strany stejně začínají, resp. podřetězce na vstupu 1. nalýza s návratem Vybereme ve větné formě podřetězec (co nejvíc vlevo, je co nejdelší a je shodný s pravou stranou některého pravidla), přepíšeme neterminálem na pravé straně pravidla a pokračujeme v konstrukci derivačního stromu. Když zjistíme, že tento krok nevede k úspěchu, vyzkoušíme jiný podřetězec,... Pomalé, nepoužíváme. 2. Deterministická analýza Využíváme další informace získané při překladu obsah nepřečtené části vstupní pásky nebo obsah zásobníku.
Determinismus Řešení nedeterminismu pravidla, jejichž pravé strany stejně začínají, resp. podřetězce na vstupu 1. nalýza s návratem Vybereme ve větné formě podřetězec (co nejvíc vlevo, je co nejdelší a je shodný s pravou stranou některého pravidla), přepíšeme neterminálem na pravé straně pravidla a pokračujeme v konstrukci derivačního stromu. Když zjistíme, že tento krok nevede k úspěchu, vyzkoušíme jiný podřetězec,... Pomalé, nepoužíváme. 2. Deterministická analýza Využíváme další informace získané při překladu obsah nepřečtené části vstupní pásky nebo obsah zásobníku.
Souhrn Pomocné množiny pro syntaktickou analýzu FIRST(α) množina terminálů, kterými mohou začínat řetězce odvozené z α α bxayγ = b FIRST(α) FOLLOW() množina terminálů, které mohou následovat za v některé větné formě v derivacích. S bxcyz = y FOLLOW() Vytváříme vždy pro všechny neterminály zároveň!!! FIRST k (α), FOLLOW k () podobné, jen zobecnění na množiny terminálních řetězců o délce nejvýše k
Souhrn Pomocné množiny pro syntaktickou analýzu FIRST(α) množina terminálů, kterými mohou začínat řetězce odvozené z α α bxayγ = b FIRST(α) FOLLOW() množina terminálů, které mohou následovat za v některé větné formě v derivacích. S bxcyz = y FOLLOW() Vytváříme vždy pro všechny neterminály zároveň!!! FIRST k (α), FOLLOW k () podobné, jen zobecnění na množiny terminálních řetězců o délce nejvýše k
Souhrn Pomocné množiny pro syntaktickou analýzu FIRST(α) množina terminálů, kterými mohou začínat řetězce odvozené z α α bxayγ = b FIRST(α) FOLLOW() množina terminálů, které mohou následovat za v některé větné formě v derivacích. S bxcyz = y FOLLOW() Vytváříme vždy pro všechny neterminály zároveň!!! FIRST k (α), FOLLOW k () podobné, jen zobecnění na množiny terminálních řetězců o délce nejvýše k
FIRST, FOLLOW Pomocné množiny pro syntaktickou analýzu Definice (Množiny FIRST) Označme α libovolnou větnou formu generovanou gramatikou G. Potom FIRST(α) je množina terminálních symbolů, jimiž začínají řetězce derivované z α. Pokud existuje derivace α ε, pak ε FIRST(α).
FIRST, FOLLOW Pomocné množiny pro syntaktickou analýzu Definice (Množiny FOLLOW) Nechť je libovolný neterminál gramatiky G. Potom do množiny FOLLOW() řadíme právě ty terminální symboly a gramatiky G, které se mohou vyskytovat bezprostředně vpravo od v nějaké větné formě, tedy existuje derivace S βaγ. Pokud je v některé derivaci symbol posledním symbolem větné formy, do množiny FOLLOW() řadíme také symbol ukončení vstupního řetězce (reprezentující například konec zdrojového souboru), který budeme značit $.
FIRST, FOLLOW Označme N 1 množinu všech neterminálních symbolů, pro které existuje ε-pravidlo (nejen přímo ε). V gramatice G = (N, T, P, S): FIRST(ε) = {ε} FIRST(aβ) = {a}, a T FIRST(β) = FIRST(α i ) i=1..n pro / N 1, α 1 α 2... α n, ( ) FIRST(β) = FIRST(α i ) {ε} FIRST(β) i=1..n pro N 1, α 1 α 2... α n
FIRST, FOLLOW Příklad FIRST G = (N, T, P, S) S ab BcB ε fabd as ε B bcb d FIRST(ab) = {a} FIRST(BcB) = {b, d} FIRST(cB) = {f, a, c} FIRST(S) = {a, b, d, ε} FIRST(S) = {f, a, b, d, ε}
FIRST, FOLLOW V gramatice G = (N, T, P, S): $ FOLLOW(S) FIRST(β) FOLLOW(B), kde αbβ FOLLOW() FOLLOW(B), kde αbβ, β ε
FIRST, FOLLOW 1) Do FOLLOW(S), kde S je startovací symbol gramatiky, vložíme symbol konce vstupního řetězce $. 2) Pro všechna pravidla gramatiky αbβ umístíme všechny prvky množiny FIRST(β) kromě ε do FOLLOW(B). Tento krok provádíme postupně pro všechna pravidla gramatiky hledáme v nich neterminály, za kterými ještě něco následuje (β), a pak vše, čím může začínat řetězec vytvořený z β, může následovat v nějaké větné formě přímo za B. 3) Rekurzívně, dokud dochází ke změnám: pro každé pravidlo αb nebo αbβ, kde existuje odvození β ε, do množiny FOLLOW(B) zařadíme všechny prvky FOLLOW(). Obsah množin FOLLOW vlastně posíláme po derivačním stromě větné formy směrem dolů vždy nejvíce vpravo, pokud je na tom místě neterminál.
FIRST, FOLLOW 1) Do FOLLOW(S), kde S je startovací symbol gramatiky, vložíme symbol konce vstupního řetězce $. 2) Pro všechna pravidla gramatiky αbβ umístíme všechny prvky množiny FIRST(β) kromě ε do FOLLOW(B). Tento krok provádíme postupně pro všechna pravidla gramatiky hledáme v nich neterminály, za kterými ještě něco následuje (β), a pak vše, čím může začínat řetězec vytvořený z β, může následovat v nějaké větné formě přímo za B. 3) Rekurzívně, dokud dochází ke změnám: pro každé pravidlo αb nebo αbβ, kde existuje odvození β ε, do množiny FOLLOW(B) zařadíme všechny prvky FOLLOW(). Obsah množin FOLLOW vlastně posíláme po derivačním stromě větné formy směrem dolů vždy nejvíce vpravo, pokud je na tom místě neterminál.
FIRST, FOLLOW 1) Do FOLLOW(S), kde S je startovací symbol gramatiky, vložíme symbol konce vstupního řetězce $. 2) Pro všechna pravidla gramatiky αbβ umístíme všechny prvky množiny FIRST(β) kromě ε do FOLLOW(B). Tento krok provádíme postupně pro všechna pravidla gramatiky hledáme v nich neterminály, za kterými ještě něco následuje (β), a pak vše, čím může začínat řetězec vytvořený z β, může následovat v nějaké větné formě přímo za B. 3) Rekurzívně, dokud dochází ke změnám: pro každé pravidlo αb nebo αbβ, kde existuje odvození β ε, do množiny FOLLOW(B) zařadíme všechny prvky FOLLOW(). Obsah množin FOLLOW vlastně posíláme po derivačním stromě větné formy směrem dolů vždy nejvíce vpravo, pokud je na tom místě neterminál.
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d 1) 2) 3) 4) 5) 6) 7) 8) FOLLOW(S) = { $, b, c } FOLLOW() = { b, c } FOLLOW(B) = { f, a, c, d, $, b }
FIRST, FOLLOW Příklad S ab BcB ε fabd as ε B bcb d FOLLOW(S) = {$, b, c} FOLLOW() = {b, c} FOLLOW(B) = {f, a, c, d, $, b}