141
UČEBNÍ TEXTY VYSOKÝCH ŠKOL Vysoké učení technické v Brně Fakulta elektrotechniky a informatiky Prof. RNDr. Milan Češka, CSc. Gramatiky a jazyky

U¨EBN˝ TEXTY VYSOKÝCH 'KOL

  • Upload
    others

  • View
    16

  • Download
    0

Embed Size (px)

Citation preview

Page 1: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

UČEBNÍ TEXTY VYSOKÝCH ŠKOL

Vysoké učení technické v Brně Fakulta elektrotechniky a informatiky

Prof. RNDr. Milan Češka, CSc.

Gramatiky a jazyky

Page 2: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Tato skripta jsou určena pro kurs Základy matematické informatiky I v 5. se-mestru studia na oboru Informatika a výpočetní technika elektrotechnické fakultyVUT v Brně.

Skripta obsahují základy teorie formálních jazyků, která má důležité aplikacev řadě oblastí počítačového inženýrství. Základní pojmy a poznatky teorie regulár-ních a bezkontextových jazyků, ústící v metody jejich syntaktické analýzy, jsou pre-rekvizicí pro studium překladačů programovacích jazyků, pro některé metody uměléinteligence i pro studium vyčíslitelnosti a algoritmické složitosti.

Způsob výkladu, použitý ve skriptech, předpokládá některé znalosti z diskrétnímatematiky. Vhodným doplňujícím a rozšiřujícím textem pro tato skripta jsou Gra-matiky a jazyky – cvičení (Češka M., Hruška T., ES VUT Brno 1988, skriptumFE VUT v Brně).

V Brně 14. 6. 1992

Autoři

c© Doc. RNDr. Milan Češka, CSc., Doc. Ing. Zdena Rábová, CSc.

Page 3: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Obsah

1 Úvod 1

2 Jazyky, gramatiky a jejich klasifikace 3

2.1 Jazyky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2 Gramatika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3 Chomského klasifikace gramatik . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.4 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Jazyky typu 3 Chomského klasifikace 13

3.1 Regulární množiny a jazyky typu 3 . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2 Jazyky přijímané konečnými automaty a jazyky typu 3 . . . . . . . . . . . . . . 15

3.3 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Bezkontextové jazyky 27

4.1 Derivační strom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.2 Fráze větné formy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.3 Víceznačnost gramatik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4.4 Rozklad věty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.5 Transformace bezkontextových gramatik . . . . . . . . . . . . . . . . . . . . . . 37

4.6 Chomského normální forma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.7 Greibachova normální forma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.8 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

5 Zásobníkové automaty a jejich vztah k bezkontextovým jazykům 53

5.1 Základní definice zásobníkového automatu . . . . . . . . . . . . . . . . . . . . . 54

5.2 Varianty zásobníkových automatů . . . . . . . . . . . . . . . . . . . . . . . . . . 56

i

Page 4: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

ii 0 0 1

5.3 Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty 59

5.4 Deterministický zásobníkový automat . . . . . . . . . . . . . . . . . . . . . . . . 65

5.5 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

6 Deterministické bezkontextové jazyky 69

6.1 Jednoduché precedenční gramatiky . . . . . . . . . . . . . . . . . . . . . . . . . 70

6.2 Výpočet precedenčních relací . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

6.3 Algoritmus syntaktické analýzy jednoduchých precedenčních jazyků . . . . . . . 74

6.4 Linearizace precedenční matice . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

6.5 Stratifikace gramatiky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

6.6 Jiné třídy precedenčních gramatik . . . . . . . . . . . . . . . . . . . . . . . . . . 82

6.7 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7 LL jazyky a jejich syntaktická analýza 85

7.1 Základní princip syntaktické analýzy LL jazyků . . . . . . . . . . . . . . . . . . 85

7.2 Výpočet množin FIRST a FOLLOW . . . . . . . . . . . . . . . . . . . . . . . . 88

7.3 Definice LL(k)-gramatiky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

7.4 Algoritmus syntaktické analýzy pro LL(k) gramatiky . . . . . . . . . . . . . . . 98

7.5 Problém transformace na L(1) gramatiku . . . . . . . . . . . . . . . . . . . . . . 102

7.6 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

8 LR jazyky a jejich syntaktická analýza 107

8.1 Definice LR(k) gramatiky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

8.2 Syntaktická analýza LR-jazyků . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

8.3 Konstrukce rozkladové tabulky . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.4 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

Literatura 132

Příloha 134

Page 5: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 1

Úvod

Teorie formálních jazyků představuje velmi důležitou oblast informatiky (computer science). Zá-klady novodobé historie této disciplíny položil v roce 1956 americký matematik Noam Chom-sky, který v souvislosti se studiem přirozených jazyků vytvořil matematický model gramatikyjazyka.

Realizace původních představ, formalizovat popis přirozeného jazyka takovým způsobem, abymohl být automatizován překlad z jednoho přirozeného jazyka do druhého nebo aby přirozenýjazyk sloužil jako prostředek komunikace člověka s počítačem, se ukázala velmi obtížnou a anisoučasné výsledky nejsou uspokojivé.

Začala se však vyvíjet vlastní teorie jazyků, která nyní obsahuje bohaté výsledky v podobě mate-maticky dokázaných tvrzení – teorémů. Tato teorie pracuje se dvěma duálními matematickýmientitami, s gramatikou a s automatem, představující abstraktní matematický stroj. Zatímcogramatika umožňuje popsat strukturu vět formálního jazyka, automat dovede tuto strukturuidentifikovat.

Poznatky teorie formálních jazyků mají význam pro mnohá odvětví kybernetiky. Dodávají algo-ritmy, jež jsou podkladem pro konstrukci reálných automatů zpracovávající informaci ve tvaruvět formálního jazyka. Stanovují však také možnosti a omezení algoritmických postupů řešeníproblémů; odhalují problémy, které jsou algoritmicky nerozhodnutelné, tj. problémy, jejichž ře-šení nelze dosáhnout v konečném čase.

Teorie formálních jazyků našla doposud největší uplatnění v oblasti programovacích jazyků.Krátce po Chomského definici gramatiky formálního jazyka a klasifikaci formálních jazyků(Chomského hierarchii formálních jazyků), Backus a Nauer použili základních objektů gra-matiky pro definici syntaxe programovacího jazyka Algol 60 (ve tvaru formalismu, jež se nazýváBackus-Nauerova forma). Další vývoj pak přímočaře vedl k aplikacím teorie jazyků v oblastipřekladačů programovacích jazyků. Stanovení principů syntaxí řízeného překladu a generátorůpřekladačů (programovacích systémů, které na základě formálního popisu syntaxe a sémantikyprogramovacího jazyka vytvoří jeho překladač) představuje kvalitativní skok při konstrukci pře-kladačů umožňující automatizovat náročnou programátorskou práci spojenou s implementacíprogramovacích jazyků.

1

Page 6: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

2 KAPITOLA 1. Úvod

Page 7: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 2

Jazyky, gramatiky a jejich klasifikace

2.1 Jazyky

Jedním ze základních pojmů pro vymezení jazyka jsou pojmy abeceda a řetězec.

Definice 2.1 Abecedou rozumíme neprázdnou množinu prvků, které nazýváme symboly abe-cedy.

V některých teoretických případech je účelné pracovat i s abecedami nekonečnými, v našichaplikacích se však omezíme na abecedy konečné.

Příklad 2.1 Jako příklady abeced můžeme uvést latinskou abecedu obsahující 52 symbolů, kteréreprezentují velká a malá písmena, řeckou abecedu, dvouprvkovou binární abecedu reprezento-vanou množinou {0, 1} resp. {true, false} nebo abecedy programovacích jazyků. Např. abecedaprogramovacího jazyka Algol 60 má 116 symbolů [11].

Definice 2.2 Řetězcem (také slovem nebo větou) nad danou abecedou rozumíme každou ko-nečnou posloupnost symbolů abecedy. Prázdnou posloupnost symbolů, tj. posloupnost, kteráneobsahuje žádný symbol, nazýváme prázdný řetězec. Prázdný řetězec budeme označovat písme-nem ε.

Formálně lze definovat řetězec nad abecedou Σ takto:

(1) prázdný řetězec ε je řetězec nad abecedou Σ,

(2) je-li x řetězec nad Σ a a ∈ Σ, pak xa je řetězec nad Σ,

(3) y je řetězec nad Σ, když a jen když lze y získat aplikací pravidel 1 a 2.

Příklad 2.2 Je-li A = {a, b,+} abeceda, pak

ε a b + aa a+ b + ab

jsou některé řetězce nad abecedou A. Pořadí symbolů v řetězci je významné; řetězce a+ b, +abjsou různé. Symbol b, například, je řetězec nad A, poněvadž εb = b.

3

Page 8: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

4 KAPITOLA 2. Jazyky, gramatiky a jejich klasifikace

Konvence 2.1 Budeme-li pracovat s obecnými abecedami, symboly, či řetězci, pak pro jejichznačení použijeme:

• velkých řeckých písmen pro abecedy,

• malých latinských písmen a, b, c, d, f, . . . pro symboly,

• malých latinských písmen t, u, v, w, . . . pro řetězce.

Nyní uvedeme některé důležité operace nad řetězci.

Definice 2.3 Nechť x a y jsou řetězce nad abecedou Σ. Konkatenací (zřetězením) řetězce xs řetězcem y vznikne řetězec xy připojením řetězce y za řetězec x. Operace konkatenace jezřejmě asociativní, tj. x(yz) = (xy)z, ne však komutativní, xy 6= yx.

Příklad 2.3 Je-li x = ab, y = ba, pak xy = abba, yx = baab, xε = εx = ab, kde ε je prázdnýřetězec.

Definice 2.4 Nechť x = a1a2 . . . an je řetězec nad abecedou Σ, ai ∈ Σ pro i = 1, . . . , n. Reverzí(zrcadlovým obrazem) řetězce x rozumíme řetězec xR = anan−1 . . . a2a1; tj. symboly řetězce xR

jsou vzhledem k řetězci x zapsány v opačném pořadí.

Příklad 2.4 Je-li x = abbc, pak xR = cbba. Zřejmě εR = ε.

Definice 2.5 Nechť w je řetězec nad abecedou Σ. Řetězec z se nazývá podřetězcem řetězce w,jestliže existují řetězce x a y takové, že w = xzy. Řetězec x1 se nazývá prefixem (předponou)řetězce w, jestliže existuje řetězec y1 takový, že w = x1y1. Analogicky, řetězec y2 se nazývásufixem (příponou) řetězce w, jestliže existuje řetězec x2 takový, že w = x2y2. Je-li y1 6= ε, resp.x2 6= ε, pak x1 je vlastní prefix, resp. y2 je vlastní sufix řetězce w.

Příklad 2.5 Je-li w = abbc, pak

ε a ab abb abbc

jsou všechny prefixy řetězce w (první čtyři jsou vlastní),

ε c bc bbc abbc

jsou všechny sufixy řetězce w (první čtyři jsou vlastní) a

a bb abb

jsou některé podřetězce řetězce w.

Zřejmě, prefix i sufix jsou podřetězce řetězce w, prázdný řetězec je podřetězcem, prefixem isufixem každého řetězce.

Definice 2.6 Délka řetězce je nezáporné celé číslo udávající počet symbolů řetězce. Délku ře-tězce x značíme symbolicky |x|. Je-li x = a1a2 . . . an, ai ∈ Σ pro i = 1, . . . n, pak |x| = n. Délkaprázdného řetězce je nulová, tj. |ε| = 0.

Konvence 2.2 Řetězec nebo podřetězec, který sestává právě z k výskytů symbolu a budemesymbolicky značit ak. Např.

a3 = aaa, b2 = bb, a0 = ε.

Page 9: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

2.1. Jazyky 5

Definice 2.7 Nechť Σ je abeceda. Označme symbolem Σ∗ množinu všech řetězců nad abecedouΣ včetně řetězce prázdného, symbolem Σ+ množinu všech řetězců nad Σ vyjma řetězce prázd-ného, tj. Σ∗ = Σ+ ∪ {ε}. Množinu L, pro níž platí L ⊆ Σ∗ (případně L ⊆ Σ+, pokud ε /∈ L),nazýváme jazykem L nad abecedou Σ. Jazykem tedy může být libovolná podmnožina řetězcůnad danou abecedou.

Příklad 2.6 Nechť jazyky L1 a L2 jsou definovány nad binární abecedou, tj. L1, L2 ⊆ {0, 1}∗,takto:

L1 = {0n1n | n ≥ 0} tj.

L1 = {ε, 01, 0011, 000111, . . .}L2 =

{xxR | x ∈ {0, 1}+

}tj.

L2 = {00, 11, 0000, 0110, 1001, 1111, . . .}

Příklad 2.7 Uvažujeme abecedu programovacího jazyka Pascal. Jazyk Pascal je nekonečnámnožina řetězců (programů) nad jeho abecedou, které lze odvodit z grafů syntaxe jazyka Pascal(viz. [13]). Např. řetězec

program P; begin end.

patří do jazyka Pascal (přestože nepopisuje žádnou akci), kdežto řetězec

procedure S; begin a := a mod b end

nepatří do jazyka Pascal, protože reprezentuje pouze úsek možného programu.

Povšimněme si nyní operací, které lze definovat nad jazyky. Tyto operace lze rozdělit do dvouskupin. Jednu skupinu představují obvyklé množinové operace plynoucí ze skutečnosti, že jazykje množina. Má tedy smysl mluvit o sjednocení, průniku, rozdílu a komplementu jazyků. Je-linapř. L1 jazyk nad abecedou Σ, pak jeho komplement (doplněk) L2 je jazyk, jenž je dán rozdílemL2 = Σ∗ − L1.

Druhá skupina operací respektuje specifikum množin tvořících jazyky, tj. skutečnost, že jejichprvky jsou řetězce. Z této skupiny definujeme operaci součinu a iterace jazyků.

Definice 2.8 Nechť L1 je jazyk nad abecedou Σ1, L2 jazyk nad abecedou Σ2. Součinem (kon-katenací) jazyků L1 a L2 je jazyk L1 · L2 nad abecedou Σ1 ∪ Σ2, jenž je definován takto:

L1 · L2 = {xy | x ∈ L1, y ∈ L2}

Operace součin jazyků je definována prostřednictvím konkatenace řetězců a má stejné vlastnostijako konkatenace řetězců – je asociativní a nekomutativní.

Příklad 2.8 Nechť:

P = {A,B, . . . , Z, a, b, . . . , z},C = {0, 1, . . . , 9} jsou abecedy

L1 = P,

L2 = (P ∪ C)∗ jsou jazyky

Součinem jazyků L1 · L2 je jazyk, který obsahuje všechny identifikátory, tak jak jsou obvykledefinovány v programovacích jazycích.

Page 10: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

6 KAPITOLA 2. Jazyky, gramatiky a jejich klasifikace

Prostřednictvím součinu jazyka se sebou samým (mocniny jazyka) můžeme definovat důležitouoperaci nad jazykem – iteraci jazyka.

Definice 2.9 Nechť L je jazyk nad abecedou Σ. Iteraci L∗ jazyka L a pozitivní iteraci L+

jazyka L definujeme takto:

L0 = {ε}(1)

Ln = L · Ln−1 pro n ≥ 1(2)

L∗ =⋃n≥0

Ln(3)

L+ =⋃n≥1

Ln(4)

Věta 2.1 Je-li L jazyk, pak platí:

L∗ = L+ ∪ {ε} a(1)

L+ = L · L∗ = L∗ · L(2)

Důkaz: Tvrzení 1 plyne z definice iterace a pozitivní iterace:

L+ = L1 ∪ L2 ∪ . . . , L∗ = L0 ∪ L1 ∪ L2 ∪ . . . tj.

L∗ − L+ = L0 = ε

Tvrzení 2 dostaneme provedením součinu L · L∗ resp. L∗ · L:

L · L∗ = L · (L0 ∪ L1 ∪ L2 ∪ . . .) = L1 ∪ L2 ∪ L3 ∪ . . . = L+,

s použitím distributivního zákona L1(L2∪L3) = L1L2∪L1L3. Podobně, s využitím ekvivalentnídefinice mocniny Ln = Ln−1L, n ≥ 0 obdržíme L∗ · L = L+. 2

Příklad 2.9 Je-li L1 = {(p}, L2 = {, p}, L3 = {)} potom jazyk L1 · L∗2 · L3 obsahuje řetězce:

(p) (p, p) (p, p, p) (p, p, p, p) . . .

2.2 Gramatika

Pojem gramatika souvisí velmi úzce s problémem reprezentace jazyka. Triviální způsob repre-zentace – výčet všech vět jazyka – je nepoužitelný nejen pro jazyky nekonečné, ale praktickyi pro rozsáhlé konečné jazyky. Také obvyklé matematické prostředky (použité v předchozíchpříkladech) jsou použitelné pouze pro reprezentaci jazyků s velmi jednoduchou strukturou.

Gramatika, jako nejznámější prostředek pro reprezentaci jazyků, splňuje základní požadavekkladený na reprezentaci konečných i nekonečných jazyků, požadavek konečnosti reprezentace.Používá dvou konečných disjunktních abeced:

(1) množiny N nonterminálních symbolů

(2) množiny Σ terminálních symbolů

Page 11: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

2.2. Gramatika 7

Nonterminální symboly, krátce nonterminály, mají roli pomocných proměnných označujícíchurčité syntaktické celky – syntaktické kategorie.

Množina terminálních symbolů, krátce terminálů, je identická s abecedou, nad níž je definovánjazyk. Sjednocení obou množin, tj. N ∪ Σ, nazýváme slovníkem gramatiky.

Konvence 2.3 Pro zápis terminálních a nonterminálních symbolů a řetězců tvořených těmitosymboly budeme používat této konvence:

(1) a, b, c, d reprezentují terminální symboly

(2) A,B,C,D, S reprezentují nonterminální symboly

(3) U, V, . . . , Z reprezentují terminální nebo nonterminální výrazy

(4) α, β, . . . , ω reprezentují řetězce terminálních a nonterminálních symbolů

(5) u, v, . . . , z reprezentují řetězce pouze terminálních symbolů

(6) řetězec uzavřený v úhlových závorkách 〈, 〉 reprezentuje nonterminální symbol (konvencepoužívaná v BNF).

Příklad 2.10 Slovník gramatiky pro definici jazyka identifikátorů může mít tvar:

N = {〈identifikátor〉, 〈písmeno〉, 〈číslice〉}

Σ = {A,B, . . . , Z, a, b, . . . , z, 0, 1, . . . , 9}

Obsahuje tedy 65 symbolů.

Gramatika představuje generativní systém, ve kterém lze z jistého vyznačeného nonterminálugenerovat, aplikací tzv. přepisovacích pravidel, řetězce tvořené pouze terminálními symboly.Takové řetězce reprezentují právě věty gramatikou definovaného jazyka.

Jádrem gramatiky je tak konečná množina P přepisovacích pravidel (nazývaných také produkce).Každé přepisovací pravidlo má tvar uspořádané dvojice (α, β) řetězců; stanovuje možnou sub-stitucí řetězce β namísto řetězce α, který se vyskytuje jako podřetězec generovaného řetězce.Řetězec α obsahuje alespoň jeden nonterminální symbol, řetězec βje prvek množiny (N ∪ Σ)∗.Formálně vyjádřeno, množina P přepisovacích pravidel je podmnožinou kartézského součinu:

(N ∪ Σ)∗N(N ∪ Σ)∗ × (N ∪ Σ)∗

Příklad 2.11 Uvažujme, že např. dvojice (AB,CDE) je jedním z přepisovacích pravidel gra-matiky a předpokládejme, že řetězec x = FGABH byl získán aplikací jiných pravidel gramatiky.Aplikujeme-li nyní na řetězec x pravidlo (AB,CDE), obdržíme řetězec y = FGCDEH (nahra-zením podřetězce AB řetězce x řetězcem CDE). Říkáme, že jsme řetězec y odvodili (derivovali)z řetězce x podle přepisovacího pravidla (AB,CDE).

Přistoupíme nyní k úplné definici gramatiky a formální definici pojmů, jejichž prostřednictvímlze definovat jazyk generovaný gramatikou.

Definice 2.10 Gramatika G je čtveřice G = (N,Σ, P, S), kde

• N je konečná množina nonterminálních symbolů

Page 12: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

8 KAPITOLA 2. Jazyky, gramatiky a jejich klasifikace

• Σ je konečná množina terminálních symbolů, N ∩ Σ = ∅

• P je konečná podmnožina kartézského součinu (N ∪ Σ)∗N(N ∪ Σ)∗ × (N ∪ Σ)∗,

• S ∈ N je výchozí (také počáteční) symbol gramatiky

Prvek (α, β) množiny P nazýváme přepisovacím pravidlem (krátce pravidlem) a budeme jejzapisovat ve tvaru α→ β. Řetězec α resp. β nazýváme levou resp. pravou stranou přepisovacíhopravidla.

Příklad 2.12G = ({A,S}, {0, 1}, P, S)

P = {S → 0A1, 0A→ 00A1, A→ ε}

Příklad 2.13 Gramatika definující jazyk identifikátorů může mít tvar:

G = (N,Σ, P, S), kde

N = {〈identifikátor〉, 〈písmeno〉, 〈číslice〉}Σ = {A,B, . . . , Z, a, b, . . . , z, 0, 1, . . . , 9}P = {〈identifikátor〉 → 〈písmeno〉,

〈identifikátor〉 → 〈identifikátor〉〈písmeno〉,〈identifikátor〉 → 〈identifikátor〉〈číslice〉,〈písmeno〉 → A,

...

〈písmeno〉 → Z,

〈číslice〉 → 0,...

〈číslice〉 → 9}S = 〈identifikátor〉

Množina P obsahuje 65 přepisovacích pravidel.

Konvence 2.4 Obsahuje-li množina pravidel P přepisovací pravidla tvaru α→ β1, α→ β2, . . . ,α→ βn, pak pro zkrácení lze použít zápisu α→ β1 | β2 | . . . | βn.

Definice 2.11 Nechť G = (N,Σ, P, S) je gramatika a nechť λ a µ jsou řetězce z (N ∪Σ)∗. Meziřetězci λ a µ platí relace ⇒G, nazývaná přímá derivace, jestliže můžeme řetězce λ a µ vyjádřitve tvaru

λ = γαδ

µ = γβδ

kde γ a δ jsou libovolné řetězce z (N ∪ Σ)∗ a α→ β je nějaké přepisovací pravidlo z P .

Platí-li mezi řetězci λ a µ relace přímé derivace, pak píšeme λ⇒G µ a říkáme, že řetězec µ lzepřímo generovat z řetězce λ v gramatice G. Je-li z kontextu zřejmé, že jde o derivaci v gramaticeG, pak nemusíme specifikaci gramatiky pod symbolem ⇒ uvádět.

Page 13: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 9

Příklad 2.14 Uvažujme gramatiku z příkladu 2.12 a řetězce λ = 000A111 a µ = 0000A1111.Položíme-li

λ = 00︸︷︷︸γ

0A︸︷︷︸α

111︸︷︷︸δ

µ = 00︸︷︷︸γ

00A1︸ ︷︷ ︸β

111︸︷︷︸δ

vidíme, že platí 000A111⇒ 0000A1111, protože 0A→ 00A1 je pravidlem v této gramatice.

Příklad 2.15 Je-li α→ β pravidlo v gramatice G, pak v této gramatice platí α⇒ β, jak plynez definice 2.11, položíme-li γ = δ = ε.

Definice 2.12 Nechť G = (N,Σ, P, S) je gramatika a λ a µ jsou řetězce z (N ∪ Σ)∗. Meziřetězci λ a µ platí relace ⇒+ nazývaná derivace, jestliže existuje posloupnost přímých derivacíνi−1 ⇒ νi i = 1, . . . , n, n ≥ 1 taková, že platí:

λ = ν0 ⇒ ν1 ⇒ . . .⇒ νn−1 ⇒ νn = µ

Tuto posloupnost nazýváme derivací délky n. Platí-li λ⇒+ µ, pak říkáme, že řetězec µ lze ge-nerovat z řetězce λ v gramatice G. Relace ⇒+ je zřejmě tranzitivním uzávěrem relace příméderivace ⇒ . Symbolem ⇒n značíme n-tou mocninu relace ⇒.

Příklad 2.16 V gramatice z příkladu 2.12 platí (v důsledku pravidla 0A → 00A1, viz příklad2.14) relace

0nA1n ⇒ 0n+1A1n+1 n > 0

a tudíž také 0A1⇒+ 0nA1n pro libovolné n > 1.

Definice 2.13 Jestliže v gramatice G platí pro řetězce λ a µ relace λ⇒+ µ nebo identita λ = µ,pak píšeme λ⇒µ

∗ . Relace ⇒∗ je tranzitivním a reflexivním uzávěrem relace přímé derivace ⇒.

Příklad 2.17 Relaci 0A1⇒+ 0nA1n, n > 1 z příkladu 2.16 lze rozšířit na relaci

0A1∗⇒ 0nA1n, n > 0

Poznámka 2.1 Dojdeme-li v posloupnosti přímých derivací k řetězci, který obsahuje pouzeterminální symboly, pak již nelze aplikovat žádné přepisovací pravidlo a proces generování končí.Z této skutečnosti, jež vyplývá z definice pravidla, je odvozen název množiny Σ jako množinyterminálních symbolů.

Definice 2.14 Nechť G = (N,Σ, P, S) je gramatika. Řetězec α ∈ (N ∪ Σ)∗ nazýváme větnouformou, jestliže platí S⇒∗ α, tj. řetězec α je generovatelný z výchozího symbolu S. Větná forma,která obsahuje pouze terminální symboly, se nazývá věta. Jazyk L(G), generovaný gramatikouG, je definován množinou všech vět

L(G) = {w | S ∗⇒w ∧ w ∈ Σ∗}

Page 14: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

10 0 0 1

Příklad 2.18 Jazyk generovaný gramatikou G z příkladu 2.12 je množina

L(G) = {0n1n | n > 0},

protože platí

S ⇒ 0A1

S ⇒∗ 0nA1n n > 0 (viz příklad 2.16 a 2.17)

S ⇒∗ 0n1n n > 0 (po aplikaci pravidla A→ ε)

2.3 Chomského klasifikace gramatik

Chomského klasifikace gramatik (a jazyků), známá také pod názvem Chomského hierarchiejazyků, vymezuje čtyři typy gramatik, podle tvaru přepisovacích pravidel, jež obsahuje množinapřepisovacích pravidel P . Tyto typy se označují jako typ 0, typ 1. typ 2 a typ 3.

2.3.1 Typ 0

Gramatika typu 0 obsahuje pravidla v nejobecnějším tvaru, shodným s definicí 2.10 gramatiky:

α→ β, α ∈ (N ∪ Σ)∗N(N ∪ Σ)∗, β ∈ (N ∪ Σ)∗

Z tohoto důvodu se gramatiky typu 0 nazývají také gramatikami neomezenými.

Příklad 2.19 Příklad neomezené gramatiky:

G = ({A,B}, {a, b}, P,A) s pravidly

A → AbB | aAbB → baB | BAbBB → b | ε

2.3.2 Typ 1

Gramatika typu 1 obsahuje pravidla tvaru:

αAβ → αγβ, A ∈ N, α, β ∈ (N ∪ Σ)∗, γ ∈ (N ∪ Σ)+ nebo S → ε

Gramatiky typu 1 se nazývají také gramatikami kontextovými, poněvadž tvar pravidla tétogramatiky implikuje, že nonterminál A může být nahrazen řetězcem γ pouze tehdy, je-li jehopravým kontextem řetězec β a levým kontextem řetězec α.

Kontextové gramatiky neobsahují pravidla tvaru αAβ → αβ, tj. nepřipouštějí, aby byl non-terminál nahrazen prázdným řetězcem. Jedinou přípustnou výjimkou je pravidlo S → ε (S jevýchozí symbol), které umožňuje popsat příslušnost prázdného řetězce k jazyku, který je danougramatikou generován. V důsledku této vlastnosti pravidel gramatiky typu 1 nemůže při gene-rování věty dojít ke zkráceni generovaných řetězců, tj. platí-li λ⇒ µ, pak |λ| ≤ |µ| (s výjimkouS ⇒ ε).

Page 15: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 11

Příklad 2.20 Příklad kontextové gramatiky:

G = ({A,S}, {0, l, c}, P, S) s pravidly

S → OA1

OA → OOA1 (α = 0, β = ε, γ = OA1)

A → c

2.3.3 Typ 2

Gramatika typu 2 obsahuje pravidla tvaru:

A→ γ, A ∈ N, γ ∈ (N ∪ Σ)∗

Gramatiky typu 2 se nazývají také bezkontextovými gramatikami, protože substituci levé stranyγ pravidla za nonterminál A lze provádět bez ohledu na kontext, ve kterém je nonterminál Auložen. Na rozdíl od kontextových gramatik, bezkontextové gramatiky smí obsahovat pravidlatvaru A→ ε. V kapitole 4 však ukážeme, že každou bezkontextovou gramatiku lze transformovat,aniž by se změnil jazyk generovaný touto gramatikou tak, že obsahuje nejvýše jedno pravidlos prázdným řetězcem na levé straně tvaru S → ε. V takovém případě, stejně jako v případěkontextových gramatik, nesmí se výchozí symbol S objevit v žádné pravé straně přepisovacíhopravidla gramatiky.

Příklad 2.21 Příklad bezkontextové gramatiky:

G = ({S}, {0, 1, c}, P, S) s pravidly

S → 0S1 | c

Poznamenejme, že jazyk generovaný touto gramatikou je stejný jako jazyk generovaný bezkon-textovou gramatikou z příkladu 2.20:

L(G) = {0nc1n}, n ≥ 1

2.3.4 Typ 3

Gramatika typu 3 obsahuje pravidla tvaru:

A→ xB nebo A→ x; A,B ∈ N, x ∈ Σ∗

Gramatika s tímto tvarem pravidel se nazývá pravá lineární gramatika (jediný možný nonter-minál pravé strany pravidla stojí úplně napravo). V následující kapitole ukážeme, že k uvedenégramatice lze sestrojit ekvivalentní speciální pravou lineární gramatiku s pravidly tvaru

A→ aB nebo A→ a; A,B ∈ N, x ∈ Σ nebo S → ε

Tuto gramatiku budeme nazývat regulární gramatikou, přesněji pravou regulární gramatikou.Gramatiky typu 3 se proto nazývají také regulárními gramatikami.

Příklad 2.22 Příklady gramatiky typu 3:

G = ({A,B}, {a, b, c}, P,A) s pravidly

A → aaB | ccBB → bB | ε

Page 16: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

12 KAPITOLA 2. Jazyky, gramatiky a jejich klasifikace

Definice 2.15 Jazyk generovaný gramatikou typu i, i = 0, 1, 2, 3, nazýváme jazykem typu i.Podle anonymních názvů gramatik mluvíme také o jazycích neomezených (i = 0), kontextových(i = 1), bezkontextových (i = 2) a regulárních (i = 3).

Věta 2.2 Nechť Li, i = 0, 1, 2, 3 značí třídu všech jazyků typu i. Pak platí L0 ⊇ L1 ⊇ L2 ⊇ L3.

Důkaz: Z definice gramatiky typu i plyne, že každá gramatika typu 1 je zároveň gramatikoutypu 0 a každá gramatika typu 3 je zároveň bezkontextovou gramatikou. Inkluze L1 ⊇ L2

plyne ze skutečnosti, že každá bezkontextová gramatika může být převedena na bezkontextovougramatiku, jež neobsahuje, s výjimkou pravidla S → ε (S je výchozí symbol), žádné pravidlos pravou stranou totožnou s prázdným řetězcem ε. 2

K poznatkům teorie formálních jazyků patří další tvrzení, jež je zesílením věty 2.2 a jež definujeChomského hierarchii formálních jazyků. Toto tvrzení uvádíme bez důkazu.

Věta 2.3 Nechť Li, i = 0, 1, 2, 3 jsou třídy jazyků typu i. Pak platí L0 ⊃ L1 ⊃ L2 ⊃ L3.

2.4 Cvičení

Cvičení 2.4.1 Vytvořte gramatiku typu 3, která generuje identifikátory jež mohou mít maxi-málně 6 znaků a začínají písmenem I, J,K,L,M nebo N(celočíselné proměnné v jazyce Fortran).

Cvičení 2.4.2 Vytvořte gramatiku typu 3, která generuje čísla jazyka Pascal.

Cvičení 2.4.3 Vytvořte bezkontextovou gramatiku, která generuje všechny řetězce nul a jed-niček takové, že počet nul je v každém řetězci shodný s počtem jedniček.

Cvičení 2.4.4 Ukažte, že neomezená gramatika G = ({S,B,C}, {a, b, c}, P, S), kde P obsahujepravidla S → SaBC,Ca → aC, S → aBC,BC → CB, aB → Ba,CB → BC,Ba → aB,B →b, aC → Ca,C → c generuje věty ve kterých je počet výskytů symbolů a, b, c navzájem roven.

Page 17: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 3

Jazyky typu 3 Chomského klasifikace

V této kapitole ukážeme ekvivalenci jazyků generovaných gramatikou typu 3 a regulárními mno-žinami s jazyky přijímanými konečnými automaty.

3.1 Regulární množiny a jazyky typu 3

Definice 3.1 Nechť Σ je konečná abeceda. Regulární množinu nad abecedou Σ definujemerekurzívně takto:

(1) ∅ (prázdná množina) je regulární množina nad Σ

(2) {ε} (množina obsahující pouze prázdny řetězec) je regulární množina nad Σ

(3) {a} pro všechna a ∈ Σ je regulární množina nad Σ

(4) jsou-li P a Q regulární množiny nad Σ, pak také P ∪Q, P ·Q a P ∗ jsou regulární množinynad Σ

(5) regulárními množinami jsou právě ty množiny, které lze získat aplikací 1–4.

Třída regulárních množin je tedy nejmenší třída jazyků, která obsahuje ∅, {ε}, {a} pro všechnysymboly a a je uzavřena vzhledem k operacím sjednocení, součinu a iterace.

Ukážeme, že tato třída tvoří právě třídu L3, tj. třídu jazyka typu 3 Chomského hierarchie.

Poznámka 3.1 Obvyklou notací pro reprezentaci regulárních množin jsou regulární výrazy [7].

Věta 3.1 Nechť Σ je konečná abeceda. Pak

∅(1)

{ε}(2)

{a} pro všechna a ∈ Σ(3)

jsou jazyky typu 3 nad abecedou Σ.

13

Page 18: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

14 KAPITOLA 3. Jazyky typu 3 Chomského klasifikace

Důkaz:

(1) G = ({S},Σ, ∅, S) je gramatika typu 3 pro kterou L(G) = ∅

(2) G = ({S},Σ, {S → ε}, S) je gramatika typu 3 pro kterou L(G) = {ε}

(3) Ga = ({S},Σ, {S → a}, S) je gramatika typu 3, pro kterou L(Ga) = {a}

2

Věta 3.2 Nechť L1 a L2 jsou jazyky typu 3 nad abecedou Σ. Pak

L1 ∪ L2(1)

L1 · L2(2)

L∗1(3)

jsou jazyky typu 3 nad abecedou Σ.

Důkaz: Protože L1 a L2 jsou jazyky typu 3, můžeme předpokládat existenci gramatik G1 =(N1,Σ, P1, S1) a G2 = (N2,Σ, P2, S2) typu 3 takových, že L(G1) = L1 a L(G2) = L2. Bez újmyna obecnosti dále předpokládejme, že množiny N1 a N2 jsou disjunktní.

(1) Nechť G3 = (N1 ∪N2 ∪ {S3},Σ, P1 ∪P2 ∪ {S3 → S1, S3 → S2}, S3) je gramatika typu 3, kdeS3 je nový nonterminál, S3 /∈ N1, S3 /∈ N2. Zřejmě L(G3) = L(G1) ∪ L(G2), poněvadž prokaždou derivaci S3⇒+

G3w existuje buď derivace S1⇒+

G1w, nebo S2⇒+

G2w a naopak. Protože

G3 je gramatika typu 3, je L(G3) jazyk typu 3.

(2) Nechť G4 = (N1 ∪ N2,Σ, P4, S1) je gramatika typu 3, jejíž množina přepisovacích pravidelP4 je definována takto:

(a) je-li A→ xB v P1, pak A→ xB je v P4

(b) je-li A→ x v P1, pak A→ xS2 je v P4

(c) všechna pravidla z P2 jsou v P4.

Nyní, jestliže S1⇒+G1w, pak S1⇒+

G4wS2. Je-li dále S2⇒+

G2x, pak S2⇒+

G4x a tedy S1⇒+

G4wx

pro libovolné w a x. Z toho plyne L(G1) · L(G2) ⊆ L(G4).

Předpokládejme, že platí S1⇒+G4w. Protože v P4 nejsou žádná pravidla tvaru A→ x z mno-

žiny P1, můžeme tuto derivaci zapsat ve tvaru S1⇒+G4x S2⇒+

G4xy, kde w = xy, přičemž

všechna pravidla použitá v derivaci S1⇒+G4xS2 byla odvozena podle (a) a (b). Pak ale musí

existovat derivace S1⇒+G1x a S2⇒+

G2y a tudíž L(G4) ⊆ L(G1) · L(G2). Z toho však plyne

L(G4) = L(G1) · L(G2).

(3) Nechť G5 = {N1 ∪ {S5},Σ, P5, S5}, S5 /∈ N1 a množina P5 je konstruována takto:

(a) je-li A→ xB v P1, pak A→ xB je v P5

(b) je-li A→ x v P1, pak A→ xS5 a A→ x jsou v P5

(c) S5 → S1 a S5 → ε jsou v P5.

Page 19: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 15

Nyní je třeba dokázat tvrzení:

DerivaceS5

+⇒G5x1S5

+⇒G5x1x2S5

+⇒G5. . .

+⇒G5x1x2 . . . xn−1S5

+⇒G5x1x2 . . . xn−1xn

existuje tehdy a jen tehdy, když existují derivace

S1+⇒G1x1, S1

+⇒G1x2, . . . , S1

+⇒G1xn.

Z tohoto tvrzení, jehož důkaz ponecháme jako cvičení, bezprostředně plyne L(G5) = (L(G1))∗.Protože G5 je gramatika typu 3, je i jazyk L(G5) typu 3. 2

Věta 3.3 Jazyk L je regulární množinou když a jen když je generován gramatikou typu 3.

Důkaz: Část „jen kdyžÿ plyne z vět 3.1 a 3.2, důkaz části „kdyžÿ využívá teorie regulárníchvýrazů a lze jej nalézt v [3]. 2

3.2 Jazyky přijímané konečnými automaty a jazyky typu 3

Definice 3.2 Nedeterministický konečný automat je 5-tice M = (Q,Σ, δ, q0, F ), kde

(1) Q je konečná množina stavů

(2) Σ je konečná vstupní abeceda

(3) δ je zobrazení Q× Σ→ 2Q (2Q je množina podmnožin množiny Q)

(4) q0 ∈ Q je počáteční stav

(5) F ⊆ Q je množina koncových stavů

Zobrazení δ nazýváme funkcí přechodu, je-li δ : Q× Σ→ Q, pak automat M je deterministickýkonečný automat.

Činnost konečného automatu M je dána posloupností přechodů; přechod z jednoho stavu dodruhého je řízen funkcí přechodu δ, která na základě přítomného stavu qi a právě přečtenéhosymbolu a ∈ Σ vstupního řetězce předepisuje budoucí stav qj automatu. Je-li M deterministickýkonečný automat, δ předepisuje vždy jediný budoucí stav qj ; v případě nedeterministickéhokonečného automatu δ předepisuje množinu budoucích stavů Qj , Qj ∈ 2Q.

Definice 3.3 Je-li M = (Q,Σ, δ, q0, F ) konečný automat, pak dvojici C = (q, w) z Q×Σ∗ nazý-váme konfigurací automatu M . Konfigurace tvaru (q0, w) je počáteční konfigurace, konfiguracetvaru (q, ε), q ∈ F je koncová konfigurace. Přechod automatu M je reprezentován binární relací`M na množině konfigurací C. Jestliže δ(q, a) obsahuje q′ (tj. δ(q, a) = Qj , Qj ∈ 2Q, q′ ∈ Qj),pak (q, aw)`M(q′, w) pro všechna w ∈ Σ∗. Označíme symbolem `kM , k ≥ 0, k-tou mocninu(C `0 C ′ právě když C = C ′), symbolem `+

M tranzitivní uzávěr a symbolem `∗M tranzitivní areflexivní uzávěr relace `M . Bude-li zřejmé, že jde o automat M , pak uvedené relace zapíšemepouze ve tvaru `, `k, `+, `∗.

Page 20: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

16 0 0 1

δ z c · 10 ]

q0 q8 q7 q6 q4

q1

q2 q2 q1

q3 q2

q4 q3 q2

q5 q5 q4 q1

q6 q5

q7 q7 q6 q4 q1

q8 q7 q6 q4

Tabulka 3.1: Funkce přechodů automatu M

Definice 3.4 Říkáme, že vstupní řetězec w je přijímán konečným automatem M , jestliže(q0, w)`∗ (q, ε), q ∈ F . Jazyk přijímaný konečným automatem M označujeme symbolem L(M)a definujeme ho jako množinu všech řetězců přijímaných automatem M :

L(M) = {w | (q0, w)∗`(q, ε) ∧ q ∈ F}

Příklad 3.1 Konečný deterministický automat

M = ({g0, q1, q3, q4, q5, q6, q7, q8}, {c, z,10 , ·, ]}, δ, q0, {q1}),

jehož funkce přechodu δ je definována tabulkou 3.1, přijímá jazyk algolovských zápisů čísel.Symbolem c značíme prvek množiny {0, 1, . . . , 9}, symbolem z prvek množiny {+,−}; znak ]ukončuje zápis čísla.

Např. vstupnímu řetězci zc.c10zc] (např. algolovskému číslu +3.110 − 5) bude odpovídat tatoposloupnost konfigurací:

(q0, zc.c10]) ` (q8, c.c10zc])

(q7, .c10zc])

(q6, c10zc])

(q5,10 zc])

(q4, zc])

(q3, c])

(q2, ])

(q1, ε)

Poněvadž (q0, zc.c10zc])`∗(q1, ε), patří zc.c10zc] do L(M).

Poznámka 3.2 K základům teorie automatů patří poznatek, že každý konečný nedeterminis-tický automat M může být převeden na „ekvivalentníÿ konečný deterministický automat M ′, tj.pro automaty. M a M ′ platí L(M ′) = L(M), [3], [12]. Tato skutečnost je velmi důležitá takév našich aplikacích.

Page 21: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 17

Dříve, než přistoupíme k důkazu ekvivalence třídy L3 a třídy jazyků přijímaných konečnýmiautomaty, ukážeme, že každý jazyk typu 3 může být generován speciálnějším typem gramatiky,než je pravá lineární gramatika.

Věta 3.4 Každá pravá lineární gramatika G = (N,Σ.P, S), tj. gramatika obsahující pouzepravidla typu A → xB nebo A → x, kde A,B ∈ N , x ∈ Σ∗ , může být transformována nagramatiku G′ = (N ′,Σ, P ′, S′), která obsahuje pouze pravidla tvaru A → aB nebo A → ε ,přičemž L(G) = L(G′).

Důkaz: Množinu přepisovacích pravidel P ′ gramatiky G′ konstruujeme takto:

(1) všechna pravidla z P tvaru A→ aB a A→ ε kde A,B ∈ N , a ∈ Σ zařadíme do množiny P ′

(2) každé pravidlo tvaru A → a1a2 . . . anB; A,B ∈ N , ai ∈ Σ, n ≥ 2 z množiny P nahradímev množině P ′ soustavou pravidel:

A → a1A1

A1 → a2A2

...

An−1 → anB

Nově zavedené nonterminály A1, . . . , An−1 přidáme k množině N ′. Derivaci A⇒G a1 . . . anBzřejmě odpovídá právě derivace A⇒n

G′ a1a2 . . . anB.

(3) Každé pravidlo tvaru A → a1 . . . an, ai ∈ Σ, n ≥ 2 z množiny P nahradíme v množině P ′

soustavou pravidel:

A → a1A′1

A′1 → a2A′2

...

A′n−1 → anA′n

A′n → ε

Derivaci A⇒G a1a2 . . . an zřejmě odpovídá právě derivace A⇒n+1

G′ a1a2 . . . an.

(4) zbývající, tzv. jednoduchá pravidla tvaru A→ B,A,B ∈ N , nahradíme takto:

(a) určíme množinu NA = {C | C = C1 ⇒ C2 ⇒ . . .⇒ Cn = A}; A,B,Ci ∈ N , tj. množinunonterminálů, z nichž lze aplikací jednoduchých pravidel generovat nonterminál A.

(b) ke každému pravidlu typu A→ aB přidáme do P ′ všechna pravidla tvaru C → aB provšechna C ∈ NA.

Bod 4b aplikuje obecný algoritmus odstranění jednoduchých pravidel bezkontextové gramatiky,který je uveden a dokázán v kapitole 4 (algoritmus 4.3). Jeho součástí je také efektivní výpočetmnožiny NA. 2

Příklad 3.2 Na základě předchozí věty budeme transformovat pravou lineární gramatiku G =({X,Y }, {a, b, c}, P,X), kde P obsahuje pravidla:

X → abc | Y | εY → aY | cbX

Page 22: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

18 0 0 1

Podle 1 budou v P ′ pravidla:X → ε, Y → aY

Podle 2 nahradíme pravidlo Y → cbX pravidly

Y → cZ, Z → bX

Podle 3 nahradíme pravidlo Y → abc pravidly

Y → aU,U → bV, V → cW,W → ε

Podle 3 nahradíme pravidlo X → Y . Protože NY = {X} přidáme k P ′ pravidla

X → aY,X → cZ

Výsledná gramatika má pak tvar G′ = ({X,Y, Z, U, V,W}, {a, b, c}, P ′, X) kde P ′ obsahuje pra-vidla:

X → ε | aY | cZ | aUY → aY | cZZ → bX

U → bV

V → cW

W → ε

Definice 3.5 Gramatika G′ = (N,Σ, P, S) se nazývá regulární (pravá regulární) jestliže mno-žina přepisovacích pravidel P obsahuje pravidla pouze tvaru A → aB nebo A → a kde A,B ∈N, a ∈ Σ. V případě, že L(G) obsahuje prázdný řetězec, pak regulární gramatika obsahuje jedinépravidlo s prázdným řetězcem na pravé straně ve tvaru S → ε. Výchozí symbol S se pak nesmíobjevit v žádné pravé straně pravidla.

Věta 3.5 Každý jazyk typu 3 lze generovat regulární gramatikou, tj. je regulárním jazykem.

Důkaz: Regulární gramatiku získáme z gramatiky zkonstruované podle věty 3.4 odstraněnímpravidel s prázdným řetězcem na pravé straně. Systematicky tento postup popisuje algoritmus4.4 v kapitole 4; zatím jej ilustrujme na příkladě. 2

Příklad 3.3 Gramatiku z příkladu 3.2 převedeme na regulární odstraněním pravidla W → ε(vznikne pravidlo V → c) a pravidla X → ε (vznikne pravidlo Z → b). Protože ε ∈ L(G) aX je na pravé straně pravidla Z → bX, musíme zavést nový výchozí symbol X ′ a odstranitjednoduché pravidlo X ′ → X. Výsledná gramatika bude mít tvar:

G′′ = ({X ′, X, Y, Z, U, V }, {a, b, c}, P ′′, X ′),

P ′′ obsahuje pravidla:

X ′ → ε | aY | cZ | aUY → aY | cZZ → bX | bX → aY | cZ | aUU → bV

V → c

Page 23: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 19

Věta 3.6 Nechť L je jazyk typu 3. Pak existuje konečný automat M takový, že L = L(M).Označíme-li LM třídu jazyků přijímaných konečnými automaty, pak ekvivalentní tvrzení mátvar L3 ⊆ LM .

Důkaz:

Podle věty 3.5 můžeme jazyk L generovat gramatikou G = (N,Σ, P, S) typu 3, jejíž pravidlamají tvar A → aB nebo A → ε (A,B ∈ N, a ∈ Σ). Sestrojme konečný (nedeterministický)automat M

M = (Q,Σ, δ, q0, F ) kde

(1) Q = N

(2) Σ = Σ

(3) δ : δ(A, a) obsahuje B pro každé pravidlo A→ aB z P

(4) q0 = S

(5) F = {A | A→ ε je pravidlo z P}

Ukážeme, že L(G) = L(M).

Důkaz provedeme indukcí. Dokazovaná induktivní hypotéza nechť má tvar:

pro každé A ∈ N platí A⇒i+1G w,w ∈ Σ∗, právě když (A,w)`iM(C, ε) pro nějaké

C ∈ F

Nejdříve dokážeme tuto hypotézu pro i = 0. Zřejmě platí

A⇒ ε právě když (A, ε)0

`(A, ε) pro A ∈ F

Nyní předpokládejme, že dokazovaná hypotéza platí pro i a položíme w = ax, a ∈ Σ, |x| = i.Pak platí A⇒i+1 w, právě když A ⇒ aB⇒i x. Podle definice funkce δ pak δ(a,A) obsahuje B(v důsledku přímé derivace A⇒ aB). Na základě induktivní hypotézy platí B⇒i x, právě když(B, x)`i−1(C, ε), C ∈ F . Shrneme-li tyto skutečnosti, platí:

A⇒ aBi⇒ ax = w, právě když (A, aX) ` (B, x)

i−1

` (C, ε), C ∈ F

tj. Ai+1⇒w, právě když (A,w)

i

`(C, ε), C ∈ F ;

tím jsme platnost induktivního předpokladu dokázali pro všechna i ≥ 0.

Speciálně pak platí

S∗⇒w, právě když (S,w)

∗`(C, ε), C ∈ F

a tedy L(G) = L(M). 2

Page 24: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

20 0 0 1

Příklad 3.4 Ke gramatice G = ({X,Y, Z, U, V,W}, {a, b, c}, P,X), kde P obsahuje pravidla

X → ε | aY | cZ | aUY → aY | cZZ → bX

U → bV

V → cW

W → ε

sestrojíme konečný automat, který přijímá jazyk L(G).

Budeme postupovat podle věty 3.6. Funkci přechodů δ reprezentujeme diagramem přechodů(obr. 3.1), v němž koncové stavy jsou vyznačeny dvojitým kroužkem.

M = (Q,Σ, δ, q0, F ) kde

Q = {X,Y, Z, U, V,W}Σ = {a, b, c}δ : viz obr. 3.1

q0 = x

F = {X,W}

Obrázek 3.1: Diagram přechodů automatu M

Věta 3.7 Nechť L = L(M) pro nějaký konečný automat M . Pak existuje gramatika G typu 3taková, že L = L(G), tj. LM ⊆ L3.

Důkaz: NechťM = (Q,Σ, δ, q0, F ). Protože každý nedeterministický automat může být převedenna deterministický automat přijímající stejný jazyk, předpokládejme, že M je deterministickýautomat. Nechť G je gramatika typu 3, G = (Q,Σ, P, q0), jejíž množina P přepisovacích pravidelje definována takto:

(1) je-li δ(q, a) = r, pak P obsahuje pravidlo q → ar

Page 25: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 21

(2) je-li p ∈ F , pak P obsahuje pravidlo p→ ε

V další části probíhá důkaz zcela analogicky důkazu věty 3.6. 2

Příklad 3.5 Na základě příkladu 3.1 sestrojíme gramatiku typu 3, která generuje jazyk algo-lovských zápisů čísel. Přechodová funkce deterministického konečného automatu, který přijímátento jazyk, je v tabulce 3.1. Výsledná gramatika bude tvaru:

G = ({q0, q1, q2, q3, q4, q5, q6, q7, q8}, {c, z, 10, ., ]}, P, q0)

P obsahuje pravidla

q0 → zq8 | cq7 | ·q6 | 10q4

q1 → ε

q2 → cq2 | ]q1

q3 → cq2

q4 → zq3 | cq2

q5 → cq5 | 10q4 | ]q1

q6 → cq5

q7 → cq7 | ·q6 | 10q4 | ]q1

q8 → cq7 | ·q6 | 10q4

Poznamenejme, že převod této gramatiky na gramatiku regulární je velice snadný, stačí dosaditza q1 prázdný řetězec a odstranit pravidlo q1 → ε.

Věta 3.8 Třída jazyků, jež jsou přijímány konečnými automaty, je totožná s třídou jazyků typu3 Chomského hierarchie.

Důkaz: Tvrzení bezprostředně plyne z vět 3.6 a 3.7. 2

Definice 3.6 Gramatika G = (N,Σ, P, S) se nazývá levá lineární gramatika, jestliže množinaP obsahuje pouze pravidla typu A→ Bx nebo A→ x kde A,B ∈ N , x ∈ Σ∗.

Věta 3.9 Každý jazyk typu 3 může být generován levou lineární gramatikou.

Důkaz: Úplný důkaz ponecháme na cvičení. Lze postupovat tak, že nejprve z definice regulárnímnožiny dokážeme tvrzení: je-li L regulární množina, pak LR je také regulární množina. Dáleukážeme: je-li G = (N,Σ, P, S) pravá lineární gramatika, pak levá lineární gramatika G′, jejížmnožina pravidel má tvar P ′ = {A→ αR | A→ α je v P}, generuje jazyk (L(G))R. 2

Příklad 3.6 Gramatika G′ = ({X,Y }, {a, b, c}, P ′, X) kde P ′ obsahuje pravidla

X → cba | Y | εY → Y a | Xbc

je levá lineární gramatika, pro kterou L(G′) = (L(G))R, G je pravá lineární gramatika z příkladu3.2.

Page 26: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

22 0 0 1

Definice 3.7 Levá lineární gramatika G = (N, Σ, P, S) se nazývá regulární (přesněji leváregulární), jestliže pravidla v P mají tvar A→ Ba nebo A→ a. Pokud L(G) obsahuje prázdnýřetězec ε, pak jediné přípustné pravidlo s pravou stranou obsahující prázdný řetězec je S → ε aS se v takovém případě nesmí objevit na pravé straně žádného pravidla.

Poznamenejme, že konstrukce levé regulární gramatiky k dané levé lineární gramatice je zcelaanalogická konstrukci pravé regulární gramatiky k dané pravé lineární gramatice. Tuto konstrukciilustruje příklad:

Příklad 3.7 Uvažujme gramatiku z příkladu 3.6, jež má pravidla:

X → cba | Y | εY → Y a | Xbc

1. krok zavádí pouze pravidla typu A→ Ba nebo A→ ε:

X → Ua | Y a | Zc | εY → Y a | ZcU → V b

V → Wc

W → ε

Z → Xb

2. krok odstraňuje pravidla typu A→ ε a upravuje gramatiku na konečný tvar:

X ′ → Ua | Y a | Zc | εY → Y a | ZcU → V b

V → c

Z → Xb | bX → Ua | Y a | Zc

Povšimněme si, v čem se liší pravidla této gramatiky od pravidel pravé regulární gramatikyz příkladu 3.3, jež byla získána z pravé lineární gramatiky (příklad 3.2)

Algoritmus 3.1 Konstrukce nedeterministického konečného automatu k pravé regulární gra-matice.

Vstup: Pravá regulární gramatika G = (N,Σ, P, S), jejíž pravidla mají tvar A→ aB a A→ akde A,B ∈ N a a ∈ Σ, případně S → ε, je-li ε ∈ L(G).

Výstup: Nedeterministický konečný automat M = (N,Σ, δ, q0, F ), pro který je L(M) = L(G).

Metoda:

(1) Položíme Q = N ∪ {qF }, kde qF reprezentuje koncový stav.

(2) Množina vstupních symbolů automatu M je identická s množinou terminálů grama-tiky G.

(3) Funkci přechodů δ definujeme takto:

Page 27: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 23

(a) Je-li A→ aB pravidlo z P , pak δ(A, a) obsahuje stav B

(b) Je-li A→ a pravidlo z P , pak δ(A, a) obsahuje qF

(4) q0 = S

(5) Je-li S → ε pravidlo z P , pak F = {S, qF }, v opačném případě F = {qF }.

Věta 3.10 Nechť G je pravá regulární gramatika a M konečný automat z algoritmu 3.1. PakL(M) = L(G).

Důkaz: Důkaz této věty je modifikací důkazu věty 3.6; přenecháme ho jako cvičení. 2

Příklad 3.8 Uvažujeme gramatiku G = ({S,B}, {0, 1}, P, S) s pravidly

S → 0B | εB → 0B | 1S | 0

Diagram přechodů automatu přijímajícího jazyk L(G) má, na základě konstrukce podle algo-ritmu 3.1, tvar:

Obrázek 3.2: Diagram přechodů

Algoritmus 3.2 Konstrukce nedeterministického konečného automatu k levé regulární grama-tice.

Vstup: Levá regulární gramatika G = (N,Σ, P, S) jejíž pravidla mají tvar A → Ba a A → akde A,B ∈ N a a ∈ Σ, případně S → ε, je-li ε ∈ L(G).

Výstup: Nedeterministický konečný automat M = (N,Σ, δ, q0, F ), pro který je L(M) = L(G).

Metoda:

(1) Položíme Q = N ∪ {q0}(2) Množina vstupních symbolů automatu M je identická s termální abecedou gramatiky

G.

(3) Funkci přechodu δ definujeme takto:

Page 28: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

24 0 0 1

(a) Je-li A→ Ba pravidlo z P , pak δ(B, a) obsahuje stav A.

(b) Je-li A→ a, pak δ(q0, a) obsahuje stav A.

(4) q0 je počáteční stav automatu M

(5) Je-li S → ε pravidlo z P pak F = {S, q0}, v opačném případě F = {S}

Věta 3.11 Nechť G je levá lineární gramatika a M konečný automat z algoritmu 3.2. PakL(M) = L(G).

Důkaz: Nejprve dokážeme, že ε ∈ L(G), právě když ε ∈ L(M). Podle konstrukce automatuM, q0 ∈ F právě když v P je pravidlo S → ε a tedy

S ⇒ ε, právě když (q0, ε)0

`(q0, ε), q0 ∈ F

Nyní dokážeme, že pro libovolné w ∈ Σ+ platí

S+⇒w, právě když (q0, w)

+

`(S, ε), S ∈ F

Položme w = ax, a ∈ Σ, x ∈ Σ∗. Induktivní hypotéza nechť má tvar:

Si⇒Ax⇒ ax, právě když (q0, ax) ` (A, x)

i

`(S, ε), A ∈ N, S ∈ F, |x| = i

Pro i = 0 dostaneme:

S ⇒ a, právě když (q0, a) ` (S, ε),

což plyne přímo z definice funkce přechodů automatu M (δ(q0, a) obsahuje S, právě když S → aje v P ).

Pro i ≥ 1 je třeba dokázat:

(a) Ax⇒ ax, právě když (q0, ax) ` (A, x)

(b) S⇒iAx právě když (A, x)`i(S, ε)

Důkaz tvrzení (a) a (b) ponecháme jako cvičení. 2

Příklad 3.9 Uvažujme gramatiku G = ({S, I,N}, {c, p, ]}, P, S) s pravidly:

E → I] | N]I → p | Ip | IcN → c | Nc

Značí-li c arabskou číslici a p písmeno, pak L(G) je jazyk identifikátorů (nonterminál I) a celýchčísel bez znaménka (nonterminál N). Každá věta jazyka L(G) končí koncovým znakem ].

Diagram přechodů automatu, který přijímá jazyk L(G), má na základě algoritmu 3.2 tvar:

Page 29: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

3.3. Cvičení 25

Obrázek 3.3: Diagram přechodů

3.3 Cvičení

Cvičení 3.3.1 Ke konečnému nedeterministickému automatu

M = ({q0, q1, q2, q3, qF }, {1, 2, 3}, δ, q0, {qF }),

kde zobrazení δ je definováno touto tabulkou

ΣQ 1 2 3q0 {q0, q1} {q0, q2} {q0, q3}q1 {q1, qF } {q1} {q1}q2 {q2} {q2, qF } {q1}q3 {q3} {q3} {q3, qF }qF ∅ ∅ ∅

sestrojte deterministický automat M ′, pro který platí L(M ′) = L(M).

Cvičení 3.3.2 Nechť L1 = L(M1) a L2 = L(M2) jsou jazyky přijímané konečnými automatyM1 = (Q1,Σ1, δ1, q

10, F1) a M2 = (Q2,Σ2, δ2, q

20, F2). Analogicky větě 3.2 ukažte konstrukci

automatů M3, M4 a M5, pro které platí:

L(M3) = L1 ∪ L2, L(M4) = L1 · L2 a L(M5) = L∗1.

Cvičení 3.3.3 K pravé lineární gramatice, která osahuje pravidla

A → B | CB → 0B | 1B | 011

C → 0D | 1C | εD → 0C | 1D

vytvořte pravou lineární gramatiku, jež generuje stejný jazyk. Nonterminál A je výchozím sym-bolem gramatiky.

Page 30: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

26 0 0 1

Cvičení 3.3.4 Vytvořte regulární gramatiku, která generuje jazyk přijímaný automatem M zecvičení 3.3.1.

Cvičení 3.3.5 Vytvořte konečný automat, který přijímá jazyk generovaný gramatikou ze cvi-čení 3.3.3.

Cvičení 3.3.6 Na základě algoritmu, jenž je „inverzníÿ k algoritmu 3.2, sestrojte levou regulárnígramatiku pro jazyk algolovských čísel. Automat přijímající tento jazyk je uveden v příkladě3.1.

Cvičení 3.3.7 Na základě gramatiky ze cvičení 2.4.2 vytvořte konečný deterministický auto-mat, který přijímá jazyk čísel programovacího jazyka Pascal.

Page 31: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 4

Bezkontextové jazyky

Význam bezkontextových gramatik a jazyků je dán dvěma důležitými faktory:

(1) Bezkontextovými gramatikami jsme schopni popsat převážnou většinu rysů současných pro-gramovacích jazyků.

(2) Jsou známé algoritmy, které umožňují efektivně analyzovat věty bezkontextových jazyků,tj. jazyků generovaných bezkontextovými gramatikami. Tyto algoritmy tvoří základní částreálných překladačů – tzn. syntaktický analyzátor.

Definice 4.1 Bezkontextová gramatika G je čtveřice G = (N,Σ, P, S)

(1) N je konečná množina nonterminálních symbolů

(2) Σ je konečná množina terminálních symbolů

(3) P je konečná množina přepisovacích pravidel (pravidel) tvaru A→ α, A ∈ N a α ∈ (N ∪Σ)∗

(4) S ∈ N je výchozí symbol gramatiky.

Dále budeme gramatikou bez další specifikace rozumět bezkontextovou gramatikou.

Příklad 4.1 Gramatika G = ({S,A,B}, {a, b, c, d}, P, S), kde P obsahuje pravidla

S → AB

A → aAb | abB → cBd | cd

generuje bezkontextový jazyk L(G) = {anbncmdm | n ≤ 1, m ≤ 1}

Jazyk L(G) je součinem dvou bezkontextových jazyků generovaných gramatikami

G1 = ({A}, {a, b}, {A→ aAb,A → ab}, A)

G2 = ({B}, {c, d}, {B → cBd,B → cd}, B)

Poznamenejme, že jazyk L(G1) = {anbn | n ≤ 1} a tudíž ani jazyk L(G) není jazykem regulár-ním, protože konečný automat nemůže pro libovolné n „počítatÿ stejný počet výskytů symbolůa a b. Na druhé straně, jazyk {anbncndn | n ≤ 1}, dokonce ani jazyk {anbncn | n ≤ 0} neníjazykem bezkontextovým.

27

Page 32: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

28 0 0 1

4.1 Derivační strom

Důležitým prostředkem pro grafické vyjádření struktury věty (její derivace) je strom, který senazývá derivačním nebo syntaktickým stromem.

Připomeňme, že strom je orientovaný acyklický graf s těmito vlastnostmi:

(1) Existuje jediný uzel, tzv. kořen stromu, do něhož nevstupuje žádná hrana.

(2) Do všech ostatních uzlů grafu vstupuje právě jedna hrana.

Uzly, z nichž žádná hrana nevystupuje, se nazývají koncové uzly stromu (listy). Při kreslenístromu je obyčejně dodržována tato konvence: kořen leží nejvýše, všechny hrany jsou orientoványsměrem dolů. Budeme-li tuto konvenci dodržovat, pak můžeme vynechat šipky, které označujíorientaci hran. Kořenem stromu na 4.1 je uzel 1, uzly 2, 4, 5, 6 jsou koncovými uzly stromu.

Obrázek 4.1: Příklad stromu

Definice 4.2 Nechť δ je věta nebo větná forma generovaná v gramatice G = (N,Σ, P, S) a nechťS = ν0 ⇒ ν1 ⇒ ν2 . . . ⇒ νk = δ její derivace v G. Derivační strom příslušející této derivaci jestrom s těmito vlastnostmi:

(1) Uzly derivačního stromu jsou označeny symboly z množiny N ∪Σ; kořen stromu je označenvýchozím symbolem S.

(2) Přímé derivaci νi−1 ⇒ νi, i = 0, 1, . . . , k, kde

νi−1 = µAλ, µ, λ ∈ (N ∪ Σ)∗, A ∈ Nνi = µαλ aA→ α, α = X1 . . . Xn je pravidlo z P,

odpovídá právě n hran (A,Xj), j = 1, . . . , n vycházejících z uzlu A jež jsou uspořádány zlevadoprava v pořadí (A,X1), (A,X2), . . . (A,Xn).

(3) Označení koncových uzlů derivačního stromu vytváří zleva doprava větnou formu nebo větuδ (plyne z (1) a (2)).

Příklad 4.2 V Gramatice z příkladu 4.1 můžeme generovat řetězec aabbcd např. derivací:

S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcd

Derivační strom odpovídající této derivaci je na obrázku 4.2. Po stranách jsou uvedena použitápravidla.

Page 33: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 29

Obrázek 4.2: Derivační strom

Poznámka 4.1 Uzel derivačního stromu, který je označen terminálním symbolem, musí býtzřejmě koncovým uzlem derivačního stromu.

Při rekonstrukci derivačního stromu k dané derivaci opakovaně aplikujeme bod (2) z definice4.2. Tuto aplikaci ilustruje obr. 4.3.

Obrázek 4.3: Konstrukce derivačního stromu

Příklad 4.3 Uvažujme gramatiku

G = ({〈výraz〉, 〈term〉, 〈faktor〉}, {+,−, ∗, /, (, ), i}, P, 〈výraz〉),

které se často používá pro popis aritmetického výrazu s binárními operacemi +,−, ∗, /. Termi-nální symbol i odpovídá identifikátoru. Množina P obsahuje tato přepisovací pravidla:

〈výraz〉 → 〈term〉 | 〈výraz〉+ 〈term〉 | 〈výraz〉 − 〈term〉〈term〉 → 〈faktor〉 | 〈term〉 ∗ 〈faktor〉 | 〈term〉/〈faktor〉〈faktor〉 → (〈výraz〉) | i

Jak lze snadno ukázat, větami jazyka L(G) jsou například řetězce i, (i), i ∗ i, i ∗ i+ i, i ∗ (i+ i).

Předpokládejme, že máme zkonstruovat derivační strom pro větnou formu 〈výraz〉 + 〈term〉 ∗〈faktor〉. Nejprve ukažme, že tento řetězec je skutečně větnou formou:

〈výraz〉 ⇒ 〈výraz〉+ 〈term〉 ⇒ 〈výraz〉+ 〈term〉 ∗ 〈faktor〉

Derivační strom začínáme vytvářet od výchozího symbolu:

〈výraz〉u

Page 34: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

30 0 0 1

První přímé derivaci odpovídá konstrukce:

〈výraz〉

`````uu u u

〈výraz〉 + 〈term〉

Po znázornění druhé přímé derivace obdržíme výsledný derivační strom.

〈výraz〉

`````

���� PPPP

uu u u〈výraz〉 + 〈term〉u u u

〈faktor〉∗〈term〉

Je-li tedy dána derivace větné formy, pak této derivaci přísluší právě jeden derivační strom.Důkaz vyplývá z konstrukce derivačního stromu. Podívejme se nyní, zda uvedené tvrzení platítaké obráceně: K derivačnímu stromu větné formy přísluší pouze jedna derivace. Uvažujmegramatiku G z příkladu 4.1.

S → A B

A → aAb | abB → cBd | cd

Na obr. 4.2 jsme znázornili derivační strom k derivaci

S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcd

Ukážeme nyní, že existují i jiné derivace věty aabbcd.

S ⇒ AB ⇒ Acd⇒ aAbcd⇒ aabbcd

neboS ⇒ AB ⇒ aAbB ⇒ aAbcd⇒ aabbcd

Uvedené derivace věty aabbcd se liší v pořadí, v němž byly vybírány nonterminály pro příméderivace. Toto pořadí však ve výsledném derivačním stromě není postiženo, a proto budouderivační stromy příslušející k 2. a 3. z uvedených derivací věty aabbcd totožné s derivačnímstromem na obr. 4.2. Neplatí tedy tvrzení, že k derivačnímu stromu přísluší pouze jedna derivace.

Poznamenejme, že jiné derivace věty aabbcd v gramatice z příkladu 4.2 neexistují. V první a druhéz uvedených derivací byla přepisovací pravidla aplikována určitým kanonickým způsobem, kterýje charakteristický pro nejužívanější syntaktické analyzátory překladačů programovacích jazyků.Zavedeme si pro tyto speciální derivace vlastní označení.

Definice 4.3 Nechť S = α1 ⇒ α2 ⇒ . . . ⇒ αn = α je derivace větné formy α. Jestliže bylv každém řetězci αi, i = 1, . . . , n − 1 přepsán nejlevější (nejpravější) nonterminál, pak tutoderivaci nazýváme levou (pravou) derivací větné formy α.

První derivace věty aabbcd je tedy derivací levou, druhá je derivací pravou.

Je-li S = α0 ⇒ α1 ⇒ . . . ⇒ αn = w levá derivace věty w, pak je každé αi, i = 0, 1, . . . , n − 1tvaru xiAiβi, kde xi ∈ Σ∗, Ai ∈ N a βi ∈ (N ∪ Σ∗). K získání větné formy αi+1 bude přepsánnonterminál Ai. Obrácená situace platí pro pravou derivaci.

Page 35: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

4.2. Fráze větné formy 31

4.2 Fráze větné formy

Definice 4.4 Nechť G = (N,Σ, P, S) je gramatika a nechť řetězec λ = αβγ je větná forma.Podřetězec β se nazývá frází větné formy λ vzhledem k nonterminálu A z N , jestliže platí:

S ⇒∗ αAγ

A ⇒+ β

Podřetězec β je jednoduchou frází větné formy λ, jestliže platí:

S ⇒∗ αAγ

A ⇒ β

Příklad 4.4 Máme nalézt všechny fráze a všechny jednoduché větné formy 〈výraz〉 + 〈term〉 ∗〈faktor〉 v gramatice, která popisuje aritmetický výraz. Jak již bylo uvedeno, derivace této větnéformy má tvar:

〈výraz〉 ⇒ 〈výraz〉+ 〈term〉 ⇒ 〈výraz〉+ 〈term ∗ 〈faktor〉

Protože platí

〈výraz〉 ⇒∗ 〈výraz〉+ 〈term〉 a

〈term〉 ⇒ 〈term〉 ∗ 〈faktor〉

je řetězec 〈term〉 ∗ 〈faktor〉 jednoduchou frází větné formy 〈výraz〉+ 〈term〉 ∗ 〈faktor〉 vzhledemk nonterminálu 〈term〉.

Dále je:

〈výraz〉 ⇒∗ 〈výraz〉〈výraz〉 ⇒+ 〈výraz〉+ 〈term〉 ∗ 〈faktor〉

a z toho vyplývá, že větná forma 〈výraz〉 + 〈term〉 ∗ 〈faktor〉 je frází sama k sobě vzhledemk výchozímu symbolu. Tato skutečnost je důsledkem triviálního případu v definici fráze, kdyjsou řetězce α a γ prázdné. Jiné fráze větné formy 〈výraz〉+ 〈term〉 ∗ 〈faktor〉 neexistují.

Pojem fráze je stěžejním pojmem pro syntaktickou analýzu. Celá třída syntaktických analyzátorůje postavena na metodách hledání nejlevější jednoduché fráze větné formy (věty). Protože dálebudeme pojmu nejlevější jednoduchá fráze často používat, zavedeme pro něj speciální označení,l-fráze.

Ve větné formě 〈výraz〉 + 〈term〉 ∗ 〈faktor〉 je jediná jednoduchá fráze: 〈term〉 ∗ 〈faktor〉. Tatofráze je tedy zároveň l-frází.

S pojmem fráze větné formy je velmi úzce svázán pojem podstrom příslušného derivačníhostromu. Podstromem derivačního stromu budeme rozumět tu část tohoto stromu, která je vyme-zena jistým uzlem, tzv. kořenem podstromu, spolu se všemi uzly, které jsou z kořene podstromudostupné prostřednictvím příslušných hran, včetně těchto hran.

Příklad 4.5 Podstromy derivačního stromu věty aabbcd z obr. 4.2 jsou stromy z obr. 4.4.

Předpokládejme nyní, že nonterminál A je kořenem podstromu derivačního stromu. Je-li β ře-tězec koncových uzlů tohoto podstromu, pak jistě platí A⇒+ β. Nechť α je řetězec koncových

Page 36: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

32 KAPITOLA 4. Bezkontextové jazyky

Obrázek 4.4: Podstromy derivačního stromu

Obrázek 4.5: Fráze větné formy

uzlů vlevo, γ řetězec koncových uzlů derivačního stromu vpravo od β. Pak platí S⇒∗ αβγ;S je kořenem derivačního stromu. To ovšem znamená, že β je frází větné formy αβγ vzhledemk nonterminálu A. Situaci ilustruje obr. 4.5.

Podstrom derivačního stromu tedy odpovídá frázi příslušné větné formy. Fráze je tvořena konco-vými uzly podstromu. Jednoduchá fráze odpovídá podstromu, jenž je výsledkem přímé derivaceA⇒ β.

Příklad 4.6 V gramatice z příkladu 4.1 nalezněte fráze věty a2b2c2d2. Nejdříve sestavíme deri-vační strom. Pro jeho konstrukci vytvořme (např.) levou derivaci této věty:

S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcBd⇒ aabbccdd

Vyznačené podstromy odpovídají dále uvedeným frázím definovaným k příslušným nonterminá-lům. Horní indexy slouží k rozlišení výskytu téhož nonterminálu (viz 4.6)

Fráze Nonterminálaabbccdd S

aabb A1

ab A2

ccdd B1

cd B2

Fráze ab a cd jsou jednoduché, ab je l-fráze.

4.3 Víceznačnost gramatik

Page 37: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 33

Obrázek 4.6: Podstromy derivačního stromu

Definice 4.5 Nechť G je gramatika. Říkáme, že věta w generovaná gramatikou G je víceznačná,existují-li alespoň dva různé derivační stromy s koncovými uzly tvořícími větu w. Gramatika Gje víceznačná, jestliže generuje alespoň jednu víceznačnou větu. V opačném případě mluvímeo jednoznačné gramatice.

Povšimněte si, že definujeme víceznačnou gramatiku, nikoli víceznačný jazyk. V mnoha přípa-dech lze vhodnými transformacemi víceznačné gramatiky odstranit víceznačnost vět, aniž sesamozřejmě změní jazyk generovaný získanou jednoznačnou gramatikou. Existují však jazyky,které nelze generovat jednoznačnou gramatikou. Takové jazyky jsou pak nazývány jazyky s inhe-rentní víceznačností.

Příklad 4.7 Uvažujme gramatiku G = ({E}, {+,−, ∗, /, (, ), i}, P, E), kde P je množina pravi-del

E := E + E | E − E | E ∗ E | E / E | ( E ) | i

Jazyk L(G) je totožný s jazykem generovaným gramatikou z příkladu 4.3 a je tvořen aritmetic-kými výrazy s binárními operacemi.

Tato gramatika je na rozdíl od gramatiky z příkladu 4.3 víceznačná. Vezměme například větui+ i ∗ i a uvažujme všechny možné derivační stromy příslušející k této větě (viz obr. 4.7).

Existence dvou různých derivačních stromů k větě i+i∗i dokazuje, že gramatika G je víceznačná.Označuje-li se + sečítání a ∗ násobení, pak není jasné, zda první operací bude násobení (prvníderivační strom), a nebo sečítání (druhý derivační strom). Jednoznačná gramatika z příkladu 4.3na druhé straně respektuje obvyklou prioritou operací (násobení má přednost před sečítáním),jak je patrno z jediného derivačního stromu věty i+i*i na obr. 4.8

Pro bezkontextové gramatiky bylo dokázáno, že problém, zda daná gramatika je a nebo nenívíceznačná, je nerozhodnutelný, tj. neexistuje algoritmus, který by v konečném čase odhalilvíceznačnost každé bezkontextové gramatiky.

Příklad 4.8 Gramatika obsahující pravidlo tvaru A → A je zřejmě víceznačná. Toto pravidlomůžeme vypustit, aniž změníme jazyk generovaný takto zredukovanou gramatikou.

Poznámka 4.2 Víceznačnost gramatiky, pokud negeneruje jazyk s inherentní víceznačností, jeobecně pokládána za negativní rys, poněvadž vede k větám, jež mají několik interpretací. Na

Page 38: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

34 0 0 1

Obrázek 4.7: Derivační stromy věty i+ i ∗ i

Obrázek 4.8: Derivační strom věty i+ i ∗ i v G2

druhé straně však víceznačná gramatika může být jednodušší, než odpovídající jednoznačnágramatika (viz příklad 4.7). Této skutečnosti se někdy využívá při konstrukci překladačů tako-vým způsobem, že se použije víceznačné gramatiky a nežádoucí interpretace víceznačné věty sevyloučí dodatečným sémantickým pravidlem.

Příklad 4.9 Jedním z nejznámějších příkladů víceznačnosti v programovacích jazycích jsoukonstrukce s then a else. Skutečně, přepisovací pravidla

S → if b then S else S

S → if b then S

S → p

kde b značí booleovský výraz a p jiný, než podmíněný příkaz, vedou k víceznačné interpretacipodmíněného příkazu. Např. k větě

if b then if b then p else p

Page 39: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 35

existují dva různé derivační stromy. Zatím, co Algol 60 tuto konstrukci nedovoluje (za then musíbýt složený příkaz), jazyk Pascal uvedenou víceznačnost řeší sémantickým pravidlem: „k danémuelse se vztahuje nejbližší předchozí thenÿ. Poznamenejme, že i toto pravidlo lze postihnout takésyntakticky:

S1 → if b then S1 | if b then S2 else S1 | pS2 → if b then S2 else S2 | p

S použitím těchto přepisovacích pravidel obdržíme pro větu if b then if b then p else p jedinýderivační strom na obr. 4.9.

Obrázek 4.9: Derivační strom podmíněného příkazu

4.4 Rozklad věty

Konstrukci derivace či derivačního stromu pro danou větu nebo větnou formu nazýváme rozkla-dem nebo syntaktickou analýzou této věty nebo větné formy. Program, který provádí rozkladvět určitého jazyka, se nazývá syntaktický analyzátor (anglicky také parser, to parse = rozložit).

Algoritmy syntaktické analýzy lze rozdělit podle způsobu, kterým je konstruována derivace věty,tj. vytvářen derivační strom, do těchto dvou základních skupin:

- syntaktická analýza shora dolů

- syntaktická analýza zdola nahoru

Při syntaktické analýze shora dolů začínáme derivační strom budovat od výchozího symbolu(kořene derivačního stromu) a postupnými přímými derivacemi dojdeme k terminálním symbo-lům, které tvoří analyzovanou větu (koncovým uzlům derivačního stromu). Problém spočívá vesprávnosti volby přímých derivací, tj. pořadí používání přepisovacích pravidel.

Při syntaktické analýze zdola nahoru začínáme derivační strom budovat od koncových uzlů apostupnými přímými redukcemi dojdeme ke kořenu (výchozímu symbolu gramatiky).

Page 40: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

36 0 0 1

Základním problémem této třídy syntaktických analyzátorů je hledání prvního podřetězce věty(v dalších krocích větných forem), který může být redukován k jistému nonterminálu – kořenupodstromu derivačního stromu. Tento podřetězec, jak již víme, se nazývá l-fráze.

Příklad 4.10 Myšlenku obou typů syntaktické analýzy ilustrujeme na příkladě gramatiky,která generuje jazyk L = {anbmcmdn | n ≥ 1,m ≥ 1}. Tato gramatika má pravidla

S → aSd | aAdA → bAc | bc

kde S je výchozí symbol.

Na obr. 4.10 je uvedena konstrukce derivačního stromu metodou shora dolů spolu s odpovídajícílevou derivací věty abbccd. Na obr. 4.11 je znázorněna konstrukce derivačního stromu metodou

Obrázek 4.10: Syntaktická analýza shora dolů

zdola nahoru. Odpovídající pravá derivace je zapsána zprava doleva.

Vraťme se opět k základním problémům syntaktické analýzy. Při analýze shora dolů konstruu-jeme levou derivaci věty. Předpokládejme, že v jistém kroku analýzy je A nejlevějším nontermi-nálem, který má být přepsán. Dále předpokládejme, že gramatika obsahuje n pravidel s levoustranou A:

A→ α1 | α2 | . . . | αn

Jak poznáme, kterým řetězcem αi je třeba nahradit nonterminál A? Podobně při analýze zdolanahoru, kdy je v každém kroku redukována l-fráze větné formy, spočívá hlavní problém v určenízačátku a konce l-fráze.

Jedním z řešení těchto problémů je náhodný výběr některé z možných alternativ. Ukáže-li sepozději, že zvolená alternativa nebyla správná, je třeba proces rozkladu „vrátitÿ a uvažovatjinou alternativu. (Při syntaktické analýze shora dolů se například pokoušíme přepisovat A ře-tězci α1, α2 . . . tak, aby se prefix získané levé derivace, který obsahuje pouze terminální symboly,shodoval s prefixem analyzované věty). Tento typ analýzy se nazývá syntaktická analýza s ná-vratem (Syntax analysis with backup). I když počet návratů je omezený, je patrné, že analýzas návratem je časově náročná. Kromě toho jsou návraty zdrojem komplikací při sémantickémvyhodnocování překládaného programu.

Page 41: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 37

Obrázek 4.11: Syntaktická analýza zdola nahoru

Praktickým řešením problémů syntaktické analýzy programovacích jazyků jsou tzv. determinis-tické gramatiky (kapitola 6.), které umožňují na základě kontextu zpracovávaného podřetězcevětné formy, určit správnou alternativu v každém kroku analýzy. Tento typ syntaktické analýzyse nazývá deterministická syntaktická analýza (deterministický rozklad) nebo syntaktická ana-lýza bez návratu. Pro ilustraci role kontextu uvažujme větu i+ i ∗ i v gramatice z příkladu 4.3.Po zpracování podřetězce i + i nám kontext reprezentovaný terminálem ∗ pomůže určit frázi,kterou není i+ i, ale podřetězec i ∗ i.

4.5 Transformace bezkontextových gramatik

Obecně neexistuje algoritmická metoda, která by umožňovala sestrojit gramatiku generující ja-zyk s libovolnou strukturou. Existuje však celá řada užitečných transformací gramatik, kterédovolují modifikovat gramatiku, aniž by byl porušen generovaný jazyk. V tomto odstavci popí-šeme některé z těchto transformací formou matematických zápisů příslušných algoritmů.

Definice 4.6 Říkáme, že gramatiky G1 a G2 jsou ekvivalentní, jestliže platí L(G1) = L(G2), tj.jestliže jimi generované jazyky jsou totožné.

V některých případech se může stát, že sestrojená gramatika obsahuje zbytečné symboly a nad-bytečná přepisovací pravidla. Nehledě k tomu, že tato skutečnost může být důsledkem chybyv konstrukci gramatiky, je velmi pravděpodobné, že syntaktická analýza bude probíhat méněefektivně. Je proto důležité odstranit z gramatiky zbytečné symboly a nadbytečná pravidla.

Uvažujme například gramatiku G = ({S,A}, {a, b}, P, S), kde P = {S → a,A → b}. Je zřejmé,že nonterminál A a terminál b se nemohou objevit v žádné větné formě. Proto je můžemez gramatiky G odstranit spolu s nadbytečným pravidlem A→ b, aniž se změní L(G).

Definice 4.7 Nechť G = (N,Σ, P, S) je gramatika. Říkáme, že symbol X ∈ (N ∪ Σ) je v gra-matice G zbytečný, jestliže neexistuje derivace tvaru S⇒∗wXy⇒∗wxy. Řetězce w, x, y jsouv Σ∗.

Abychom zjistili, zda nonterminál A je zbytečný, popíšeme algoritmus určující, může-li se z non-terminálu A generovat řetězec terminálních symbolů, tj. zjišťujeme, zda {w | A⇒∗w, w ∈ Σ∗} =∅

Page 42: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

38 0 0 1

Tento algoritmus lze formulovat jako algoritmus, který zjišťuje, je-li jazyk, generovaný bezkon-textovou gramatikou, neprázdný.

Algoritmus 4.1 Je L(G) neprázdný?

Vstup: gramatika G = (N,Σ, P, S).

Výstup: ANO je-li L(G) 6= ∅, NE v opačném případě.

Metoda: Sestrojíme množiny N0, N1, . . . rekurzivně takto

(1) N0 = ∅, i = 1

(2) Ni = {A | A→ α je v P ∧ α ∈ (Ni−1 ∪ Σ)∗} ∪Ni−1

(3) Je-li Ni 6= Ni−1, polož i = i+ 1 a vrať se ke kroku 2. Je-li Ni = Ni−1, polož Nt = Ni

(4) Jestliže výchozí symbol S je v Nt, pak je výstup ANO, jinak NE.

Poznámka 4.3 Jestliže množina nonterminálů N má n prvků, pak, protože Nt ⊆ N , musíalgoritmus 4.1 skončit maximálně po n+ 1 iteracích kroku 2.

Věta 4.1 Algoritmus 4.1 má výstup ANO, právě když S⇒∗w pro nějaké w ∈ Σ∗ Důkaz:Nejprve dokážeme indukcí pro i implikaci:

Jestliže platí A ∈ Ni, pak A∗⇒w pro nějaké w ∈ Σ∗(1)

Pro i = 0 implikace platí, protože N0 = ∅. Předpokládejme, že (1) platí pro i, a že A jeprvkem množiny Ni+1. Je-li zároveň A ∈ Ni, pak je induktivní krok triviální. Jestliže A ležív Ni+1 − Ni, pak existuje pravidlo A → X1 . . . Xk, kde Xj je buď terminální symbol, neboXj ∈ Ni, j = 1, . . . , k. Pro každé j tedy existuje řetězec wj ∈ Σ∗ takový, že Xj⇒∗wj a platítak

A⇒ X1 . . . Xk∗⇒w1X2 . . . Xk

∗⇒ . . .∗⇒w1 . . . wk = w

Opačnou implikaci:Jestliže A

n⇒w, pak A ∈ Ni pro nějaké i(2)

dokážeme opět indukcí.

Je-li n = 1, pak zřejmě i = 1. Předpokládejme, že (2) platí pro n, a že A⇒n+1 w . Pak můžemepsát A⇒ X1 . . . Xk⇒nw, kde w = w1 . . . wk a Xj⇒nj wj pro j = 1, . . . , k, nj ≤ n. (Podřetězcewj jsou fráze řetězce w vzhledem k nonterminálům Xj v případě, že Xj ∈ N , pak Xj ∈ Nij pronějaké ij . Položme ij = 0, jestliže Xj ∈ Σ. Nechť i = 1 + max(i1, . . . , ik). Pak, podle definice,A ∈ Ni. Položíme-li nyní A = S v implikacích (1) a (2), dostáváme důkaz věty 4.1. 2

Definice 4.8 Říkáme, že symbol X ∈ (N ∪ Σ) je nedostupný v gramatice G = (N,Σ, P, S),jestliže X se nemůže objevit v žádné větné formě.

Algoritmus 4.2 Odstranění nedostupných symbolů

Vstup: Gramatika G = (N,Σ, P, S).

Výstup: Gramatika G′ = (N ′,Σ′, P ′, S), pro kterou platí

(i) L(G′) = L(G)

Page 43: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 39

(ii) Pro všechna X z (N ′ ∪ Σ′) existují řetězce α a β z (N ′ ∪ Σ′)∗ tak, že S ⇒ αXβv gramatice G′.

Metoda:

(1) Položíme V0 = {S} a i = 1

(2) Konstruujeme Vi = {X | A→ αXβ ∈ P ∧A ∈ Vi−1} ∪ Vi−1

(3) Je-li Vi 6= Vi−1, polož i = i+ 1 a vrať se ke kroku 2.

Je-li Vi = Vi−1, pak

N ′ = Vi ∩NΣ′ = Vi ∩ Σ

P ′ ⊆ P obsahuje ta pravidla, která jsou tvořena pouze symboly z Vi.

Algoritmus 3.2 je podobný algoritmu 4.1. Protože je Vi ⊂ N ∪ Σ, je počet opakování bodu (2)algoritmu 4.2 konečný. Důkaz algoritmu se provede indukcí pro i této ekvivalence:

S∗⇒αXβ, právě když X ∈ Vi pro nějaké i.

Nyní zformulujeme algoritmus pro odstranění zbytečných symbolů.

Algoritmus 4.3 Odstranění zbytečných symbolů.

Vstup: Gramatika G = (N,Σ, P, S) generující neprázdný jazyk.

Výstup: Gramatika G′ = (N ′,Σ′, P ′, S), pro kterou platí:

(i) L(G) = L(G′)

(ii) Žádný symbol v N ′ ∪ Σ’ není zbytečný

Metoda:

(1) Na gramatiku G aplikuj algoritmus 4.1 s cílem získat množinu Nt. Polož G = (N ∩Nt,Σ, P1, S), kde P1 obsahuje pravidla tvořené pouze symboly z Nt ∪ Σ

(2) Algoritmus 4.2 aplikuj na gramatiku G. Výsledkem je gramatika G′ = (N ′,Σ′, P ′, S),která neobsahuje zbytečné symboly.

V kroku (1) algoritmu 4.3 jsou z G odstraněny všechny nonterminály, které nemohou generovatterminální řetězce. V kroku (2) jsou pak odstraněny všechny symboly, které jsou nedostupné.Obrácené pořadí použití algoritmů 4.1 a 4.2 nemusí vždy vést ke gramatice bez zbytečnýchsymbolů.

Věta 4.2 Gramatika G′ z algoritmu 4.3 je ekvivalentní gramatice G a nemá zbytečné symboly.

Důkaz: Dokážeme sporem, že gramatika G′ nemá zbytečné symboly. Předpokládejme, že A ∈ N ′je zbytečný symbol. Podle definice zbytečných symbolů musíme uvažovat dva případy:

1. Neplatí S⇒∗G′ αAβ pro všechna α a β. V tomto případě se však dostáváme do sporu

s krokem (2) algoritmu 4.3.

Page 44: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

40 0 0 1

2. Platí S⇒∗G′ αAβ pro nějaká α a β, avšak neplatí A⇒∗

G′ w,w ∈ Σ′∗. Pak A nebude odstra-

něn v kroku (2) algoritmu 4.3 a navíc, platí-li A⇒∗G γBδ, pak ani B nebude odstraněnv kroku (2). Platí-li však A⇒∗Gw, pak také platí A⇒∗

G′ w a tedy neplatí-li A⇒∗G′ w, pak

neplatí ani A⇒∗Gw, což je spor s krokem (1) algoritmu 4.3.

Důkaz, že G′ neobsahuje ani zbytečný terminál se provede obdobně. 2

Příklad 4.11 Uvažujme gramatiku G = ({S,A,B}, {a, b}, P, S), kde P obsahuje pravidla:

S → a | AA → AB

B → b

Aplikujeme-li na G algoritmus 4.3, pak v kroku 1 získáme Nt = {S,B}, takže G = ({S,B}, {a, b},{S → a,B → b}, S}). Po aplikování algoritmu 4.2 na G obdržíme V2 = V1 = {S, a}. Výsledkemje tedy ekvivalentní gramatika

G′ = ({S}, {a}, {S → a}, S).

Kdybychom jako první aplikovali algoritmus 4.2, zjistíme, že všechny symboly v G jsou dostupnéa algoritmus 4.2 tedy gramatiku G nezmění. Po aplikování algoritmu 4.1 získáme Nt = {S,B},takže výsledná gramatika bude G a ne G′.

Další důležitou transformací, kterou nyní popíšeme, je transformace odstraňující z gramatikypravidla tvaru A→ ε (ε je prázdný řetězec), tzv. ε-pravidla. Jestliže ovšem L(G) má obsahovattaké prázdný řetězec, pak není možné aby G neobsahovala žádné ε-pravidlo. Následující definicegramatiky bez ε-pravidla respektuje tuto skutečnost.

Definice 4.9 Říkáme, že gramatika G = (N,Σ, P, S) je gramatikou bez ε-pravidel, jestliže buďP neobsahuje žádné ε-pravidlo, nebo existuje jediné ε-pravidlo tvaru S → ε a výchozí symbol Sse nevyskytuje na pravé straně žádného pravidla z P .

Algoritmus 4.4 Transformace na gramatiku bez ε-pravidel.

Vstup: Gramatika G = (N,Σ, P, S)

Výstup: Ekvivalentní gramatika G′ = (N ′,Σ′, P ′, S′) bez ε-pravidel.

Metoda:

(1) Sestroj Nε = {A | A ∈ N a A⇒∗ ε}. Konstrukce množiny Nε je analogická konstrukciNt z 4.1.

(2) Nechť P ′ je množina pravidel, kterou konstruujeme takto:

a) Jestliže A → α0B1α1B2 . . . Bkαk je v P, k ≥ 0 a každé Bi je v Nε, 1 ≤ i ≤ k,avšak žádný ze symbolů řetězců αj není v Nε, 0 ≤ j ≤ k, pak k P ′ přidej všechnapravidla tvaru

A→ α0X1α1X2 . . . Xkαk

kde Xi je buď Bi nebo ε. Nepřidávej ε-pravidlo A → ε, které se objeví, jsou-livšechna αi = ε.

Page 45: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 41

b) Jestliže S ∈ Nε pak k P ′ přidej pravidla

S′ → ε | S

S′ je nový výchozí symbol. Polož N ′ = N ∪ {S′} Jestliže S /∈ Nε, pak N ′ = N aS′ = S

(3) Výsledná gramatika má tvar G′ = (N ′,Σ′, P ′, S′)

Příklad 4.12 Uvažujme gramatiku G = ({S}, {a, b}, P, S), kde P obsahuje pravidla S →aSbS | bSaS | ε. Po aplikování algoritmu 4.4 získáme gramatiku G′ bez ε-pravidel. G′ =({S′, S}, {a, b}, P ′, S′), kde P ′ obsahuje pravidla

S′ → S | εS → aSbS | bSaS | aSb | abS | ab | bSa | baS | ba

Věta 4.3 Algoritmus 4.3 převádí vstupní gramatiku G na ekvivalentní gramatiku G′ bez ε-prav.Důkaz: G′ zřejmě neobsahuje ε-pravidla kromě případného pravidla S → ε, je-li ε ∈ L(G).Důkaz, že L(G) = L(G′) se provede indukcí pro délku řetězce w v ekvivalenci

A∗⇒G′w právě když w 6= ε ∧A ∗⇒

Gw

Jinou užitečnou transformací je odstranění pravidel tvaru A→ B. 2

Definice 4.10 Přepisovací pravidlo tvaru A→ B,A,B ∈ N se nazývá jednoduché pravidlo.

Algoritmus 4.5 Odstranění jednoduchých pravidel.

Vstup: Gramatika G bez ε-pravidel.

Výstup: Ekvivalentní gramatika G′ bez jednoduchých pravidel.

Metoda:

(1) Pro každé A ∈ N sestroj množinu NA = {B | A⇒∗B} takto:

a) N0 = {A}, i = 1

b) Ni = {C | B → C je v P a B ∈ Ni−1} ∪Ni−1

c) Jestliže Ni 6= Ni−1, polož i = i + 1 a opakuj krok b). V opačném případě jeNA = Ni.

(2) Sestroj P ′ takto: Jestliže B → α je v P a není jednoduchým pravidlem, pak provšechna A, pro něž B ∈ NA, přidej k P ′ pravidla A→ α

(3) Výsledná gramatika je G = (N,Σ, P ′, S)

Příklad 4.13 Uvažujme gramatiku s přepisovacími pravidly:

E → E + T | TT → T ∗ F | FF → (E) | i

Tato gramatika se liší od gramatiky z příkladu 4.3 pouze jiným značením nonterminálu a generujetudíž stejný jazyk aritmetických výrazů

Page 46: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

42 0 0 1

Po aplikování algoritmu 4.5 bude

NE = {E, T, F}NT = {T, F}NF = {F}

a výsledná množina přepisovacích pravidel, neobsahující jednoduchá pravidla, bude:

E → E + T | T ∗ F | (E) | iT → T ∗ F | (E) | iF → (E) | i

Věta 4.4 Algoritmus 4.4 převádí vstupní gramatiku G na ekvivalentní gramatiku G′ bez jed-noduchých pravidel. Důkaz: Gramatika G′ zřejmě neobsahuje jednoduchá pravidla. Abychomukázali, že L(G) = L(G′), dokážeme že platí L(G′) ⊆ L(G) a také L(G) ⊆ L(G′).

1. L(G′) ⊆ L(G)

Nechť w ∈ L(G′). Pak existuje v G′ derivace S = α0 ⇒ α1 ⇒ . . .⇒ αn = w.

Jestliže k derivaci αi⇒G′ αi+1 bylo použito pravidla A → β, pak existuje nonterminál B(A = B případně) takový, že A⇒∗GB a B⇒G β a tedy A⇒∗G β a αi⇒∗G αi+1. Z toho plyne,že platí S⇒∗Gw a w je tudíž v L(G).

2. L(G) ⊆ L(G′)

Nechť w ∈ L(G) a S = α0 ⇒ α1 ⇒ . . . ⇒ αn = w je levá derivace řetězce w v gramaticeG. Nechť i1, i2, . . . ik je posloupnost indexů tvořená pouze těmi j, pro které v levé derivaciαj−1 ⇒ αj nebylo použito jednoduchého pravidla. Speciálně ik = n, protože posledníaplikované pravidlo v derivaci řetězce w nemůže být jednoduché. Derivace řetězce w v Gje levou derivací, a proto aplikací jednoduchých pravidel nahrazujeme pouze nejlevějšínonterminál jiným nonterminálem (reprezentuje levou stranu pravidla v G′). Platí tedyS⇒

G′ αi1⇒G′ . . .⇒G′ αi1 = w a tudíž w ∈ L(G′).

Dokázali jsme tak ekvivalenci gramatik G a G′. 2

Definice 4.11 Říkáme, že G je gramatika bez cyklu, jestliže v ní neexistuje derivace tvaruA⇒+ A pro žádné A z N . Jestliže G je gramatika bez cyklu a bez ε-pravidel a nemá žádnézbytečné symboly, pak říkáme, že G je vlastní gramatika.

Věta 4.5 Je-li L bezkontextový jazyk, pak existuje vlastní gramatika G taková, že L = L(G).Důkaz: Vyplývá z algoritmů 4.1–4.5. Gramatika, jež neobsahuje ε-pravidla a jednoduchá pra-vidla, je zřejmě gramatikou bez cyklu. Existence ε-pravidel a jednoduchých pravidel, na druhéstraně, neimplikuje existenci cyklu (tj. derivace tvaru A⇒+ A pro nějaké A ∈ N). 2

Poznámka 4.4 Gramatiky, které obsahují ε-pravidla a cykly, komplikují obvykle algoritmyrozkladu. Většina efektivních syntaktických analyzátorů je konstruována pro vlastní gramatiku.

Další transformací, kterou uvedeme, je odstranění levé rekurze. Tato transformace je důležitápro použití analýzy typu shora-dolů.

Page 47: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 43

Definice 4.12 Nechť G = (N,Σ, P, S). Přepisovací pravidlo z P se nazývá rekurzi zleva (rekur-zivní zprava), jestliže je tvaru A → Aα(A → αA), A ∈ N,α ∈ (N ∪ Σ)∗. Jestliže v G existujederivace A⇒+ αAβ, pro nějaké A ∈ N , říkáme, že gramatika G je rekurzivní. Je-li α = ε, pakmluvíme o gramatice rekurzivní zleva, je-li β = ε, pak říkáme, že G je rekurzivní zprava.

Poznamenejme, že je-li jazyk L(G) nekonečný, pak G musí být rekurzivní.

Dříve, než zformujeme algoritmus eliminující levou rekurzi, ukážeme, jakým způsobem lze od-stranit přepisovací pravidla rekurzivní zleva.

Definice 4.13 Pravidlo A → α , s levou stranou tvořenou nonterminálem A, budeme nazývatA-pravidlo (Neplést s ε-pravidlem.)

Věta 4.6 Nechť G = (N,Σ, P, S) je gramatika a nechť A → Aα1 | Aα2 | . . . | Aαm | β1 |β2 | . . . | βn jsou všechna A-pravidla. Žádný z řetězců βi nezačíná nonterminálem A. GramatikaG′ = (N ∪ {A′},Σ, P ′, S), kde P ′ obsahuje namísto uvedených pravidel pravidla

A → β1 | β2 | . . . | βn | β1A′ | β2A

′ | . . . | βnA′

A′ → α1 | α2 | . . . | αm | α1A′ | α2A

′ | . . . | αmA′

je ekvivalentní s gramatikou G, tj. L(G) = L(G′). Důkaz: Uvedena transformace nahra-zuje pravidla rekurzivní zleva pravidly, která jsou rekurzivní zprava. Označíme-li jazyky L1 ={β1, β2, . . . , βn} a L2 = {α1, α2, . . . , αm} vidíme, že v G lze z nonterminálu A derivovat řetězcetvořící jazyk L1L

∗2. Právě tyto řetězce můžeme však derivovat z A také v gramatice G′. Efekt

popisované transformace ilustruje obrázek 4.12. 2

Obrázek 4.12: Odstranění levé rekurze: nalevo část stromu v G, napravo část stromu v G′

Příklad 4.14 Uvažujme gramatiku G z předcházejícího příkladu s pravidly

E → E + T | TT → T ∗ F | FF → (E) | i

Page 48: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

44 0 0 1

Po odstranění pravidel rekurzivních zleva získáme ekvivalentní gramatiku G′ s pravidly

E → T | TE′

E′ → +T | +TE′

T → F | FT ′

T ′ → ∗F | ∗FT ′

F → (E) | i

Věta 4.7 Nechť G = (N,Σ, P, S) je gramatika. A→ αBβ, B ∈ N ;α, β ∈ (N ∪ Σ)∗ je pravidloz P a B → γ1 | γ2 | . . . | γn jsou všechna B-pravidla v P . Nechť G′ = (N,Σ, P ′, S), kde

P ′ = P − {A→ αBβ} ∪ {A→ αγ1β | αγ2β | . . . | αγnβ}.

Pak L(G) = L(G′). Důkaz: Výsledkem této transformace je odstranění pravidla A → αBβz gramatiky G tím způsobem, že za nonterminál B „dosadímeÿ všechny pravé strany B-pravidel.Formálně se důkaz provede tak, že se ukáže platnost konjunkce L(G) ⊆ L(G) ∧ L(G′) ⊆ L(G).Efekt této transformace ilustruje obr. 4.13, jenž znázorňuje derivační stromy řetězce aabbb v gra-matice G resp. G′. Gramatika G obsahuje pravidlo A → aAA a dvě A-pravidla A → aAA | b.Položíme-li α = a,B = A, β = A, můžeme eliminovat pravidlo A → aAA zavedením těchtoA-pravidel v gramatice G′:

A→ aaAAA | abA | b

2

Obrázek 4.13: Derivační stromy věty aabbb v G resp. G′

Algoritmus 4.6 Odstranění levé rekurze.

Vstup: Vlastní gramatika G = (N,Σ, P, S)

Výstup: Gramatika G′ bez levé rekurze.

Metoda:

(1) Nechť N = {A1, A2, . . . , An}. Gramatiku budeme transformovat tak, že je-li Ai → αpravidlo, pak α začíná buď terminálem, nebo nonterminálem Aj , j > i. K tomu účelupoložme i = 1.

Page 49: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 45

(2) Nechť Ai → Aiα1 | . . . | Aiαm | β1 | . . . | βp jsou všechna Ai-pravidla a nechť žádnéβi nezačíná nonterminálem Ak, je-li k ≤ i.Nahraď všechna Ai-pravidla těmito pravily:

Ai → β1 | . . . | βp | β1A′i | . . . | βpA′i

A′i → α1 | . . . | αm | α1A′i | . . . | αmA′i

kde A′i je nový nonterminál. Takto všechna Ai-pravidla začínají buď terminálem, nebononterminálem Ak, k > i.

(3) Je-li i = n, pak jsme získali výslednou gramatiku G′. V opačném případě položi = i+ 1 a j = 1.

(4) Každé pravidlo tvaru Ai → Ajα nahraď pravidly Ai → β1α | . . . | βpα kde Aj → β1 |. . . | βp jsou všechna Aj-pravidla. Po této transformaci budou všechna Aj-pravidla za-čínat buď terminálem, nebo nonterminálem Ak, k > j, takže také všechna Ai-pravidlabudou mít tuto vlastnost.

(5) Je-li j = i− 1, pak přejdi ke kroku (2). Jinak j = j + 1 a opakuj krok (4).

Věta 4.8 Každý bezkontextový jazyk lze generovat gramatikou bez levé rekurze. Důkaz: NechťG je vlastní gramatika. Algoritmus 4.6 používá pouze transformací z vět 4.6 a 4.7 a tudíž jeL(G) = L(G′).

Dále musíme dokázat, že G′ není gramatikou rekurzivní zleva. Formální důkaz nebudeme pro-vádět (viz [3]). Uvědomíme si však, že krok (2) odstraňuje pravidla rekurzivní zleva. Stejnětak pravidla vzniklá aplikací kroku (4) nejsou rekurzivní zleva. Protože krok (2) je aplikovánna všechny nonterminální symboly, nemůže výsledná gramatika obsahovat pravidla rekurzivnízleva. 2

Příklad 4.15 Nechť G je gramatika s pravidly:

A → BC | aB → CA | AbC → AB | CC | a

Položme A1 = A,A2 = B a A3 = C. V každém kroku uvedeme pouze nová pravidla pro tynonterminály, jejichž pravidla se mění.

krok (2), i=1, beze změnykrok (4), i=2, j=1, B → CA | BCb | abkrok (2), i=2, B → CA | ab | CAB′ | abB′

B′ → CbB′ | Cbkrok (4), i=3, j=1, C → BCB | aB | CC | akrok (4), i=3, j=2, C → CACB | abCB | CAB′CB | abB′CB | aB | CC | akrok (2), i=3, C → abCB | abB′CB | aB | a | abCBC ′ | abB′CBC ′ | aBC ′ | aC ′

C ′ → ACBC ′ | AB′CBC ′ | CC ′ | ACB | AB′CB | C

4.6 Chomského normální forma

Definice 4.14 Gramatika G = (N,Σ, P, S) je v Chomského normální formě (CNF), jestližekaždé pravidlo z P má jeden z těchto tvarů:

Page 50: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

46 0 0 1

(1) A→ BC,A,B,C ∈ N nebo

(2) A→ a, a ∈ Σ nebo

(3) Je-li ε ∈ L(G), pak S → ε je pravidlo z P a výchozí symbol S se neobjeví na pravé straněžádného pravidla.

Chomského normální forma gramatiky je prostředkem zjednodušujícím tvar reprezentace bez-kontextového jazyka. Nyní popíšeme algoritmus převodu obecné bezkontextové gramatiky doChomského normální formy.

Algoritmus 4.7 Převod do Chomského normální formy.

Vstup: Vlastní gramatika G = (N,Σ, P, S) bez jednoduchých pravidel.

Výstup: Gramatika G′ = (N ′,Σ, P ′, S′) v CNF taková, že L(G) = L(G′)

Metoda: Z gramatiky G získáme ekvivalentní gramatiku G′ v CNF takto:

(1) Množina pravidel P ′ obsahuje všechna pravidla tvaru A→ a z P

(2) Množina pravidel P ′ obsahuje všechna pravidla tvaru A→ BC z P

(3) Je-li pravidlo S → ε v P , pak S → ε je také v P ′

(4) Pro každé pravidlo tvaru A → X1 . . . Xk, kde k > 2 z P přidej k P ′ tuto množinupravidel. Symbolem X ′i značíme nonterminál Xi, je-li Xi ∈ N , nebo nový nonterminál,je-li Xi ∈ Σ:

A → X ′1〈X2 . . . Xk〉〈X2 . . . Xk〉 → X ′2〈X3 . . . Xk〉

...

〈Xk−1Xk〉 → X ′k−1X′k

kde každý symbol 〈Xi . . . Xk〉 značí nový nonterminální symbol.

(5) Pro každé pravidlo tvaru A → X1X2, kde některý ze symbolů X1 nebo X2 leží v Σpřidej k P ′ pravidlo A→ X ′1X

′2.

(6) Pro každý nový nonterminál tvaru a′ přidej k P ′ pravidlo a′ → a. Výsledná gramatikaje G′ = (N ′,Σ, P ′, S′); množina N ′ obsahuje všechny nonterminály tvaru 〈Xi . . . Xk〉a a′.

Věta 4.9 Nechť L je bezkontextový jazyk. Pak existuje bezkontextová gramatika G v CNFtaková, že L = L(G). Důkaz: Podle věty 4.5 má jazyk L vlastní gramatiku G. Stačí tedy dokázat,že výsledkem algoritmu 4.7 je ekvivalentní gramatika G′ tj. L(G) = L(G′). Tato ekvivalence všakplyne bezprostředně z aplikace věty 4.7 na každé pravidlo z P ′, které má nonterminály tvaru a′

a 〈Xi...Xj〉. Výsledkem bude gramatika G′. 2

Příklad 4.16 Nechť G je gramatika s pravidly

S → aAB | BAA → BBB | aB → AS | b

Page 51: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

4.7. Greibachova normální forma 47

Chomského normální forma G′ = (N ′, {a, b}, P ′, S) má pravidla:

S → a′〈AB〉 | BAA → B〈BB〉 | aB → AS | b

〈AB〉 → AB

〈BB〉 → BB

a′ → a

Nová množina nonterminálů je tedy N ′ = {S,A,B, 〈AB〉, 〈BB〉, a′}

Příklad 4.17 Předpokládejme, že gramatika G je v CNF, a že řetězci w ∈ L(G) přísluší derivacev G délky p. Jaká je délka věty w? Řešení: Nechť |w| = n. Pak pro odvození věty bylo třeban-krát aplikovat pravidlo tvaru A → a a (n-1)-krát pravidlo tvaru A → BC. Dostáváme tedyvztah

p = n+ n− 1 = 2n− 1

a vidíme, že p je vždy liché. Řešení příkladu je tedy

|w| = p+ 12

2

4.7 Greibachova normální forma

Definice 4.15 Gramatika G = (N,Σ, P, S) je v Greibachové normální formě (GNF), je-li Ggramatikou bez ε-pravidel a jestliže každé pravidlo (s výjimkou případného pravidla S → ε) mátvar A→ aα kde a ∈ Σ a α ∈ N∗.

Lemma 4.1 Nechť G = (N,Σ, P, S) je gramatika bez levé rekurze. Pak existuje lineární uspo-řádání < definované na množině nonterminálních symbolů N takové, že je-li A→ Bα v P , pakA < B. Důkaz: Nechť R je relace na množině N taková, že ARB platí právě když A⇒+ Bα pronějaké α ∈ (N∪Σ)∗. Z definice levé rekurze plyne, že R je částečné uspořádání (R je tranzitivní).Každé částečné uspořádání pak lze rozšířit na lineární uspořádání. 2

Nyní zformulujeme algoritmus převodu gramatiky G do Greibachové normální formy.

Algoritmus 4.8 Převod do Greibachové normální formy.

Vstup: Vlastní gramatika bez levé rekurze G = (N,Σ, P, S)

Výstup: Ekvivalentní gramatika G′ v GNF

Metoda:

(1) Podle lemmy 4.1 vytvoř lineární uspořádání < na N takové, že každé A-pravidlozačíná buď terminálem, nebo nějakým nonterminálem B takovým, že A < B. Nechť

N = {A1, A2, . . . , An} a A1 < A2 < . . . < An.

Page 52: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

48 0 0 1

(2) Polož i = n− 1

(3) Je-li i = 0 přejdi k bodu (5), je-li i 6= 0 nahraď každé pravidlo tvaru Ai → Ajα, kdej > i pravidly Ai → β1α | . . . | βmα, kde Aj → β1 | . . . | βm jsou všechna Aj-pravidla.(Každý z řetězců β1 . . . βm začíná terminálem.)

(4) Polož i = i− 1 a opakuj krok (3).

(5) V tomto okamžiku všechna pravidla (s vyjímkou pravidla S → ε) začínají terminálnímsymbolem. V každém pravidle A → aX1 . . . Xk nahraď ty symboly Xj , které jsouterminálnímy symboly, novým nonterminálem X ′j .

(6) Pro všechna X ′j z bodu (5) přidej pravidla X ′j → Xj

Věta 4.10 Nechť L je bezkontextový jazyk. Pak existuje gramatika G v GNF taková, že L =L(G). Důkaz: Z definice uspořádání < vyplývá, že všechna An-pravidla začínají terminály, a žepo opakovaném provádění kroku (3) algoritmu 4.8 budou všechna Ai-pravidla pro i = 1, . . . , n−1začínat také terminálními symboly. Krok (5) a (6) převádí nepočáteční terminální symbolypravých stran na nonterminály, aniž se podle věty 4.10 mění generovaný jazyk. 2

Příklad 4.18 Převeďme gramatiku G s pravidly

E → T | TE′

E′ → +T | +TE′

T → F | FT ′

T ′ → ∗F | ∗FT ′

F → (E) | i do GNF.

Řešení: Podle lemmy 4.1 je E < T < F . Jako lineární uspořádání na množině nonterminálůvezměme uspořádání

E′ < E < T ′ < T < F

Všechna F -pravidla začínají terminálem (důsledek skutečnosti, že F je největší prvek v uspořá-dání < ). Další největší symbol T má pravidla T → F | FT ′ a po aplikaci kroku (3) dostávámepravidla T → (E) | i | (E)T ′ | iT ′.

Výsledná gramatika v GNF má pravidla:

E → (E)′ | i | (E)′T ′ | iT ′ | (E)′E′ | iE′ | (E)′T ′E′ | iT ′E′

E′ → +T | +TE′

T → (E)′ | i | (E)′T ′ | iT ′

T ′ → ∗F | ∗FT ′

F → (E)′ | i)′ → )

2

Nevýhodou algoritmu 4.8 je velké množství nových pravidel. Existuje alternativní algoritmuspřevodu do GNF, [3], který nezvětšuje tak výrazně počet pravidel gramatiky, avšak zavádí zasevíce nonterminálů.

Page 53: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

4.8. Cvičení 49

4.8 Cvičení

Cvičení 4.8.1 Pro výpočet tranzitivního uzávěru binární relace definované na konečné množině(např. slovníku gramatiky) se velmi často používá reprezentace relace prostřednictvím booleov-ské matice a operací nad touto maticí. Je-li A booleovská matice reprezentující binární relaciR na množině M (tj. A[p, q] = true, je-li (p, q) ∈ R a A[p, q] = false, je-li (p, q) /∈ R, p, q ∈ Ma A[p, q] je prvek matice A v řádku označeném p a sloupci označeném q), pak tranzitivní uzávěrrelace R je relace R+, jež je reprezentován maticí A+:

A+ = A+A2 + . . .+An,(3)

kde n = min(|M | − 1, |R|) a operace sečítání, resp. násobení jsou interpretovány jako disjunkce,resp. konjunkce.

Pro výpočet tranzitivního uzávěru existuje efektivnější postup než podle 3, nazývaný, podleautora, Warshallův algoritmus.

Algoritmus 4.9 Warshallův algoritmus pro výpočet tranzitivního uzávěru binární relace.

Vstup: Booleovská matice A reprezentující binární relaci R.

Výstup: Booleovská matice B reprezentující binární relaci R+.

Metoda:

(1) Polož B = A a i = 1.

(2) Pro všechna j, jestliže B[j, i] = true, pak pro k = 1, . . . , n polož B[j, k] = B[j, k] +B[i, k].

(3) Polož i = i+ 1.

(4) Je-li i ≤ n, vrať se ke kroku (2); v opačném případě je B výsledná matice.

Ukažte, že algoritmus 4.9 počítá skutečně tranzitivní uzávěr binární relace.

Cvičení 4.8.2 V gramatice z příkladu 4.3 vytvořte levou a pravou derivaci a derivační stromvěty i ∗ (i+ i− i). Nalezněte všechny fráze, jednoduché fráze a l-frázi této věty.

Cvičení 4.8.3 Nechť G = (N,Σ, P, S) je gramatika a α1, α2 řetězce α1, α2 ∈ (N ∪Σ)∗. Navrh-něte algoritmus, který zjišťuje, zda platí α1⇒∗G α2.

Cvičení 4.8.4 Je dána gramatika G = ({S,A,B}, {a, b}, P, S), která má pravidla

S → bA | aBA → a | aS | bAAB → b | bS | aBB

Ukažte, že tato gramatika je víceznačná (uvažujte např. větu aabbab). Pokuste se nalézt ekviva-lentní jednoznačnou gramatiku.

Page 54: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

50 0 0 1

Cvičení 4.8.5 Gramatiku s pravidly

S → A | BA → aB | bS | bB → AB | BaC → AS | b

transformujte na ekvivalentní gramatiku bez zbytečných symbolů.

Cvičení 4.8.6 Nalezněte gramatiku bez ε-pravidel, jež je ekvivalencí s gramatikou

S → ABC

A → BB | εB → CC | aC → AA | b

Cvičení 4.8.7 Ke gramatice

S → A | BA → C | DB → D | EC → S | a | εD → S | bE → S | c | ε

nalezněte ekvivalentní vlastní gramatiku.

Cvičení 4.8.8 Formulujte algoritmus, který testuje, zda gramatika G je a nebo není gramatikoubez cyklu.

Cvičení 4.8.9 V gramatice

S → AB

A → BS | bB → SA | a

odstraňte levou rekurzi.

Cvičení 4.8.10 Do Chomského normální formy převeďte gramatiku

G = ({S, T, L}, {a, b,+,−, ∗, /, [, ]}, P, S)

kde P obsahuje pravidla

S → T + S | T − S | TT → L ∗ T | L/T | LL → [S] | a | b

Page 55: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0 0 1 51

Cvičení 4.8.11 Gramatiku G = ({S,A,B}, {a, b}, P, S) s pravidly

S → Ba | AbA → Sa | AAb | aB → Sb | BBa | b

převeďte do Greibachové normální formy.

Cvičení 4.8.12 Sestrojte bezkontextovou gramatiku jazyka PL0, jehož grafy syntaxe jsou v pří-loze.

Page 56: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

52 0 0 1

Page 57: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 5

Zásobníkové automaty a jejich vztahk bezkontextovým jazykům

V této kapitole se budeme zabývat abstraktním zařízením – zásobníkovým automatem, kterýpředstavuje přirozený model syntaktického analyzátoru bezkontextových jazyků. Zásobníkovýautomat je jednocestný nedeterministický automat, jenž je opatřen zásobníkem reprezentujícímnekonečnou paměť. Schéma zásobníkového automatu je uvedeno na obr. 5.1. Vstupní páska je

Obrázek 5.1: Schéma zásobníkového automatu

rozdělena na jednotkové záznamy, každý záznam obsahuje právě jeden vstupní symbol. Obsahjednotkového záznamu může být čten čtecí hlavou, nemůže však být přepsán (read only inputtape). V určitém časovém okamžiku může čtecí hlava zůstat na daném záznamu, nebo se posuneo jeden záznam doprava (jednocestný automat). Konečná řídící jednotka realizuje operace po-suvu čtecí hlavy a ukládání informace do zásobníku prostřednictvím funkce přechodů definovanénad vstupní abecedou, množinou stavů řídící jednotky a vrcholem zásobníku.

Obsahem této části je základní definice zásobníkového automatu, varianty zásobníkových au-tomatů a základní výsledek teorie zásobníkových automatů – formální jazyk je bezkontextový,právě když je přijatelný zásobníkovým automatem. Dále bude definována důležitá podtřída

53

Page 58: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

54 KAPITOLA 5. Zásobníkové automaty a jejich vztah k bezkontextovým jazykům

bezkontextových jazyků – deterministické bezkontextové jazyky, jež jsou přijímány tzv. deter-ministickými zásobníkovými automaty.

5.1 Základní definice zásobníkového automatu

Definice 5.1 Zásobníkový automat P je sedmice

P = (Q,Σ,Γ, δ, q0, Z0, F ), kde

(1) Q je konečná množina stavových symbolů reprezentujících vnitřní stavy řídicí jednotky

(2) Σ je konečná vstupní abeceda; jejími prvky jsou vstupní symboly

(3) Γ je konečná abeceda zásobníkových symbolů

(4) δ je zobrazení z množiny Q× (Σ ∈ {ε})×Γ do konečné množiny podmnožin množiny Q×Γ∗

popisující funkci přechodů

(5) q0 ∈ Q je počáteční stav řídicí jednotky

(6) Z0 ∈ Γ je symbol, který je na počátku uložen do zásobníku – tzn. startovací symbol

(7) Z ⊆ Q je množina koncových stavů

Definice 5.2 Konfigurací zásobníkového automatu P nazveme trojici

(q, w, α) ∈ Q× Σ∗ × Γ∗

kde

(1) q je přítomný stav řídící jednotky

(2) w je doposud nepřečtená část vstupního řetězce; první symbol řetězce w je pod čtecí hlavou.Je-li w = ε, pak byly všechny symboly ze vstupní pásky přečteny.

(3) α je obsah zásobníku. Pokus nebude uvedeno jinak, budeme zásobník reprezentovat řetěz-cem, jehož nejlevější symbol koresponduje s vrcholem zásobníku. Je-li α = ε, pak je zásobníkprázdný.

Definice 5.3 Přechod zásobníkového automatu P budeme reprezentovat binární relací `P (nebo` bude-li zřejmé, že jde o automat P ), která je definována na množině konfigurací zásobníkovéhoautomatu P . Relace

(q, aw, Zα)`(q′, w, γα)

platí, jestliže δ(q, a, Z) obsahuje prvek (q′, γ) pro nějaké q ∈ Q, a ∈ (Σ ∪ {ε}), w ∈ Σ∗, Z ∈ Γ aα, γ ∈ Γ∗.

Relaci `P interpretujeme tímto způsobem. Nachází-li se zásobníkový automat P ve stavu q a navrcholu zásobníku je uložen symbol Z, pak po přečtení vstupního symbolu a 6= ε může automatpřejít do stavu q′, přičemž se čtecí hlava posune doprava a na vrchol zásobníku se uloží, poodstranění symbolu Z, řetězec γ. Je-li γ = ε, pak je pouze odstraněn vrchol zásobníku.

Page 59: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.1. Základní definice zásobníkového automatu 55

Je-li a = ε, neposouvá se čtecí hlava, což znamená, že přechod do nového stavu a nový ob-sah zásobníku není určován příštím vstupním symbolem. Tento typ přechodu budeme nazývatε-přechodem. Poznamenejme, že ε-přechod může nastat i tehdy, když byly přečteny všechnyvstupní symboly.

Relace `i,`+,`∗ jsou definovány obvyklým způsobem. Relace `+ resp. `∗ je tranzitivní, resp.tranzitivní a reflexivní uzávěr relace `,`i je i-tá mocnina relace `, i ≥ 0.

Počáteční konfigurace zásobníkového automatu má tvar (q0, w, Z0) pro w ∈ Σ∗, tj. automat jev počátečním stavu q0, na vstupní pásce je řetězec w a v zásobníku je startovací symbol Z0.Koncová konfigurace má tvar (q, ε, α), kde q ∈ F je koncový stav a α ∈ Γ∗.

Definice 5.4 Platí-li pro řetězec w ∈ Σ∗ relace (q0, w, Z0)`∗(q, ε, α) pro nějaké q ∈ F a α ∈ Γ∗,pak říkáme, že řetězec w je přijímán zásobníkovým automatem P . Množinu L(P ) všech řetězcůpřijímaných zásobníkovým automatem P , který nazýváme jazykem přijímaným zásobníkovýmautomatem.

Příklad 5.1 Uvažujme jazyk L = {0n1n | n ≥ 0}. Zásobníkový automat P , který přijímá jazykL, má tvar

P = ({q0, q1, q2}, {0, 1}, {Z, 0}, δ, q0, Z, {q0})

kde

δ(q0, 0, Z) = {(q1, 0Z)}δ(q1, 0, 0) = {(q1, 00)}δ(q1, 1, 0) = {(q2, ε)}δ(q2, 1, 0) = {(q2, ε)}δ(q2, ε, Z) = {(q0, ε)}

a pracuje tak, že kopíruje všechny nuly ze vstupního řetězce do zásobníku. Objeví-li se navstupu symbol 1, pak odstraňuje jednu nulu ze zásobníku. Kromě toho požaduje, aby všechnynuly předcházely všechny jedničky. Například pro vstupní řetězec 0011 realizuje automat P tytopřechody:

(q0, 0011, Z) ` (q1, 011, 0Z)

` (q1, 11, 00Z)

` (q2, 1, 0Z)

` (q2, ε, Z)

` (q0, ε, ε)

Ukažme, že skutečně platí L(P ) = L. Z definice funkce přechodů δ a relace ` plyne (q0, ε, Z)`0

(q0, ε, Z) a tedy ε ∈ L(P ). Dále platí

(q0, 0, Z) ` (q1, ε, OZ)

(q1, 0i, 0Z) `i (q1, ε, 0

i+1Z)

(q1, 1, 0i+1Z) ` (q2, ε, 0

iZ)

(q2, 1i, piZ) `i (q2, ε, Z)

(q2, ε, Z) ` (q2, ε, Z)

Page 60: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

56 0 0 1

což dohromady implikuje

(q0, 0n1n, Z)

2n+1

` (q0, ε, ε) pro n ≥ 1

a tedy L ⊆ L(P ).

Dokázat opačnou inkluzi L(P ) ⊆ L, tj. dokázat, že zásobníkový automat nepřijímá jiné řetězce,než 0n1n, n ≥ 1, je obtížnější. Příjme-li zásobníkový automat P vstupní řetězec, pak musí projítposloupností stavů q0, q1, q2, q0.

Jestliže platí (q0, w, Z)`i(q1, ε, α), pak w = 0i a α = 0iZ. Podobně, jestliže (q2, w, α)`i(q2, ε, β)pak w = 1i a α = 0iβ. To však znamená, že relace (q1, w, α)`(q2, ε, β) platí, právě kdyžw = 1 a α = 0β a relace (q2, w, Z)`∗(q0, ε, ε) platí, právě když w = ε. Tedy, jestliže platí(q0, w, Z)`i(q0, ε, α) pro nějaké i > 0, pak w = 0n1n, i = 2n+ 1 a α = ε, tj. L(P ) ⊆ L.

5.2 Varianty zásobníkových automatů

V tomto odstavci uvedeme dvě varianty základní definice zásobníkového automatu, které námusnadní objasnit vztah mezi zásobníkovými automaty a bezkontextovými jazyky.

Definice 5.5 Rozšířeným zásobníkovým automatem rozumíme sedmici

P = (Q,Σ,Γ, δ, q0, Z0, F )

kde δ je zobrazení z konečné podmnožiny Q × (Σ ∪ {ε}) × Γ∗ do množiny podmnožin množinyQ× Γ∗. Ostatní symboly mají stejný význam jako v základní definici 5.1.

Relace (q, aw, α, γ)`(q′, w, β, γ) platí, jestliže δ(q, a, α) obsahuje (q′, β) pro q ∈ Q, a ∈ Σ ∪ {ε}a α ∈ Γ∗. Tato relace odpovídá přechodu, v němž je vrcholový řetězec zásobníku odstraněna nahrazen řetězcem β. (Připomeňme, že v základní definici je α ∈ Γ nikoliv α ∈ Γ∗). Jazykdefinovaný automatem P , je

L(P ) = {w | (q0, w, Z0)∗`(q, ε, α), w ∈ F, α ∈ Γ∗}

Rozšířený zásobníkový automat může, na rozdíl od základní definice provádět přechody i v pří-padě, že je zásobník prázdný.

Příklad 5.2 Uvažujme rozšířený zásobníkový automat P , který přijímá jazyk

L = {wwR | w ∈ {a, b}∗},P = ({q, p}, {a, b}, {a, b, S, Z}, δ, q, Z, {p})

kde zobrazení δ je definováno takto:

δ(q, a, ε) = {(q, a)}δ(q, b, ε) = {(q, b)}δ(q, ε, ε) = {(q, S)}

δ(q, ε, aSa) = {(q, S)}δ(q, ε, bSb) = {(q, S)}δ(q, ε, SZ) = {(p, ε)}

Page 61: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0 0 1 57

Pro vstupní řetězec aabbaa realizuje automat P tyto přechody:

(q, aabbaa, Z) ` (q, abbaa, aZ)

` (q, bbaa, aaZ)

` (q, baa, baaZ)

` (q, baa, SbaaZ)

` (q, aa, bSbaaZ)

` (q, aa, SaaZ)

` (q, a, aSaaZ)

` (q, a, SaZ)

` (q, ε, aSaZ)

` (q, ε, SZ)

` (q, ε, ε)

Vidíme, že automat P pracuje tak, že nejdříve ukládá do zásobníku prefix vstupního řetězce, pakna vrchol zásobníku uloží znak S značící střed; pak vrcholový řetězec aSa nebo bSb nahrazujesymbolem S. Tento příklad ilustruje také nedeterministickou povahu zásobníkového automatu,protože zobrazením není určeno, zda má být přečten vstupní symbol a uložen na vrchol zásobníku(δ(q, x, ε) = (q, x), x ∈ {a, b}), nebo zda má být proveden ε-přechod, který uloží na vrcholzásobníku středový symbol S, (δ(q, ε, ε) = (q, S)).

Z definice rozšířeného zásobníkového automatu vyplývá, že je-li jazyk L přijímán zásobníkovýmautomatem, pak je také přijímán rozšířeným zásobníkovým automatem. Ukažme nyní, že platíi opačná implikace.

Věta 5.1 Nechť P = (Q,Σ,Γ, δ, q0, Z0, F ) je rozšířený zásobníkový automat. Pak existuje zá-sobníkový automat P1 takový, že L(P1) = L(P ).

Důkaz: Položme m = max{|α| | δ(q, a, α) 6= ∅ pro nějaké q ∈ Q a α ∈ Σ ∪ {ε}}

Zásobníkový automat P1 budeme konstruovat tak, aby simuloval automat P . Protože automatP neurčuje přechody podle vrcholu zásobníku, ale podle vrcholového řetězce zásobníku, budeautomat P1 ukládat m vrcholových symbolů v jakési „vyrovnávací pamětiÿ řídící jednotky tak,aby na počátku každého přechodu věděl, jakých m vrcholových symbolů je v zásobníku auto-matu P . Nahrazuje-li automat P k vrcholových symbolů řetězcem délky l, pak se totéž provedeve vyrovnávací paměti automatu P1. Jestliže l < k, pak P1 realizuje k − l ε-přechodů, kterépřesouvají k− l symbolů z vrcholu zásobníku do vyrovnávací paměti. Automat P1 pak může si-mulovat další přechod automatu P . Je-li l ≥ k, pak se symboly přesouvají z vyrovnávací pamětido zásobníku.

Formálně můžeme konstrukci zásobníkového automatu P1 popsat takto:

P1 = (Q1,Σ1,Γ1, δ1, q1, Z1, F1) kde

(1) Q1 = {[q, α] | q ∈ Q,α ∈ Γ∗1 a 0 ≤ |α| ≤ m}

(2) Γ1 = Γ ∪ {Z1}

(3) Zobrazení δ1 je definováno takto:

a) Předpokládejme, že δ(q, a,X1 . . . Xk) obsahuje (r, Y1 . . . Yl).

Page 62: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

58 0 0 1

(i) Jestliže l ≥ k, pak pro všechna Z ∈ Γ1 a α ∈ Γ∗1 taková, že |α| = m− k

δ1([q,X1 . . . Xkα], a, Z) obsahuje ([r, β], γZ)

kde βγ = Y1 . . . Ylα a |β| = m.

(ii) Je-li l < k, pak pro všechna Z ∈ Γ1 a α ∈ Γ∗1 taková, že |α| = m− k

δ1([q,X1 . . . Xkα], a, Z) obsahuje ([r, Y1 . . . YlαZ], ε)

b) Pro všechna q ∈ Q,Z ∈ Γ1 a α ∈ Γ1 taková, že |α| < m

δ1([q, α], ε, Z) = {([q, α, Z], ε)}

Tato pravidla vedou k naplnění vyrovnávací paměti (obsahuje m symbolů).

(4) q1 = [q0, Z0, Zm−11 ]. Vyrovnávací paměť obsahuje na počátku symbol Z0 na vrcholu a m− 1

symbolů Z1 na dalších místech. Symboly Z1 jsou speciální znaku pro označení dna zásobníku.

(5) F1 = {[q, α] | q ∈ F, α ∈ Γ∗1}Lze ukázat, že

(q, aw,X1 . . . XkXk+1 . . . Xn)P

(r, w, Y1 . . . YlXk+1 . . . Xn)

platí, právě když ([q, α], aw, β)`+P1

([r, α′], w, β′) kde

αβ = X1 . . . XnZm1

α′β′ = Y1 . . . YlXk+1 . . . XnZm1

|α| = |α′| = m

a mezi těmito dvěma konfiguracemi automatu P1 není žádná konfigurace, ve které by druhýčlen stavu (vyrovnávací paměť) měl délku m.

Tedy relace(g0, w, Z0)

P

(q, ε, α) pro q ∈ F, α ∈ Γ∗

platí, právě když

([q0, Z0, Zm−11 ], w, Z1)

P1

([q, β], ε, γ)

kde |β| = m a βγ = αZm1 . Tedy L(P ) = L(P1). 2

Definice 5.6 Nechť P = (Q,Σ,Γ, δ, q0, Z0, F ) je zásobníkový nebo rozšířený zásobníkový auto-mat. Řetězec w je přijímán s vyprázdněním zásobníku, jestliže platí (q0, w, Z0)`+(q, ε, ε), a ∈ F .Označme Lε(P ) množinu všech řetězců, které jsou přijímány zásobníkovým automatem P s vy-prázdněním zásobníku.

Věta 5.2 Nechť L je jazyk přijímaný zásobníkovým automatem P = (Q,Σ,Γ, δ, q0, Z0, F ), L =L(P ). Lze zkonstruovat zásobníkový automat P ′ takový, že Lε(P ′) = L.

Důkaz: Opět budeme konstruovat automat P ′ tak, aby simuloval automat P . Kdykoli automat Pdospěje do koncového stavu, bude automat P , nebo přejde do speciálního tvaru qε, který způsobívyprázdnění zásobníku. Musíme však uvážit situaci, kdy automat P je v konfiguraci s prázdnýmzásobníkem, nikoliv však v koncovém stavu. Abychom zabránili případům, že automat P ′ přijímá

Page 63: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.3. Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty 59

řetězec, který nemá být přijat, přidáme k zásobníkové abecedě automatu P ′ znak, jenž budeoznačovat dno zásobníku a může být vybrán pouze tehdy, je-li automat P ′ ve stavu qε. Formálněvyjádřeno, nechť

P = (Q ∪ {qε, q′},Σ,Γ ∪ {Z ′}, δ′, q′, Z ′, ∅), kde

symbolem ∅ vyznačujeme, že P přijímá řetězec s vyprázdněním zásobníku. Zobrazení δ nynídefinujeme takto:

(1) Jestliže δ(q, a, Z) obsahuje (r, γ), pak δ′(q, a, Z) obsahuje (r, γ) pro všechna q ∈ Q, a ∈ Σ∪{ε}a Z ∈ Γ.

(2) δ(q′, ε, Z ′) = {(q0, Z0Z′)}. První přechod zásobníkového automatu P ′ uloží do zásobníku

řetězec Z0Z′, kde Z ′ je speciální znak označující dno zásobníku, a přejde do počátečního

stavu automatu P .

(3) Pro všechna q ∈ F a Z ∈ Γ ∪ {Z ′} obsahuje δ′(q, ε, Z) prvek (qε, ε).

(4) Pro všechna Z ∈ Γ ∪ {Z ′} je δ(qε, ε, Z) = {(qε, ε)}.

Nyní zřejmě platí

(q′, w, Z ′) `P ′ (q0, w, Z0Z′)

`nP ′ (q, ε, Y1 . . . Yr)

`P ′ (qε, ε, Y2 . . . Yr)

`r−1

P ′ (qε, ε, ε) kde Yr = Z ′,

právě když

(q0, w, Z0)n

P

(q, ε, Y1 . . . Yr−1)

pro q ∈ F a Y1 . . . Yr−1 ∈ Γ∗. Tudíž Lε(P ′) = L(P ).

Předchozí věta platí také obráceně 2

Věta 5.3 Nechť P = (q,Σ,Γ, δ, q0, Z0, ∅) je zásobníkový automat. Lze zkonstruovat zásobníkovýautomat P ′ takový, že L(P ) = Lε(P ).

Důkaz: Zásobníkový automat P ′ konstruujeme tak, že má speciální symbol Z ′ na dně zásobníku.Jakmile je tento symbol ze zásobníku odstraněn, přechází automat P ′ do nového koncového stavuqf : F ′ = {qf}. Formální konstrukci automatu P ′ nebudeme provádět. 2

5.3 Ekvivalence bezkontextových jazyků a jazyků přijímanýchzásobníkovými automaty

Nejdříve ukážeme, jak lze zkonstruovat nedeterministický syntaktický analyzátor jazyka gene-rovaného bezkontextovou gramatikou, který pracuje metodou shora–dolů.

Věta 5.4 Nechť G = (N,Σ, P, S) je bezkontextová gramatika. Z gramatiky G můžeme zkon-struovat zásobníkový automat R takový, že Lε(R) = L(G).

Důkaz: Zásobníkový automat R konstruujeme tak, aby vytvářel levou derivaci vstupního řetězcev gramatice G. Nechť R = ({q},Σ, N ∪ Σ, δ, S, ∅), kde δ je definováno takto:

Page 64: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

60 KAPITOLA 5. Zásobníkové automaty a jejich vztah k bezkontextovým jazykům

(1) Je-li A→ α pravidlo z P , pak δ(q, ε, A) obsahuje (q, α).

(2) δ(q, a, a) = {(q, ε)} pro všechna a ∈ Σ.

Nyní ukážeme, že A⇒mw, právě když a jen když (q, w, ε)`n(q, ε, ε) pro nějaké m,n ≥ 1.

Část „jen kdyžÿ dokážeme indukcí pro m. Předpokládejme, že A⇒mw. Je-li m = 1 a w =a1 . . . ak, k ≥ 0 pak

(q, a1 . . . ak, A) ` (q, a1 . . . ak)

`k (q, ε, ε)

Předpokládejme nyní, že platí A⇒mw pro m > 1. První krok této derivace musí mít tvarA⇒ X1X2 . . . Xk, přičemž Xi⇒mi xi pro mi < m, 1 ≤ i ≤ k a x1x2 . . . xk = w. Tedy

(q, w,A) ` (q, w,X1 . . . Xk)

Je-li Xi ∈ N , pak podle induktivního předpokladu

(q, xi, Xi)∗`(q, ε, ε)

Je-li Xi = xi, xi ∈ Σ, pak(q, xi, Xi) ` (q, ε, ε)

Nyní již vidíme, že levé derivaci

A⇒X1 . . . Xkm1⇒x1X2 . . . Xk

m2⇒ . . .mk⇒ x1x2 . . . xk = w

odpovídá tato posloupnost přechodů:

(q, x1 . . . xk, A)`(q, x1 . . . xk, X1 . . . Xk)∗`(q, x2 . . . xk, X2 . . . Xk) . . .

∗`(q, ε, ε)

Část „kdyžÿ, tj. je-li (q, w,A)`n(q, ε, ε), pak ⇒+ w dokážeme indukcí pro n. Pro n = 1, w = εa A → ε je pravidlo v P . Předpokládejme, že dokazovaná relace platí pro všechna n′ < n. Pakprvní přechod automatu R musí mít tvar

(q, w,A) ` (q, w,X1 . . . Xk)

a (q, xi, Xi)`ni(q, ε, ε) pro 1 ≤ i ≤ k, kde w = x1 . . . xk. Pak A → X1 . . . Xk je pravidlo z P aderivace Xi⇒+ xi plyne z induktivního předpokladu. Je-li Xi ∈ Σ pak Xi⇒0 xi.

Tedy A⇒X1 . . . Xk⇒∗ x1X2 . . . Xk⇒∗ . . .⇒∗ x1 . . . xk−1Xk⇒∗ x1 . . . xk−1xk = w je levá deri-vace řetězce w z A.

Vezmeme-li S = A jako speciální případ, dostaneme S⇒+ w, právě když (q, w, s)`+(q, ε, ε) atedy Lε(R) = L(G). 2

Příklad 5.3 Ke gramatice G s pravidly

E → E + T | TT → T ∗ F | FF → (E) | i

Page 65: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.3. Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty 61

sestrojme zásobníkový automat P takový, že Lε(P ) = L(G)

Řešení:P = ({q}, {+, ∗, (, ), i}, {+, ∗, (, ), i, E, T, F}, δ, q, E, ∅)

kde δ je zobrazení

δ(q, ε, E) = {(q, E + T ), (q, T )}δ(q, ε, T ) = {(q, T ∗ F ), (q, F )}δ(q, ε, F ) = {(q, (E)), (q, i)}δ(q, ε, a) = {(q, ε)} pro všechna a ∈ {+, ∗, (, ), i}

Pro vstupní řetězec i+ i ∗ i může zásobníkový automat P realizovat tuto posloupnost přechodů:

(q, i+ i ∗ i, E) ` (q, i+ i ∗ i, E + T )

` (q, i+ i ∗ i, T + T )

` (q, i+ i ∗ i, F + T )

` (q, i+ i ∗ i, i+ T )

` (q,+i ∗ i,+T )

` (q, i ∗ i, T )

` (q, i ∗ i, T ∗ F )

` (q, i ∗ i, F ∗ F )

` (q, i ∗ i, i ∗ F )

` (q, ∗i, ∗F )

` (q, i, F )

` (q, i, i)

` (q, ε, ε)

2

Nyní ukážeme, jakým způsobem lze k bezkontextové gramatice G definovat rozšířený zásobní-kový automat reprezentující syntaktický analyzátor zdola–nahoru.

Věta 5.5 Nechť G = (N,Σ, P, S) je bezkontextová gramatika. Rozšířený zásobníkový automatR = ({q, r},Σ, N ∪ Σ ∪ {6S}, δ, q, 6S, {r}), kde zobrazení δ je definováno takto:

(1) δ(q, a, ε) = {(1, a)} pro všechna a ∈ Σ.

(2) Je-li A→ α pravidlo z P , pak δ(q, ε, α) obsahuje (q, A).

(3) δ(q, ε, S 6S) = {(r, ε)}.

Přijímá jazyk L(G), tj. L(R) = L(G).

Důkaz: Ukážeme, že automat R pracuje tak, že vytváří pravou derivaci postupnými reduk-cemi l-fráze počínaje terminálním řetězcem (umístěným na vstupní pásce) a konče výchozímsymbolem S. Jinými slovy automat R realizuje syntaktickou analýzu zdola–nahoru.

Page 66: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

62 KAPITOLA 5. Zásobníkové automaty a jejich vztah k bezkontextovým jazykům

Změna konvence: Vrchol zásobníku budeme nyní uvádět vpravo. Induktivní hypotéza, kteroudokážeme indukcí pro n má tvar:

S∗⇒rmαAy

n⇒rmxy implikuje (q, xy, 6S)

∗`(q, y, 6S, αA), ⇒

rmznačí pravou derivaci.

Pro n = 0 tato hypotéza platí, protože αA = x a tudíž automat R provádí přechody podleδ(q, a, ε) = {(q, a)}, a ∈ Σ, přesouvající řetězec x do zásobníku.

Nyní předpokládejme, že induktivní hypotéza platí pro všechny derivace, kratší než n. Můžemepsát

αAγ⇒rmαβy

n−1⇒rmxy

Je-li řetězec αβ tvořen pouze terminálními symboly, pak αβ = x a (q, xy, 6S)`∗(q, y, 6Sαβ)`(q, y,6SαA). Není-li αβ ∈ Σ∗, pak můžeme psát αβ = γBz, kde B je nejpravější nonterminál a podleinduktivní hypotézy

S∗⇒rmγBzy

n−1⇒rmxy

implikuje (q, xy, 6S)`∗(q, zy, 6SγB). Platí tedy (q, zy, 6SγB)`∗(q, y, 6SγBz)`(q, y, 6SαA) a tudížjsme dokázali induktivní hypotézu. Protože (q, ε, 6SS)`(r, ε, ε) dostáváme L(G) ⊆ L(R).

Abychom dokázali, že L(R) ⊆ L(G), ukažme, že platí implikace:

Jestliže (q, xy, 6S)n

`(q, y, 6SαA), pak αAy∗⇒xy

Pro n = 0 tato implikace platí. Předpokládejme, že platí také pro všechny posloupnosti přechodůkratší než n. Protože vrchol zásobníku je nonterminální symbol, prováděl se poslední přechodpodle předpisu (2) v zobrazení δ a můžeme psát:

(q, xy, 6S)n−1

` (q, y, 6Sαβ)`(q, y, 6SαA)

kde A→ β je pravidlo z P . Existuje tedy derivace αAy⇒ αβy⇒∗ xy.

Jako speciální případ uvažujme implikaci:

je-li (q, w, 6S)∗`(q, ε, 6SS) pak S

∗⇒w

Protože však platí (q, w, 6S)`∗(q, ε, 6SS)`(r, ε, ε) je L(R) ⊆ L(G) a společně s první částí důkazudostáváme L(G) = L(R). 2

Poznamenejme, že automat R skutečně představuje model syntaktického analyzátoru, který vy-tváří pravou derivaci vstupního řetězce postupnými redukcemi l-fráze větných forem (počátečnívětná forma je vstupní řetězec, koncová větná forma je výchozí symbol gramatiky). Bezpro-středně po přechodu automatu je pravá větná forma αAx reprezentována obsahem zásobníku(řetězec αA) a nezpracovanou částí vstupního řetězce (řetězec x). Následující činností automatuje přesunutí prefixu řetězce x na vrchol zásobníku a redukce l-fráze dané vrcholovým řetězcemzásobníku. Tento typ syntaktické analýzy se, jak již víme, nazývá syntaktická analýza zdola–nahoru.

Příklad 5.4 Sestrojme syntaktický analyzátor R zdola–nahoru pro gramatiku s pravidly

E → E + T | TT → T ∗ F | FF → (E) | i

Page 67: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.3. Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty 63

Nechť R je rozšířený zásobníkový automat

R = ({q, r}, {+, ∗, (, ), i}, {6S,E, T, F,+, ∗, (, ), i}, δ, q, 6S, {r})

kde δ je zobrazení

(1) δ(q, a, ε) = {(q, a)} pro všechna a ∈ {i,+, ∗, (, )}.

(2)

δ(q, ε, E + T ) = {(q, E)}δ(q, ε, T ) = {(q, E)}

δ(q, ε, T ∗ F ) = {(q, T )}δ(q, ε, F ) = {(q, T )}

δ(q, ε, (E)) = {(q, F )}δ(q, ε, i) = {(q, F )}

(3) δ(q, ε, 6SE) = {(r, ε)}

Pro vstupní řetězec i + i ∗ i může rozšířený zásobníkový automat R provést tuto posloupnostpřechodů:

(q, i+ i ∗ i, 6S) ` (q,+i ∗ i, 6Si)` (q,+i ∗ i, 6SF )

` (q,+i ∗ i, 6ST )

` (q,+i ∗ i, 6SE)

` (q, i ∗ i, 6SE+)

` (q, ∗i, 6SE + i)

` (q, ∗i, 6SE + F )

` (q, ∗i, 6SE + T )

` (q, i, 6SE + T∗)` (q, ε, 6SE + T ∗ i)` (q, ε, 6SE + T ∗ F )

` (q, ε, 6SE + T )

` (q, ε, 6SE)

` (q, ε, ε)

Na závěr tohoto odstavce ukážeme , že bezkontextové jazyky jsou ekvivalentní jazykům přijíma-ným zásobníkovými automaty, tj., že lze také ke každému zásobníkovému automatu R vytvořitbezkontextovou gramatiku G takovou, že L(R) = L(G).

Věta 5.6 Nechť R = (Q,Σ,Γ, δ, q0, Z0, F ) je zásobníkový automat. Pak existuje bezkontextovágramatika G, pro kterou platí L(G) = L(R).

Důkaz: Gramatiku G budeme konstruovat tak, aby levá derivace terminálního řetězce w přímokorespondovala s posloupností přechodů automatu R. Budeme používat nonterminálních sym-bolů tvaru [qZr] kde q, r ∈ Q,Z ∈ Γ. Vrchol zásobníku uvádíme opět vlevo.

Nechť gramatika G = (N,Σ, P, S) je formálně definována takto:

Page 68: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

64 KAPITOLA 5. Zásobníkové automaty a jejich vztah k bezkontextovým jazykům

(1) N = {[qZr] | q, r ∈ Q,Z ∈ Γ} ∪ {S}

(2) Jestliže δ(q, a, Z) obsahuje (r,X1 . . . Xk) k ≥ 1, pak k množině přepisovacích pravidel Ppřidej všechna pravidla tvaru

[qZsk]→ a[rX1s1][s1X2s2] . . . [sk−1Xksk]

pro každou posloupnost s1, s2, . . . , sk stavů z množiny Q.

(3) Jestliže δ(q, a, Z) obsahuje (r, ε), pak k P přidej pravidlo [qZr]→ a.

(4) Pro každý stav q ∈ Q přidej k P pravidlo S → [q0Z0q].

Indukcí lze opět dokázat, že pro všechna q, r ∈ Q a Z ∈ Γ platí [qZr]⇒mw, právě když(q, w, Z)`n(r, ε, ε). Speciální případ této ekvivalence je S ⇒ [q0Z0q]⇒+ w, právě když (q0, w, Z0)`+(q, ε, ε), q ∈ F . To však znamená, že Lε(R) = L(G). 2

Příklad 5.5 Nechť P = ({q0, q1}, {0, 1}, {X,Z0}, δ, q0, Z0, ∅) kde zobrazení δ je dáno takto:

δ(q0, 0, Z0) = {(q0, XZ0)}δ(q0, 0, X) = {(q0, XX)}δ(q0, 1, X) = {(q1, ε)}δ(q1, 1, X) = {(q1, ε)}δ(q1, ε,X) = {(q1, ε)}δ(q0, ε, Z0) = {(q1, ε)}

Zkonstruujme gramatiku G = (N,Σ, P, S) takovou, že L(P ) = L(G). Množiny nonterminálů aterminálů mají tvar:

N = {S, [q0Xq0], [q0Xq1], [q1Xq0], [q1Xq1], [q0Z0q0], [q0Z0q1], [q1Z0q0], [q1Z0q1]}Σ = {0, 1}

Množina N obsahuje některé nonterminály, které jsou v gramatice G nedostupné. Abychom jenemuseli dodatečně odstraňovat, začneme konstruovat pravidla gramatikyG počínaje S-pravidlya přidávejme pouze ty nonterminály, které se objevují na pravých stranách konstruovanýchpravidel.

Podle bodu (4) sestrojíme S-pravidla:

S → [q0Z0q0] S → [q0Z0q1]

Nyní přidáme pravidla pro nonterminál [q0Z0q0]

[q0Z0q0] → 0[q0Xq0][q0Z0q0]

[q0Z0q0] → 0[q0Xq1][q1Z0q0]

vyplývající z δ(q0, 0, Z0) = {(q0, XZ0)}.

Pravidla pro nonterminál [q0Z0q1]

[q0Z0q1] → 0[q0Xq0][q0Z0q1]

[q0Z0q1] → 0[q0Xq1][q1Z0q1]

Page 69: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.4. Deterministický zásobníkový automat 65

jsou požadována zobrazením δ(q0, 0, Z0) = {(q0, XZ0)}.

Pravidla pro zbývající nonterminály jsou:

[q0Xq0] → 0[q0Xq0][q0Xq0]

[q0Xq0] → 0[q0Xq1][q1Xq0]

[q0Xq1] → 0[q0Xq0][q0Xq1]

[q0Xq1] → 0[q0Xq1][q1Xq1]

protože, δ(q0, 0, X) = {(q0, XX)};

[q0Xq1] → 1, protože δ(q0, 1, X) = {(q1, ε)}[q1Z0q1] → ε, protože δ(q1, ε, Z0) = {(q1, ε)}[q1Xq1] → ε, protože δ(q1, ε,X) = {(q1, ε)}[q1Xq1] → 1, protože δ(q1, 1, X) = {(q1, ε)}.

Povšimněme si nyní, že pro nonterminály [q1Xq0] a [q1Z0q0] nejsou definována žádná pravidla,a proto ani z nonterminálu [q0Z0q0] ani z [q0Xq0] nemohou být derivovány terminální řetězce.Odstraníme-li tedy pravidla obsahující některý z uvedených čtyř nonterminálů, dostaneme ekvi-valentní gramatiku generující jazyk L(P ):

S → [q0Z0q1]

[q0Z0q1] → 0[q0Xq1][q1Z0q1]

[q0Xq1] → 0[q0Xq1][q1Xq1]

[q1Z0q1] → ε

[q0Xq1] → 1

[q1Xq1] → ε

[q1Xq1] → 1

Výsledky dokázané v tomto odstavci nyní můžeme shrnout takto:

Tvrzení

• L je jazyk generovaný bezkontextovou gramatikou,

• L je jazyk přijímaný zásobníkovým automatem,

• L je jazyk přijímaný zásobníkovým automatem s vyprázdněním zásobníku a

• L je jazyk přijímaný rozšířeným zásobníkovým automatem

jsou vzájemně ekvivalentní.

5.4 Deterministický zásobníkový automat

V předchozím odstavci jsem ukázali, že ke každé bezkontextové gramatice lze sestrojit zásobní-kový automat, který reprezentuje syntaktický analyzátor pro věty generované danou gramati-kou. Tento analyzátor je obecně nedeterministický. Z hlediska aplikací teorie formálních jazyků

Page 70: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

66 0 0 1

v překladačích jsou důležité tzv. deterministické bezkontextové jazyky, které lze analyzovat de-terministickými syntaktickými analyzátory. V tomto odstavci definujeme třídu zásobníkovýchautomatů, které v každém okamžiku mohou přijít pouze do jediné konfigurace, tzv. determinis-tické zásobníkové automaty, a jim odpovídající deterministické jazyky.

Definice 5.7 Zásobníkový automat P = (Q,Σ,Γ, δ, q0, Z0, F ) nazýváme deterministickým zá-sobníkovým automatem, jestliže pro každé q ∈ Q a Z ∈ Γ platí buď pro každé a ∈ Σ obsahujeδ(q, a, Z) nanejvýš jeden prvek a δ(q, ε, Z) = ∅, nebo δ(q, a, Z) = ∅ pro všechna a ∈ Σ a δ(q, ε, Z)obsahuje nejvýše jeden prvek.

Protože zobrazení δ(q, a, Z) obsahuje nejvýše jeden prvek, budeme místo δ(q, a, Z) = {(r, γ)}psát δ(q, a, Z) = (r, γ).

Příklad 5.6 Deterministický zásobníkový automat, který přijímá jazyk L = {wcwR | w ∈{a, b}+}, má tvar:

P = ({q0, q1, q2}, {a, b, c}, {Z, a, b}, δ, q0, Z, {q2})

kde zobrazení δ je definováno takto:

δ(q0, X, Y ) = (q0, XY ) pro všechna X ∈ {a, b} a Y ∈ {Z, a, b}δ(q0, c, Y ) = (q1, Y ) pro všechna Y ∈ {a, b}δ(q1, X,X) = (q1, ε) pro všechna X ∈ {a, b}δ(q1, ε, Z) = (q2, ε)

Automat P pracuje tak, že dokud nepřečte středový symbol c, ukládá symboly vstupního řetězcedo zásobníku. Potom přejde do stavu q1 a srovnává další vstupní symboly se symboly zásobníku.

Definici deterministického zásobníkového automatu můžeme rozšířit tak, aby zahrnovala rozší-řené zásobníkové automaty.

Definice 5.8 Rozšířený zásobníkový automat R = (q,Σ,Γ, δ, q0, Z0, F ) je (rozšířeným) deter-ministickým automatem, jestliže platí:

(1) Pro každé q ∈ Q, a ∈ Σ ∪ {ε} a γ ∈ Γ∗ obsahuje δ(q, a, γ) nejvýše jeden prvek.

(2) Je-li δ(q, a, α) 6= ∅, δ(q, a, β) 6= ∅ a α 6= β, pak řetězec α není sufixem řetězce β a ani β nenísufixem α.

(3) Je-li δ(q, a, α) 6= ∅ a δ(q, ε, β) 6= ∅, pak řetězec α není sufixem řetězce β a ani β není sufixemα.

Poznámka 5.1 Definice 5.8 předpokládá, že vrchol zásobníku je vpravo; pokud je vlevo, pakje třeba nahradit slovo „sufixÿ slovem „prefixÿ.

Mezi zásobníkovým automatem a deterministickým zásobníkovým automatem bohužel neplatívztah jako mezi nedeterministickým a deterministickým konečným automatem, tzn., že ne každýjazyk přijímaný zásobníkovým automatem může být přijímán deterministickým zásobníkovýmautomatem.

Definice 5.9 Jazyk L se nazývá deterministický bezkontextový jazyk, jestliže existuje determi-nistický zásobníkový automat P takový, že L(P ) = L.

Page 71: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

5.5. Cvičení 67

Třída deterministických bezkontextových jazyků představuje vlastní podtřídu jazyků bezkontex-tových. V následující kapitole se budeme zabývat některými důležitými typy deterministickýchbezkontextových jazyků a gramatik.

5.5 Cvičení

Cvičení 5.5.1 Sestrojte zásobníkový automat, který přijímá jazyk

L = {anbm | n ≤ m ≤ 2n}

Cvičení 5.5.2 Pro gramatiky

(a)S → aSb | ε

(b)

S → AS | bA → SA | a

(c)

S → SS | AA → 0A1 | S | 01

sestrojte zásobníkové automaty modelující syntaktickou analýzu shora–dolů a zdola–nahoru.

Cvičení 5.5.3 Nalezněte gramatiku, která generuje jazyk L(P ), kde

P = ({q0, q1, q2}, {a, b}, {Z0, A}, δ, q0, Z0, {q2});

zobrazení δ má tvar:

δ(q0, a, Z0) = (q1, AZ0)

δ(q0, a, A) = (q1, AA)

δ(q1, a, A) = (q0, AA)

δ(q1, ε, A) = (q2, A)

δ(q2, b, A) = (q2, ε)

Page 72: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

68 KAPITOLA 5. Zásobníkové automaty a jejich vztah k bezkontextovým jazykům

Page 73: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 6

Deterministické bezkontextovéjazyky a jejich syntaktická analýza,precedenční jazyky

Velmi důležitou podmnožinou bezkontextových jazyků jsou z hlediska aplikací v programova-cích jazycích deterministické bezkontextové jazyky. Jejich název je odvozen od zařízení, kterýmlze tyto jazyky reprezentovat – deterministického zásobníkového automatu. Pro tyto jazyky lzesestrojit syntaktický analyzátor, který pracuje bez návratu – deterministický syntaktický analy-zátor.

V této kapitole se seznámíme s některými deterministickými gramatikami, které generují deter-ministické jazyky:

1. precedenčními gramatikami

2. LL gramatikami

3. LR gramatikami

Existují bezkontextové jazyky, které nelze popsat žádnou deterministickou gramatikou. Menšíobecnost algoritmů deterministického rozkladu však na druhé straně vyvažují přednosti, kterédeterministické jazyky přinášejí pro implementaci zvláště proto, že deterministickými gramati-kami lze popsat většinu syntaktických rysů programovacích jazyků, které se normálně popisujíbezkontextovou gramatikou.

Mezi nejvýznačnější vlastnosti deterministických jazyků z hlediska jejich implementace můžemezařadit:

1. Efektivnost rozkladu

Pro deterministický bezkontextový jazyk lze sestrojit deterministický syntaktický analyzá-tor, jenž pracuje v čase lineárně s lineárním paměťovým prostorem. Znamená to, že je-li ndélka analyzovaného vstupního řetězce, pak existují konstanty c1 a c2 tak, že syntaktickýanalyzátor nespotřebuje více než c1n operací (konečné délky) a více než c2n paměti.

69

Page 74: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

70 KAPITOLA 6. Deterministické bezkontextové jazyky

2. Automatizovatelnost výstavby syntaktického analyzátoru

Jak dále uvidíme, syntaktická analýza je realizována jednoduchým algoritmem, který ope-ruje nad určitou tabulkou (tabulkami), jež nese informace získané z deterministické grama-tiky popisující analyzovaný jazyk. Existují algoritmy (konstruktory syntaktických analy-zátorů), jejichž vstupem je deterministická gramatika a výstupem jsou tabulky pro vlastnísyntaktický analyzátor.

3. Snadnost lokalizace syntaktických chyb a připojení sémantického zpracování

Tyto vlastnosti jsou důsledkem skutečnosti, že deterministické syntaktické analyzátorypracují bez návratů.

6.1 Jednoduché precedenční gramatiky

Nejjednodušší třída deterministických syntaktických analyzátorů je založena na tzv. precedenč-ních relacích. V precedenčních gramatikách jsou hranice l-fráze stanovovány podle určitých (pre-cedenčních) relací, které platí mezi symboly pravé větné formy. Syntaktické analyzátory posta-vené na precedenčních gramatikách patří k historicky nejstarším analyzátorům programovacíchjazyků. Existuje řada různých tříd precedenčních gramatik; k nejznámějším patří:

• jednoduché precedenční gramatiky

• rozšířené precedenční gramatiky

• slabé precedenční gramatiky

• operátorové precedenční gramatiky

Z precedenčních relací patří k nejdůležitějším relace m, která je definována mezi terminálnímia nonterminálními symboly tak, že prohlížíme-li vstupní symboly pravé větné formy αβw zlevadoprava a je-li řetězec β l-frází této větné formy, pak precedenční relace m platí mezi poslednímsymbolem l-fráze β a prvním symbolem terminálního podřetězce w. Relace m tedy slouží k ur-čení konce l-fráze. Určení začátku (levého konce) l-fráze a pravidla, podle kterého je provedenaredukce, se může provést několika způsoby v závislosti na typu precedence.

K ohraničení l-fráze β jednoduché precedenční gramatiky se používají tří precedenčních relacíl,

.=,m. Mezi všemi dvojicemi symbolů řetězce α platí relace l nebo

.=; relace l platí mezi

posledním symbolem řetězce α a prvním symbolem řetězce β. Mezi všemi dvojicemi symbolůl-fráze β platí relace

.= a mezi posledním symbolem řetězce β a prvním symbolem řetězce w

platí relace m.

V jednoduché precedenční gramatice lze tedy l-frázi lokalizovat takto: Symboly dané větnéformy prohlížíme tak dlouho, dokud nenajdeme první dvojici symbolů, pro které platí relacem. Nalezli jsme tak konec l-fáze. Abychom našli její začátek, vracíme se (prohlížíme symbolyvětné formy zprava doleva) a hledáme první výskyt relace l. Řetězec mezi relacemi l a mje hledanou l-frází. Předpokládáme-li, že pracujeme s gramatikou,v níž pravé straně pravidla(l-frázi) odpovídá jednoznačně levá strana pravidla, pak můžeme jednoznačně provést redukci.Tento proces se opakuje tak dlouho, dokud není celý vstupní řetězec zredukován až k výchozímusymbolu, nebo když už nemůže být provedena další redukce (v tom případě je signalizovánachyba).

Page 75: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 71

Definice 6.1 Nechť je G = (N,Σ, P, S) bezkontextová gramatika. Wirth-Weberovy precedenčnírelace l,

.=,m jsou definovány na množině N ∪ Σ takto:

(1) Existuje-li v P pravidlo A → αXBβ takové, že B⇒+ Y γ,A,B ∈ N,X, Y ∈ (N ∪ Σ), pakX l Y .

(2) Existuje-li v P pravidlo A→ αXY β, pak X.= Y .

(3) Poněvadž symbol, jenž následuje za posledním symbolem l-fráze, musí být terminál, je relacem definována na (N ∪ Σ)× Σ

Existuje-li v P pravidlo A→ αBY β takové, že B⇒+ γX a Y ⇒∗ aδ, pak X m a.

Při konstrukci syntaktického analyzátoru je účelné přidat na začátek a na konec vstupníhořetězce speciální koncový znak; použijeme znaku ]. Předpokládáme, že platí ]lX pro všechnaX, pro která S⇒+ Xα a Y m ] pro všechna Y , pro která S⇒+ αY .

Poznámka 6.1 Precedenční relace čteme stejně jako relace <,=, >. Nemají však jejich vlast-nosti. Relace

.= není obvyklou ekvivalencí, relace m a l nejsou normálně tranzitivní a mohou

být symetrické a reflexivní.

Definice 6.2 Gramatika G se nazývá UI-gramatikou (Uniquely Invertible), jestliže její žádnádvě pravidla nemají stejnou pravou stranu.

Není obtížné ukázat, že každá gramatika má alespoň jednu UI-gramatiku.

Definice 6.3 Nechť G = (N,Σ, P, S) je vlastní gramatika, ε 6∈ L(G). Existuje-li pro každoudvojici symbolů z N ∪ Σ nanejvýš jedna Wirth-Weberova precedenční relace, pak se grama-tika G nazývá precedenční gramatikou. Je-li precedenční gramatika UI-gramatikou, nazveme jijednoduchou precedenční gramatikou.

Příklad 6.1 Uvažujme gramatiku G s pravidly:

S → aSSb | c

precedenční relace pro symboly gramatiky G jsou spolu s koncovým znakem ] obsaženy v tab.6.1. Tato tabulka se nazývá precedenční maticí.

S a b c ]S

.= l

.= l

a.= l l

b m m m m

c m m m m

] l l

Tabulka 6.1: Precedenční matice

Prázdná políčka v tab. 6.1 značí, že pro odpovídající symboly není definována precedenční relace.Vyskytnou-li se v průběhu analýzy takové symboly vedle sebe, pak jde zřejmě o syntaktickouchybu. Poněvadž jsou precedenční relace definovány jednoznačně a žádná dvě pravidla nemajístejnou pravou stranu, je G jednoduchá precedenční gramatika.

Page 76: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

72 0 0 1

6.2 Výpočet precedenčních relací

Uvažujme gramatiku z příkladu 6.1 s pravidly

S → aSSb | c.

Vyjdeme-li přímo z definice 6.1 precedenčních relací, pak nejsnáze určíme relaci.=, protože je

definována pro každou dvojici sousedních symbolů pravé strany každého pravidla. Z prvníhopravidla plyne a

.= S, S

.= S a S

.= b. Poněvadž druhé pravidlo má pravou stranu délky 1,

v dané gramatice již jiné relace.= neplatí.

Abychom nalezli relace l, uvažujme dvojice sousedních symbolů tvaru XC. Symbol X je v relacil s nejlevějším symbolem každého řetězce, jenž je netriviálně derivovatelný z C. V příkladě uva-žujme dvojice aS a SS. Poněvadž z S mohou být derivovány pouze řetězce začínající symbolema nebo c, je al a, al c, S l a, S l c.

Relaci m vypočítáme tak, že uvažujeme dvojice sousedních symbolů tvaru CX. Nejdříve najdemevšechny poslední symboly Y řetězců derivovatelných z C. Pak nalezneme všechny terminálnísymboly d, kterými začínají řetězce derivovatelné z X. (Je-li X terminál, pak d = X je jedinámožnost.) Pro každé Y a d platí Y m d. V příkladě jsou uvažované dvojice SS a Sb, Y je b neboc, d je a nebo c a tedy bm a, bm c, cm a, cm c, bm b, cm b.

Pro praktické účely je zřejmě uvedený způsob hledání precedenčních relací nevhodný. Ukážemeproto metodu výpočtu těchto relací, která využívá reprezentace binárních relací booleovskýmimaticemi.

Nejdříve přeformulujeme definici precedenčních relací l a m.

Věta 6.1 Nechť G = (N,Σ, P, S) je vlastní gramatika, ε 6∈ L(G) a nechť F a L jsou relace:

F = {(A,X) | A→ Xα je v P,X ∈ (N ∪ Σ), α ∈ (N ∪ Σ)∗},L = {(A,X) | A→ αX je v P,X ∈ (N ∪ Σ), α ∈ (N ∪ Σ)∗}

pak

(1) X l Y , právě když existuje pravidlo A→ αXBβ takové, že platí BF+Y .

(2) X m a, právě když a ∈ Σ a existuje pravidlo A→ αBY β takové, že platí BL+X a Y F ∗a.

Důkaz: Tvrzení plyne bezprostředně z definice 6.1

Na základě věty 6.1 můžeme již stanovit algoritmus výpočtu precedenčních relací prostřednic-tvím booleovských matic: Označme symbolem [R] booleovskou matici jež reprezentuje binárnírelaci R (viz 4.8.1).

Algoritmus 6.1 Výpočet precedenčních relací prostřednictvím booleovských matic.

Vstup: Vlastní gramatika G = (N,Σ, P, S), ε 6∈ L(G).

Výstup: Matice [.=], [l] a [m] reprezentující precedenční relace.

Metoda:

Page 77: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 73

(1) Na základě pravidel gramatiky G definuj matice [.=], [F ] a [L].

(2) Vypočítej matici [l] jako součin matic [.=] a [F+], kde matice [F+] reprezentuje

tranzitivní uzávěr relace F a lze jej efektivně vypočítat aplikací Warshallova algoritmu(algoritmus 4.9).

[l] = [.=] · [F+]

(3) Vypočítej matici [m] podle vztahu

[m] = [L+]′ · [ .=] · [F ∗]

kde

[A]′ značí transpozici matice A (popisuje inverzní relaci)[F ∗]′ značí tranzitivní a reflexivní uzávěr relace F, [F ∗] = [F+] + [I], [I] je jednot-ková matice.

Z matice [m] získáme již snadno matici [m] tak, že relaci m zúžíme pouze na ty prvky(X,Y ) ∈ m, pro něž platí Y ∈ Σ.

Ověření algoritmu 6.1 ponecháme jako cvičení.

2

Příklad 6.2 Ilustrujme nyní výpočet precedenčních relací algoritmem 6.1 na příkladě jednodu-ché precedenční gramatiky z příkladu 6.1:

(1)

[.=] =

S a b c

S 1 0 1 0a 1 0 0 0b 0 0 0 0c 0 0 0 0

[F ] =

0 1 0 10 0 0 00 0 0 00 0 0 0

[L] =

0 0 1 10 0 0 00 0 0 00 0 0 0

(2) [F+] = [F ],

[l] =

1 0 1 01 0 0 00 0 0 00 0 0 0

0 1 0 10 0 0 00 0 0 00 0 0 0

=

0 1 0 10 1 0 10 0 0 00 0 0 0

(3) [L+] = [L],

[L+]′ =

0 0 0 00 0 0 01 0 0 01 0 0 0

,

[F ∗] = [F+] + [I] =

1 1 0 00 1 0 00 0 1 00 0 0 1

,

[m] = [L+]′ · [ .=] · [F ∗] =

0 0 0 00 0 0 01 1 1 11 1 1 1

,

Page 78: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

74 0 0 1

[m] =

0 0 0 00 0 0 00 1 1 10 1 1 1

Pro konstrukci úplné precedenční matice využijeme pak matic [

.=], [l] a [m] a hodnot SF ∗X

resp. SL+X pro doplnění řádku resp. sloupce označeného symbolem ]:

S a b c ]S

.= l

.= l

a.= l l

b m m m m

c m m m m

] l l

6.3 Algoritmus syntaktické analýzy jednoduchých precedenč-ních jazyků

Lemma 6.1 Nechť G = (N,Σ, P, S) je vlastní gramatika, ε 6∈ L(G).

(1) Jestliže X lA nebo X.= A a A→ Y α je pravidlo z P , pak X l Y .

(2) Jestliže Al a,A.= a nebo Am a a A→ αY je pravidlo z P , pak Y m a.

Důkaz: Tvrzení (1) ponecháme jako cvičení a dokážeme tvrzení (2):

(a) Je-li Ala, pak existuje pravá strana pravidla tvaru β1ABβ2 taková, že B⇒+ aγ pro nějakéγ ∈ (N ∪ Σ)∗. Z předpokladu pravidla A→ αY plyne okamžitě Y m a.

(b) Je-li A.= a, pak existuje pravá strana β1Aaβ2. Protože platí a⇒∗ a a A⇒+ αY , opět

dostáváme Y m a.

(c) Jestliže Ama, pak existuje pravá strana β1BXβ2, kde B⇒+ γA a X⇒∗ aδ pro nějaké řetězceγ a δ. Pak však platí B⇒+ γαY a také v tomto případě dostáváme Y m a.

2

Následující věta spolu s uvedenou lemmou nám umožní formulovat algoritmus rozkladu jazykagenerovaného jednoduchou precedenční gramatikou.

Věta 6.2 Nechť G = (N,Σ, P, S) je vlastní gramatika, ε 6∈ L(G). Jestliže

]S]n⇒rmXpXp−1 . . . Xk+1Aa1 . . . aq⇒

rmXpXp−1 . . . Xk+1Xk . . . X1a1 . . . aq

pak je:

(1) pro p < i < k Xi+1 lXi nebo Xi+1.= Xi

Page 79: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 75

(2) Xk+1 lXk

(3) pro 1 ≤ i < k, Xi+1.= Xi

(4) X1 m a1

Důkaz: Důkaz provedeme indukcí. Pro n = 0 máme ]S]⇒rm ]Xk . . . X1]. Z definice precedenč-ních relací plyne ] l Xk, Xi+1

.= Xi pro k > i ≥ 1 a X1 m ]. Řetězec Xk . . . X1 nemůže být

prázdný, poněvadž ε 6∈ L(G).

Nyní předpokládejme, že tvrzení platí pro n a uvažujme derivaci

]S] ⇒nrm Xp . . . Xk+1Aa1 . . . aq

⇒rm Xp . . . Xk+1Xk . . . X1a1 . . . aq

⇒rm Xp . . . Xj+1Yr . . . Y1Xj−1 . . . X1a1 . . . aq′

tj. nonterminál Xj je nahrazen Yr . . . Y1 v poslední přímé derivaci, takže Xj−1 . . . X1 jsou termi-nální symboly.

Podle induktivní hypotézy je Xj+1 l Xj nebo Xj+1.= Xj . Tedy, na základě lemmy 6.1 (1)

je Xj+1 l Yr. Podobně mezi Xj a symbolem vpravo (kterým může být také a1) platí jednaz precedenčních relací a tedy podle 6.1 (2) platí Y1 mXj−1 nebo, je-li j = 1, Y1 m a1. PoněvadžYr . . . Y1 je pravá strana pravidla, dostáváme Yr

.= Yr−1, . . . , Y2

.= Y1. Konečně, platnost relace

Xj+1 lXi nebo Xi+1.= Xi plyne pro p < i < j z induktivního předpokladu. 2

Jestliže G je precedenční gramatika, pak tvrzení věty 6.2 můžeme na základě definice zesílittakto:

V bodě (1): „právě jedna z relací l nebo.=ÿ.

V bodech (1)–(4): „a žádné jiné relace neplatíÿ.

Podle uvedených tvrzení lze zkonstruovat algoritmus deterministické syntaktické analýzypro jednoduchou precedenční gramatiku. V každém kroku analýzy je v každé pravé větnéformě XpXp−1 . . . Xk+1Xk . . . X1a1 . . . aq precedenčními relacemi jednoznačně definována l-frázeXk . . . X1 a jednoznačně definována redukce podle pravidla A → Xk . . . X1. Snadno dokazatel-ným důsledkem této skutečnosti je, že jednoduchá precedenční gramatika je jednoznačná.

Ještě dříve, než uvedeme vlastní algoritmus syntaktické analýzy, definujme pojem pravý rozklad,který nám umožní popsat výsledek syntaktické analýzy zdola–nahoru.

Definice 6.4 Nechť G = (N,Σ, P, S) je gramatika, jejíž pravidla jsou očíslována indexy1, 2, . . . , p (tj. p je mohutnost množiny P ) a nechť α je větná forma.

Pravým rozkladem řetězce α budeme rozumět v opačném pořadí zapsanou posloupnost indexůpravidel, jež byly použity v pravé derivaci větné formy α.

Algoritmus 6.2 Rozklad vět jednoduchého precedenčního jazyka.

Vstup: Jednoduchá precedenční gramatika G = (N,Σ, P, S) precedenční matice a vstupní ře-tězec w = a1 . . . an].

Pravidla z P jsou očíslována 1, 2, . . . , p.

Page 80: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

76 0 0 1

Výstup: Pravý rozklad řetězce w, je-li w větou jazyka L(G), jinak error.

Metoda: Činnost algoritmu popíšeme opět přechody mezi konfiguracemi. Konfigurace tohotoalgoritmu je dána trojicí (αX, x, π), kde

(a) αX je obsah zásobníku Z,X je vrchol zásobníku

(b) x je doposud nepoužitá část vstupního řetězce

(c) π je řetězec, jenž po skončení algoritmu reprezentuje pravý rozklad řetězce w. Konfi-gurace (], w, ε) je počáteční konfigurací algoritmu (v zásobníku Z je uložen koncovýsymbol ])

(1) Hledání l-fráze. (α, ax, π) ` (αa, x, π), je-li X l a nebo X.= a (X je nejpravější

symbol řetězce α); vrať se k (1). Je-li Xma, přejdi k (2). Není-li pro (X, a) definovánaprecedenční relace pak error.

(2) Redukce.(αXk+1Xk . . . X1, x, π) ` (αXk+1A, x, πi),

jestliže platí:

a) Xj+1.= Xj pro 1 ≤ j < k

b) Xk+1 lXk

c) a je-li A→ Xk . . . X1 i-tým pravidlem z P .

Je-li x = ], pak algoritmus končí; πi je pravý rozklad řetězce w. Jinak přejdi k (1).Nemůže-li být redukce provedena, pak error.

Snadno lze dokázat, že je počet operací algoritmu 6.2 lineárně závislý na délce vstupního řetězce.Činnost tohoto algoritmu ukážeme na příkladě.

Příklad 6.3 Uvažujme precedenční gramatiky z příkladu 6.1

(1) S → aSSb

(2) S → c

Její precedenční matice je v tab. 6.1. Pro vstupní řetězec accb algoritmus 6.2 prochází toutoposloupností konfigurací:

(], accb], ε) ` (]a, ccb], ε)

` (]ac, cb], ε)

` (]aS, cb], 2)

` (]aSc, b], 2)

` (]aSS, b], 22)

` (]aSSb, ], 22)

` (]S, ], 221)

Pravým rozkladem je řetězec π = 221. Dále popíšeme chování algoritmu 6.2, není-li w v L(G).

Page 81: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

6.4. Linearizace precedenční matice 77

Uvažujme vstupní řetězec acb a odpovídající posloupnost konfigurací:

(], acb], ε) ` (]a, cb], ε)

` (]ac, b], ε)

` (]aS, b], 2)

` (]aSb, ], 2)

error

V poslední konfiguraci je jako l-fráze identifikován řetězec aSb, protože platí ]l a.= S

.= bm ].

Tuto frázi však nelze redukovat, poněvadž v G neexistuje pravidlo s pravou stranou aSb.

6.4 Linearizace precedenční matice

Uvážeme-li, že běžný programovací jazyk má kolem 150-ti symbolů, pak je k reprezentaci pre-cedenční matice třeba obsadit minimálně 150 × 150 × 2 bitů. (Reprezentace l,

.= a m jsou

zobrazitelné nejméně na 2 bitech). Proto bylo nutno hledat cesty, jak snížit nároky na paměťpro ukládání informace o precedenčních relacích. Jednou z cest jsou precedenční funkce, kterévzniknou tzv. linearizací precedenční matice.

Definice 6.5 Nechť je G = (N,Σ, P, S) jednoduchá precedenční gramatika. M je její prece-denční matice. Jsou-li f a g celočíselné nezáporné funkce definované na množině N ∪ Σ ∪ {]}tak, že

(1) je-li M(X,Y ) = l, pak f(X) < g(Y )

(2) je-li M(X,Y ) =.=, pak f(X) = g(Y )

(3) je-li M(X,Y ) = m, pak f(X) > g(Y ), X, Y ∈ N ∪ Σ ∪ {]}

Příklad 6.4 Uvažujme jednoduchou precedenční gramatiku G s pravidly

S → aSc | bSc | c

Její precedenční matice je uvedena v tab. 6.2.

S a b c ]S

.=

a.= l l l

b.= l l l

c m m

] l l l

Tabulka 6.2: Precedenční matice

Hodnoty precedenčních funkcí f a g jsou uvedeny v tab. 6.3.

Page 82: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

78 0 0 1

f g

S 1 0

a 0 1

b 0 1

c 2 1

] 0 0

Tabulka 6.3: Hodnoty precedenčních funkcí

Nároky na paměť se tedy použitím precedenčních funkcí nezanedbatelně sníží. Má-li grama-tika n symbolů, pak precedenční matice vyžaduje (n + 1) × (n + 1) elementárních paměťovýchmíst (uvažujme rovněž koncový symbol ]), kdežto precedenční funkce potřebuje pouze 2(n+ 1)paměťových míst. Precedenční funkce jsou uloženy jako vektory. Náhrada precedenční maticeprecedenčními funkcemi se nazývá linearizací precedenční matice.

Použití precedenčních funkcí místo precedenční matice však přináší jednu nevýhodu. „Prázdnáÿpolíčka v matici jsou během analýzy interpretována jako syntaktické chyby. Uvažujme např. pre-cedenční matici z předešlého příkladu (tab. 6.2). Vyskytnou-li se např. vedle sebe symboly cb,je zřejmé, že vstupní řetězec není syntakticky správně utvořen. Poněvadž jsou však precedenčnífunkce definovány pro všechny symboly gramatiky G, bude mezi symboly cb vypočtena prece-denční relace m. I když je jasné, že v některém z příštích kroků nebude možné provést redukci,nevýhodou je, že se indikace chyby oddálí. Tento problém je částečně řešitelný pr slabé prece-denční gramatiky, kde algoritmus nemusí rozlišovat relace l a

.=. Pak lze navrhnout precedenční

matici tak, že je pro příslušné precedenční funkce případ f(X) = g(Y ) interpretován oprávněnějako syntaktická chyba. Sníží se tím počet případů, kdy analyzátor neohlásí co nejdříve chybu.

Ne však ke každé precedenční matici existují precedenční funkce. V algoritmu 6.3 je uvedenpostup pro nalezení precedenčních funkcí, pokud existují, pro danou precedenční matici. Používáprecedenční matice M jejíž prvky 0,−1, 1 reprezentují precedenční relace takto: Platí-li mezisymbolem označujícím i-tý řádek a symbolem, který označuje j-tý sloupec relace

(1) l pak Mi,j = −1

(2).= pak Mi,j = 0

(3) m pak Mi,j = 1

(4) relace není definována, pak Mi,j = blank

Algoritmus 6.3

Vstup: Precedenční matice M řádu n, jejíž hodnoty jsou −1, 0, 1 a blank.

Výstup: Precedenční funkce reprezentovaná celočíselnými vektory f = (f1, . . . , fn) a g =(g1, . . . , gn), pro které platí

fi < gj je-li Mi,j = −1

fi = gj je-li Mi,j = 0

Page 83: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 79

fi > gj je-li Mi,j = 1

nebo „NEÿ, pokud takové funkce neexistují.

Metoda:

(1) Vytvoř orientovaný graf s 2×n uzly, jenž se nazývá linearizačním grafem pro M . Napočátku označ uzly grafu symboly F1, F2, . . . , Fn a G1, G2, . . . , Gn. V průběhu algo-ritmu budou tyto uzly „reprezentoványÿ novými uzly podle kroků (2) a (3). V každémokamžiku bude existovat uzel Fi reprezentující uzel Fi a uzel Gj reprezentující uzelGj . Na počátku polož Fi = Fi a Gj = Gj pro všechna i a j. Pro každé i i j provádějkroky (2) a (3).

(2) Je-li Mi,j = 0, vytvoř nový uzel N spojením uzlů Fi a Gj . Uzel N bude nyní repre-zentovat všechny uzly, které byly dříve reprezentovány uzly Fi a Gj .

(3) Je-li Mi,j = 1, sestroj hranu, která vede z uzlu Fi do uzlu Gj . Je-li Mi,j = −1, sestrojhranu, která vede z uzlu Gj do uzlu Fi.

(4) Je-li výsledný graf cyklický, je výstup algoritmu „NEÿ. Precedenční funkce k maticiM neexistují.

(5) Je-li linearizační graf acyklický, pak je fi rovno délce nejdelší cesty z uzlu Fi a gjrovno délce nejdelší cesty z uzlu Gj .

Poznámka 6.2 V kroku (4) algoritmu 6.3 je nutno zjistit, zda je orientovaný graf cyklický.

Příklad postupu:

(i) Najdi uzel grafu, jenž nemá žádné vycházející hrany. Neexistuje-li takový uzel, je grafcyklický. V opačném případě tento uzel odstraň a přejdi k bodu (ii).

(ii) Je-li výsledný graf prázdný, pak je původní graf acyklický. Jinak opakuj bod (i).

V kroku (5) algoritmu 6.3 máme nalézt délku nejdelší cesty z daného uzlu orientovaného acyk-lického grafu. Lze použít této techniky: ke každému uzlu Ni grafu budeme postupně přiřazovatcelá čísla ki, která budou po skončení tohoto algoritmu reprezentovat délku nejdelší cesty z Ni.

(i) Na začátku polož pro všechny uzly Ni hodnotu ki = 0.

(ii) Krok (iii) opakuj tak dlouho, dokud se mění hodnota některého ki. Nezmění-li aplikacekroku (iii) žádnou z hodnot ki, pak příslušná ki udávají nejdelší cestu z uzlu Ni.

(iii) Vezmi uzel N grafu. Vycházejí-li u uzlu N hrany vedoucí do uzlů N1, N2, . . . , Nm apříslušejí-li těmto uzlům hodnoty k1, k2, . . . , km, pak polož k = max(k1, k2, . . . , km) + 1; kje hodnota, která přísluší k uzlu N . Tento krok proveď pro všechny uzly.

Je-li d délka nejdelší cesty v orientovaném acyklickém grafu, pak je pro jeden uzel třeba provéstkrok (iii) maximálně d-krát.

Příklad 6.5 Uvažujme precedenční matici M

Page 84: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

80 KAPITOLA 6. Deterministické bezkontextové jazyky

1 2 3 4 51 −1 −1 0 −12 1 −1 03 −1 1 04 −1 15 1 1

Obrázek 6.1: Linearizační graf

Po provedení algoritmu 6.3 získáme linearizační graf znázorněn na obr. 6.1. Podle kroku (2)algoritmu 6.3 jsou spojeny uzly (F3, G4), (F2, G5) a (F1, G3). Linearizační graf je acyklický,výsledné precedenční funkce jsou:

f = (0, 1, 2, 1, 3)

g = (3, 2, 0, 2, 1)

Např. f5 = 3, poněvadž nejdelší cesta z uzlu F5 má délku 3.

6.5 Stratifikace gramatiky

Pro danou gramatiku programovacího jazyka velmi často nejsou precedenční relace definoványjednoznačně. Znamená to, že pro dva symboly z N ∪Σ platí více, než jedna precedenční relace.Zdrojem takových kolizí může být levá rekurze. Předpokládejme, že gramatika obsahuje pravidloA → Aα a pravidlo B → βCAγ. Pro symboly CA pak platí zároveň relace C

.= A a C l A.

Page 85: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 81

Tento typ kolize lze někdy odstranit přidáním nového nonterminálu D a zaměněním pravidlaB → βCAγ dvojicí pravidel B → βCDγ a D → A. Nyní platí C

.= D a C lA.

Podobně, obsahuje-li gramatika pravidla rekurzivní zprava, mohou nastat kolize mezi relacemi.= a m, které by bylo možno odstranit zavedením nového nonterminálu. Tato metoda se nazývástratifikací (rozvrstvením) gramatiky. Uvedený postup však nemusí vždycky vést k jednoduchéprecedenční gramatice. Provedené změny mohou být důsledkem jiných kolizí v jednoznačnostiprecedenčních relací. Platí-li mezi symboly A a B současně relace l a relace m, pak tento postupnevede k úspěšnému cíli a vhodnější je použít některého z jiných typů syntaktické analýzy.

Nehledě k tomu, že stratifikace zvětšuje precedenční matici, uvedené manipulace s gramatikou,která má kolem 100 pravidel u jazyků jako je Algol 60, vyžadují příliš mnoho času i pro zkušenéosoby.

Stratifikaci budeme nyní ilustrovat na příkladě gramatiky pro popis aritmetického výrazu.

Příklad 6.6 Uvažujme gramatiku G s pravidly:

E → E + T | TT → T ∗ F | FF → (E) | i

Z prvního pravidla plyne relace +.= T . Poněvadž je však gramatika G rekurzivní zleva v T , platí

též + l T . Podobný problém nastává s dvojicí symbolů (, E. Stratifikací obdržíme gramatikus pravidly

E → E1(1)

E1 → E1 + T1(2)

E1 → T1(3)

T1 → T(4)

T → T ∗ F(5)

T → F(6)

F → (E)(7)

F → i(8)

která, jak je vidět z její precedenční matice v tab. 6.4, je jednoduchou precedenční gramatikou.Tab. 6.4 obsahuje rovněž hodnoty precedenčních funkcí f a g.

6.6 Jiné třídy precedenčních gramatik

Rozšíření precedenční gramatiky

Definice Wirth-Weberových precedenčních relací lze zobecnit tak, že místo precedenčních relacímezi dvěma symboly definujeme precedenční relace mezi dvojicemi řetězců. Tak zvané (m,n)-precedenční relace l,

.=,m jsou definovány jako podmnožina množiny

(N ∪ Σ ∪ {]})m × (N ∪ Σ ∪ {]})n

Page 86: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

82 0 0 1

E E1 T1 T F i ( + ∗ ) ] f gE

.= 2 2

E1.= m m 4 3

T1 m m m 5 4T m

.= m m 6 5

F m m m m 7 6i m m m m 7 7(

.= l l l l l l 2 7

+.= l l l l 4 4

∗ .= l l 6 6

) m m m m 7 2] l l l l l l 1 8

Tabulka 6.4: Precedenční matice a funkce

Jsou-li tyto relace disjunktní, pak mluvíme o (m,n)-precedenční gramatice. Věty jazyka, jenžje generován tzv. rozšířenou precedenční gramatikou, mohou být analyzovány algoritmem, jenžse jen nepatrně liší od algoritmu 6.2. Pro vyhodnocení precedenční relace se musí v algoritmurozkladu uvažovat m symbolů na vrcholu zásobníku a n příštích vstupních symbolů. I kdyžz praktických důvodů (rozsah precedenční matice) nebývá n+m > 5, je třída (m,n) precedenč-ních jazyků významně větší něž třída jednoduchých precedenčních jazyků. Zmíněný algoritmusrozkladu však opět vyžaduje, aby byla (m,n)-precedenční gramatika zároveň UI-gramatikou.

Slabé precedenční gramatiky

Definice 6.6 Nechť G = (N,Σ, P, S) bezkontextová gramatika, která nemá žádné ε-pravidla.Říkáme, že G je slabá precedenční gramatika, platí-li tyto dvě podmínky:

(1) Relace m je disjunktní se sjednocením relací l a.=.

(2) Jsou-li A → αXβ a B → β pravidla z P a X ∈ N ∪ Σ, pak neplatí žádná z relací X l Bnebo X

.= B.

K určení konce l-fráze opět slouží relace m. K určení začátku l-fráze však nelze použít relací la.=, poněvadž nejsou disjunktní. Algoritmus rozkladu hledá začátek l-fráze tak, že porovnává

řetězec slov od konce fráze s pravými stranami pravidel. V případě, že by byla některá pravástrana pravidla sufixem jiné pravé strany, mohlo by dojít k nejednoznačnosti. Jsou-li např. A→ γa B → βγ pravidla z P a αβγw pravá větná forma, ve které byl nalezen konec l-fráze mezi řetězciγ a w, pak by nemuselo být jasné, zda se má redukovat řetězec γ, nebo řetězec βγ. Podmínka(2) v definici slabé precedenční gramatiky však zaručuje, že je l-fráze jednoznačně dána nejdelšípravou stranou pravidla, kterého lze k redukci použít. V našem příkladě je tedy αBw příštípravou větnou formou v procesu rozkladu.

Třída slabých precedenčních jazyků není větší než třída jednoduchých precedenčních jazyků.Existuje algoritmus, jenž každou slabou precedenční gramatiku převede na jednoduchou pre-cedenční gramatiku. Výhodou slabých precedenčních gramatik je snad přirozenější a čitelnějšípopis syntaxe jazyka.

Page 87: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 83

Operátorové gramatiky

Definice 6.7 Nechť G = (N,Σ, P, S) je bezkontextová gramatika. Jestliže platí:

(1) Žádná pravá strana pravidla z P neobsahuje dva sousední nonterminály.

(2) Mezi každými dvěma symboly z (Σ ∪ {]}) je definována nanejvýš jedna precedenční relacel nebo

.= nebo m takto:

(a) a.= b je-li A→ αaγbβ v P a γ ∈ (N ∪ {ε})

(b) al b je-li A→ αaBβ v P a B⇒+ γbδ, kde γ ∈ (N ∪ {ε})

(c) am b je-li A→ αBbγ v P a B⇒+ δaγ, kde γ ∈ (N ∪ {ε})

(d) ]l a je-li S⇒+ γaα, γ ∈ (N ∪ {ε})

(e) am ] je-li S⇒+ αaγ, γ ∈ (N ∪ {ε}),

pak G se nazývá operátorovou precedenční gramatikou.

Příklad 6.7 Uvažujme gramatiku G s pravidly:

E → E + T | TT → T ∗ F | FF → i | (E)

Tato gramatika splňuje první podmínku z definice operátorové precedenční gramatiky. V tab.6.5 jsou uvedeny precedenční relace definované mezi terminálními symboly gramatiky G podledefinice operátorové precedenční gramatiky.

+ ∗ ( ) i ]+ m l l m l m

∗ m m l m l m

( l l l.= l

) m m.= m m

i m m m m

] l l l l

Tabulka 6.5: Precedenční matice

Protože precedenční relace jsou definovány jednoznačně, je G operátorovou precedenční grama-tikou.

Operátorové precedenční jazyky jsou vlastní podmnožinou jednoduchých precedenčních jazyků.Nebylo by obtížně sestrojit deterministicky syntaktický analyzátor, jenž na základě precedenčnímatice pro operátorovou precedenční gramatiku identifikuje l-frázi a provádí příslušnou redukci.Výhodou této metody jsou menší nároky na paměť, protože precedenční relace jsou definoványpouze pro terminální symboly gramatiky.

Page 88: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

84 0 0 1

6.7 Cvičení

Cvičení 6.7.1 Která z těchto gramatik je jednoduchá precedenční gramatika?

(a)

S → if E then S else S | aE → E or b | b

(b)

S → AS | AS → (S) | ().

(c)

S → SA | AA → (S) | ().

Cvičení 6.7.2 Uvažujme gramatiku G, která popisuje seznamové struktury, např. ((a, (a,∧)),(a, a), (a)):

S → a | ∧ | (T )

T → T, S | S

Ukažte, že G není jednoduchá precedenční gramatika.

Cvičení 6.7.3 Gramatika G s pravidly

S → a | ∧ | (R)

T → S, T | SR → T

je ekvivalentní s gramatikou z cvičení 6.7.2. Pro gramatiku G vytvořte precedenční matici aprecedenční funkce.

Page 89: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 7

LL jazyky a jejich syntaktickáanalýza

LL jazyky představují vlastní podtřídu deterministických bezkontextových jazyků, pro kterélze zkonstruovat deterministický syntaktický analyzátor. Analyzátory těchto jazyků realizujísyntaktickou analýzu shora–dolů. Název LL je odvozen z charakteristiky analýzy: Left to rightparse – rozklad zleva–doprava a Left parse – levý rozklad.

Jak uvidíme později, analyzátory LL jazyků nemají, z hlediska co nejobecnějšího použití, takovévlastnosti jako analyzátory LR jazyků. Přesto jsou však velmi rozšířené a oblíbené. Hlavnímdůvodem je mnohem menší pracnost a složitost jejich realizace.

7.1 Základní princip syntaktické analýzy LL jazyků

Předpokládejme, že G = (N,Σ, P, S) je jednoznačná gramatika, a že řetězec w = a1a2 . . . an jevětou z L(G). Pak existuje jednoznačná posloupnost větných forem δ0, δ1, . . . , δm:

δ0 = S

δr ⇒Pr δr+1, r = 0, 1, . . . ,m− 1

δm = w

Pr značí index přepisovací pravidla, jež bylo použito pro expanzi nejlevějšího nonterminálu vevětné formě δr.

Vzhledem k tomu, že vytváříme levou derivaci věty w, je každá větná forma δr (s výjimkou δm)tvaru:

δr = a1a2 . . . ajAβ, A ∈ N, β ∈ (N ∪ Σ)∗,

přičemž terminální prefix a1 . . . aj větné formy δr je shodný s prefixem věty w.

Jsou-li A→ α1 | α2 | . . . | αl A-pravidla z P , pak základní problém deterministické syntaktickéanalýzy spočívá v jednoznačném výběru toho pravidla A→ αi, jehož aplikací dostaneme z větnéformy δr příští větnou formu δr+1.

V modelu syntaktického analyzátoru shora–dolů, jenž je reprezentován zásobníkovým automa-tem zkonstruovaným podle věty 4.1, tento problém řešen není; výsledný automat je nedetermi-

85

Page 90: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

86 0 0 1

nistický.

Uvažme však například gramatiku tvaru

G = ({X,Y }, {a, b, c}, P,X)

s pravidly

X → aXa | cY c | bY → aY bX | c

a nějakou levou derivaci, např. věty acacbbca:

X ⇒ aXa⇒ acY ca⇒ acaY bXca⇒ acacbXca⇒ acacbbca

Vidíme, že v této gramatice můžeme vytvořit deterministicky levou derivaci každé věty, protoževýběr pravé strany pravidla pro nonterminál X i Y je zcela jednoznačně určen následujícímsymbolem vstupní věty. Konkrétně, je-li

δr = a1a2 . . . ajAβ

r-tá větná forma, pak výběr pravidla pro přechod k příští větné formě δr+1 v závislosti nanejlevějším nonterminálu A a příštím vstupním symbolu aj+1 popisuje tabulka 7.1.

aj+1

A a b c

S X → aXa X → b X → cY c

Y Y → aY bX Y → c

Tabulka 7.1:

Jednoznačné přiřazení přepisovacího pravidla k dvojici (nonterminál, příští vstupní symbol),tj. k řádku a sloupci v tab. 7.1, bylo velmi jednoduché, poněvadž každé pravidlo uvažovanégramatiky začíná terminálním symbolem a tento jediný terminální symbol je dostačující k de-terministickému výběru správné alternativy. Uvažujme nyní obecnější případ.

Předpokládejme, že pro expanzi nonterminálu A ve větné formě

δr = a1 . . . ajAβ

máme k dispozici příštích k-vstupních symbolů aj+1 . . . aj+k vstupní věty w a že žádné z A-pravidel

A→ α1 | α2 | . . . | αlnegeneruje prázdný řetězec, tj. neplatí αi⇒∗ ε pro žádné αi. Dále předpokládejme, že ke každépravé straně αi umíme nalézt množinu terminálních řetězců x, pro které platí

buď αi⇒∗ x, kde |x| < k

nebo αi⇒∗ xγ, kde |x| = k a γ ∈ (N ∪ Σ)∗,

t.j množinu terminálních řetězců délky nejvýše k, které tvoří prefixy derivací z αi. Jestližedovedeme na základě těchto množin zkonstruovaných ke každé pravé straně αi jednoznačně určit,podle příštích k symbolů aj+1 . . . aj+k, kterého pravidla se má použít k expanzi nontermináluA, pak je problém deterministické syntaktické analýzy opět vyřešen.

Page 91: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 87

Příklad 7.1 Uvažujme gramatiku G = ({S,B,C}, {a, b, c, d}, P, S) s pravidly

S → aB | aCCB → Sb | bC → cC | d

Z tvaru S-pravidel vidíme, že větu generovanou v této gramatice nelze deterministicky syntak-ticky analyzovat na základě pouze jediného příštího vstupního symbolu (je-li tímto symbolemsymbol a, pak nemůžeme rozhodnout, zda se má aplikovat pravidlo S → aB, nebo S → aCC).Uvažujeme tedy případ k = 2 a podle pravidel gramatiky sestrojme ke každé pravé straněpravidla množinu terminálních řetězců délky rovné nebo menší k, kterým začínají derivace z α:

A aB {aa, ab}aCC {ac, ad}

B Sb {aa, ab, ac, ad}b {b}

C cC {cc, cd}d {d}

Tabulka 7.2:

Protože množiny příslušející A-pravidlům jsou disjunktní, je možné k danému nonterminálujednoznačně přiřadit, na základě příštích dvou symbolů, přepisovací pravidlo, jehož se má použít.Toto přiřazení zobrazuje tabulka 7.3.

aa ab ac ad b cc cd dS S → aB S → aB S → aCC S → aCC

B B → Sb B → Sb B → Sb B → Sb B → b

C C → cC C → cC C → d

Tabulka 7.3:

Doposud jsme předpokládali, že gramatika, pro níž hledáme deterministický syntaktický analy-zátor shora–dolů, nemá ε-pravidla. Ukážeme nyní, že diskutovaná metoda, využívající k predikcipravidla pro derivaci příštích vstupních symbolů věty, může být aplikována také na gramatikus ε-pravidly.

Uvažujme opět větnou formuδr = a1 . . . ajAβ

a A-pravidla A→ α1 | α2 | . . . | αl. Předpokládejme, že jedno z A-pravidel může vést k náhraděnonterminálu A prázdným řetězcem, t.j pro některý řetězec αi platí αi⇒∗ ε. Aplikací tohotopravidla pak lze získat v následujících krocích větnou formu

δr+s = a1 . . . ajβ, s ≥ 1.

Jak poznáme, kdy takový případ nastane a kdy tedy použít pravidla A → αi. Povšimněme si,že příští vstupní symboly aj+1, aj + 2, . . . , aj+k v takovém případě neodpovídají terminálnímuprefixu derivace z řetězce αi, ale terminálnímu prefixu derivace z řetězce β. Tento prefix však

Page 92: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

88 KAPITOLA 7. LL jazyky a jejich syntaktická analýza

musí ležet v množině terminálních řetězců (délky rovné k nebo menší než k), které mohou ná-sledovat za nonterminálem A v některé větné formě a jak uvidíme později, tuto množinu umímealgoritmicky nalézt. Za předpokladu, že taková množina terminálních řetězců konečné délky ur-čuje jednoznačně, kdy se má aplikovat pravidlo A→ αi, αi⇒∗ ε, pak je problém deterministickéanalýzy řešitelný i pro gramatiky, jež obsahují ε-pravidla.

Příklad 7.2 Uvažujme gramatiku G = ({S,B,C}, {a, b, c}, P, S) s pravidly

S → aBb | bCa | cB → cS | εC → bB | a

Nejprve spočítáme množiny řetězců délky 1 (nebo 0 v případě αi⇒∗ ε), kterými začínají derivacez pravých stran pravidel.

aBc {a}S bCa {b}

c {c}cS {c}

B ε {ε}bB {b}

C a {a}

Tabulka 7.4:

V důsledku pravidla B → ε nalezneme množinu terminálních řetězců délku l, které se mohouobjevit bezprostředně za nonterminálem B. Z pravidla S → aBb resp. z derivace S ⇒ bCa ⇒bbBa plyne, že tato množina obsahuje prvek b resp. a. Protože množina {a, b} příslušející pravidluB → ε je disjunktní s množinou {c}, jež přísluší druhému B-pravidlu, a protože i množiny proS-pravidla resp. C-pravidla jsou disjunktní, lze na základě jediného příštího vstupního symbolujednoznačně vybrat pravidlo, jež se má v levé derivaci aplikovat. Přiřazení pravidel v závislostina tomto příštím symbolu uvádí tab. 7.5.

a b cS S → aBb S → bCa S → c

B B → ε B → ε B → cS

C C → a C → bB

Tabulka 7.5:

7.2 Výpočet množin FIRST a FOLLOW

V tomto odstavci ukážeme, jakým způsobem lze algoritmicky hledat v dané gramatice množinyterminálních řetězců, které umožňují predikci v deterministické syntaktické analýze shora–dolů.Nejdříve zavedeme jejich pojmenování a přesnou definici.

Page 93: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 89

Konvence 7.1 Nechť Σ je abeceda a k nezáporné celé číslo. Symbolem Σ∗k značíme množinuřetězců nad abecedou Σ, jejíchž délka je menší nebo rovna k, tj. Σ∗k = {x | x ∈ Σ∗ ∧ |x| ≤ k}.

Definice 7.1 Nechť G = (N,Σ, P, S) je gramatika. Množinu FIRSTk(α), α ∈ (N ∪Σ)∗ definu-jeme takto:

FIRSTk(α) = {x | x ∈ Σ∗k a buď |x| < k∧α ∗⇒x nebo |x| = k∧α ∗⇒xγ pro nějaké γ ∈ (N∪Σ)∗}

Příklad 7.3 V gramatice z příkladu 7.2 (viz tab. 7.4) je

FIRST1(aBc) = FIRST1(a) = {a}

FIRST1(B) = {c, ε}

Definice 7.2 Nechť G = (N,Σ, P, S) je gramatika. Množinu FOLLOWk(A), A ∈ N definujemetakto:

FOLLOWk(A) = {x | x ∈ Σ∗k ∧ S ∗⇒αAβ ∧ x ∈ FIRSTk(β), β ∈ (N ∪ Σ)∗}

Příklad 7.4 V gramatice z příkladu 7.2, jež má pravidla

S → aBb | bCa | cB → cS | εC → bB | a

je FOLLOW1(S) = {a, b}, protože existují derivace

S ⇒ aBb⇒ acSb

S ⇒ bCa⇒ bbBa⇒ bbcSa;

FOLLOW1(B) = {a, b},

protože existují derivace

S ⇒ aBb

S ⇒ bCa⇒ bbBa;

FOLLOW1(C) = {a}

protože existuje derivaceS ⇒ bCa.

Jiné derivace, jež by měly vliv na další prvky uvedených množin FOLLOW neexistují.

Konvence 7.2 V případě, že k = 1 budeme psát namísto FIRST1(α) nebo FOLLOW1(A)pouze FIRST(α) nebo FOLLOW(A).

Poznámka 7.1 Z definice 7.2 plyne, že množina FOLLOWk(A) obsahuje prázdný řetězec ε,právě když existuje v gramatice větná forma, jejímž posledním symbolem je nonterminál A, t.jS⇒∗ αA implikuje ε ∈ FOLLOWk(A).

Je jasné, že pro praktické aplikace nepřichází v úvahu způsob výpočtu množin FIRSTk aFOLLOWk, který jsme používali doposud v příkladech 7.1–7.4. Dříve, než formulujeme algoritmy

Page 94: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

90 0 0 1

pro výpočet těchto množin, předešleme, že dominantní praktický význam ve třídě diskutovanýchgramatik má případ k = 1, a že gramatika, ke které hledáme deterministický syntaktický ana-lyzátor shora–dolů, nesmí obsahovat levou rekurzi.

Abychom nalezli množinu FIRST(α), α = X1X2 . . . Xm, je třeba vypočítat množiny FIRST(X)pro všechny symboly X řetězce α. Množiny FIRST(X) jsou definovány podle pravidel, jež plynouz definice 7.1:

1. Je-li X terminál, pak FIRST(X) = {X}

2. Je-li X nonterminál a X → aα pravidlo, pak k množině FIRST(X) přidej terminál a.

Je-li X → ε pravidlo, pak k FIRST(X) přidej ε.

3. Je-li X → Y1Y2 . . . Ym pravidlo, pak pro všechna i, pro která platí Yj ∈ N a FIRST(Yj)obsahuje ε pro j = 1, . . . , i− 1, přidej k FIRST(X) prvky množiny FIRST(Yi) různé od ε.Platí-li ε ∈ FIRST(Yj) pro všechna j = 1, . . . ,m, pak k FIRST(X) přidej také ε.

Známe-li množiny FIRST(Xi), pak FIRST(X1X2 . . . Xm) vypočítáme takto:

Množina FIRST(X1 . . . Xm) bude obsahovat všechny symboly z FIRST(X1) různé od ε. JestližeFIRST(X1) obsahuje ε, pak k FIRST(X1 . . . Xm) přidej všechny symboly z FIRST(X2) různéod ε. Jestliže FIRST(X1) i FIRST(X2) obsahuje ε, pak k FIRST(X1 . . . Xm) přidej symbolyz FIRST(X3) různé od ε, atd. Nakonec k FIRST(X1 . . . Xm) přidáme ε v případě, že všechnymnožiny FIRST(Xi), i = 1, . . . ,m, obsahují ε.

Na základě tohoto postupu můžeme formulovat algoritmus výpočtu množiny FIRST(α), jenž jevhodný zejména pro jeho programovou realizaci.

Algoritmus 7.1 Výpočet množiny FIRST(α).

Vstup: Gramatika G = (N,Σ, P, S) bez levé rekurze a řetězec α = X1X2 . . . Xn, α ∈ (N ∪Σ)∗.

Výstup: Množina FIRST(α).

Metoda:

(1) Vypočítej množinu Nε = {A | A⇒∗ ε}.(2) Vytvoř binární relaci F na množině N ∪ Σ takto:

F = {(X,Y ) | X → αY β je v P, Y ∈ (N ∪ Σ), α ∈ N∗ε , β ∈ (N ∪ Σ)∗}

(3) Vytvoř binární relaci H na množině N ∪ Σ ∪ {ε} takto:

H = F+ ∪ {(X, ε) | X ∈ Nε} ∪ {(a, a) | a ∈ (Σ ∪ {ε})},

kde F+ je tranzitivní uzávěr relace F .

(4) Polož FIRST(Xi) = {a | (Xi, a) ∈ H, Xi ∈ (N ∪ Σ ∪ {ε}), a ∈ (Σ ∪ {ε})} proi = 1, . . . , n.

(5) Polož i = 1 a FIRST(α) = ∅.(6) FIRST(α) := FIRST(α) ∪ FIRST(Xi).

Page 95: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 91

(7) Je-li i = n nebo i < n∧ ε /∈ FIRST(Xi), pak FIRST(α) je výsledná množina. V opač-ném případě FIRST(α) := FIRST(α)− {ε} a vrať se ke kroku (6).

Poznámka 7.2 Formulace algoritmu 7.1 převádí těžiště výpočtu množiny FIRST(α) do kon-strukce tranzitivního uzávěru relace F , pro níž můžeme využít operací s booleovskými maticemi.Poznamenejme, že relace H definuje pro symbol X ∈ (N ∪ Σ ∪ {ε}) ty symboly Y z množiny(N ∪ Σ ∪ {ε}), pro něž platí X⇒∗ Y α, α ∈ (N ∪ Σ)∗.

Příklad 7.5 Pro pravé strany α pravidel gramatiky G = ({A,B,C}, {a, b, c}, P,A),

A → BCb | abE → bB | εT → cA | ε

spočítejte podle algoritmu 7.1 množiny FIRST(α).

(1) Zřejmě je Nε = {B,C}.

(2) Relaci F reprezentujeme booleovskou maticí

[F ] =

A B C a b c

A 0 1 1 1 1 0B 0 0 0 0 1 0C 0 0 0 0 0 1a 0 0 0 0 0 0b 0 0 0 0 0 0c 0 0 0 0 0 0

(3) Vypočítáme matici H

[H] =

A B C a b c ε

A 0 1 1 1 1 0 0B 0 0 0 0 1 0 1C 0 0 0 0 0 1 1a 0 0 0 1 0 0 0b 0 0 0 0 1 0 0c 0 0 0 0 0 1 0ε 0 0 0 0 0 0 1

(4) Dostáváme:

FIRST(A) = {a, b, c}FIRST(B) = {b, ε}FIRST(C) = {c, ε}FIRST(ε) = {ε}

FIRST(X) = {X} pro X = a, b, c

Page 96: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

92 0 0 1

(5)–(7) Dostáváme:

FIRST(BCb) = (FIRST(B)− {ε}) ∪ (FIRST(C)− {ε}) ∪ FIRST(b) = {b, c}FIRST(aB) = {a}FIRST(bB) = {b}

FIRST(ε) = {ε}FIRST(cA) = {c}

Výpočet množiny FOLLOW(A)

Při výpočtu množiny FOLLOW(A), pro všechny nonterminály A ∈ N můžeme postupovat podletěchto pravidel:

1. FOLLOW(S), kde S je výchozí symbol gramatiky, obsahuje ε.

2. Je-li A → αBβ, β 6= ε, pravidlo gramatiky pak všechny prvky z FIRST(β), vyjma ε, jsouobsaženy v FOLLOW(B).

3. Jsou-li A → αB nebo A → αBβ, β⇒∗ ε pravidla gramatiky, pak všechny prvkyz FOLLOW(A) jsou ve FOLLOW(B).

Příklad 7.6 Uvažujme gramatiku z předchozího příkladu 7.5, jež má pravidla

A → BCd | aBB → bB | εC → cA | ε

Položme FOLLOW(A) = FOLLOW(B) = FOLLOW(C) = ∅

1. FOLLOW(A) := {ε}

2.

FOLLOW(B) := FOLLOW(B) ∪ FIRST(Cb) [pravidlo A→ BCb]

FOLLOW(C) := FOLLOW(C) ∪ FIRST(b) [pravidlo A→ BCb]

3.

FOLLOW(B) := FOLLOW(B) ∪ FOLLOW(A) [pravidlo A→ aB]

FOLLOW(A) := FOLLOW(A) ∪ FOLLOW(C) [pravidlo C → cA]

tedy

FOLLOW(A) = {ε, b}FOLLOW(B) = {b, c, ε}FOLLOW(C) = {b}

Page 97: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 93

Algoritmus 7.2 Výpočet množiny FOLLOW(A).

Vstup: Gramatika G = (N,Σ, P, S), A ∈ N .

Výstup: Množina FOLLOW(A).

Metoda:

(1) Vypočítej množinu Nε = {A | A⇒∗ ε}(2) Vytvoř relaci L na množině (N ∪ Σ) takto:

L = {(X,Y ) | X → αY β, je pravidlo z P, β ∈ N∗ε , α ∈ (N ∪ Σ)}

(3) Vypočítej relaci (L−1)∗.

(4) Polož RA = {X | (A,X) ∈ (L−1)∗}, FOLLOW(A) = ∅.Množina RA obsahuje zřejmě právě ty nonterminály, ze kterých lze derivovat řetězcekončící nonterminálem A (ve smyslu relace ⇒∗).

(5) Pro každý výskyt nonterminálu X ∈ RA na pravé straně α× β pravidla proveď:

FOLLOW(A) := FOLLOW(A) ∪ (FIRST(β)− {ε})

(6) Je-li S ∈ RA, pak FOLLOW(A) := FOLLOW(A) ∪ {ε}

Příklad 7.7 Pro všechny nonterminály gramatiky G = ({A,B,C}, {a, b, c}, P, S),

A → aBC | bBB → CbA | c | εC → aBa | cBaC | ε

spočítejte podle algoritmu 7.2 množinu FOLLOW.

(1) Nε = {B,C}.

(2)

[L] =

A B C a b c

A 0 1 1 1 1 0B 1 0 0 0 0 1C 0 0 1 1 0 0a 0 0 0 0 0 0b 0 0 0 0 0 0c 0 0 0 0 0 0

(3)

[L−1∗] =

A B C a b c

A 1 1 0 0 0 0B 1 1 0 0 0 0C 1 1 1 0 0 0a 1 1 1 1 0 0b 1 0 0 0 1 0c 1 1 0 0 0 1

Page 98: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

94 0 0 1

(4)

RA = {A,B}RB = {A,B}RC = {A,B,C}

(5)

FOLLOW(A) = (FIRST(C)− {ε}) ∪ FIRST(a) ∪ FIRST(aC)

FOLLOW(B) = (FIRST(C)− {ε}) ∪ FIRST(a) ∪ FIRST(aC)

FOLLOW(C) = (FIRST(C)− {ε}) ∪ FIRST(a) ∪ FIRST(aC) ∪ FIRST(bA)

Dosadíme-li nyní hodnoty množin FIRST, (FIRST(C) = {a, c, ε}), pak s přihlédnutím k bodu(6) dostáváme výsledné množiny FOLLOW:

FOLLOW(A) = {ε, a, c}FOLLOW(B) = {ε, a, c}FOLLOW(C) = {ε, a, b, c}

7.3 Definice LL(k)-gramatiky

Definice 7.3 Nechť G = (N,Σ, P, S) je gramatika. Říkáme, že G je LL(k) gramatika pro nějaképevné k ≥ 0, jestliže z libovolných dvou levých derivací tvaru

S∗⇒wAβ ⇒ wα1β

∗⇒wx a

S∗⇒wAβ ⇒ wα2β

∗⇒wy

takových, že FIRSTk(x) = FIRSTk(y), plyne α1 = α2.

Definice 7.3 říká, že G je LL(k) gramatika, jestliže pro danou větnou formu tvaru wAβ a proprvních k terminálních symbolů, které mají být vygenerovány z Aβ, existuje v gramatice Gprávě jedno přepisovací pravidlo A→ α.

Definice 7.4 Je-li G LL(k) gramatika pro nějaké k, pak říkáme, že G je LL gramatika. Jazykgenerovaný LL(k) gramatikou nazýváme LL(k) jazykem nebo, nespecifikujeme-li hodnotu k,také LL jazykem.

Příklad 7.8 Uvažujme gramatiku

S → aAS | bA → a | bSA

Intuitivně G je LL(1) gramatika, poněvadž pro libovolnou větnou formu s nejlevějším non-terminálem C a vstupní řetězec s příštím terminálem c existuje pouze jedno pravidlo, kteréderivuje terminální řetězec začínající symbolem c. Skutečně, začínají-li x a y terminálem a,

Page 99: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 95

použilo se pravidla S → aAS(α1 = α2 = aAS); začínají-li x a y terminálem b, pak se pou-žilo pravidla S → b(α1 = α2 = b). Poněvadž z S nemůže být derivován prázdný řetězec ε,není možné, aby platilo, že x = y = ε. Analogický rozbor lze provést pro tuto dvojici deri-vací: S⇒∗wAβ ⇒ wα1β⇒∗wx a S⇒∗wAβ ⇒ wα2β⇒∗wy. Tato gramatika je příkladem tzv.jednoduché LL(1) gramatiky.

Definice 7.5 Gramatika G, jež nemá žádná ε-pravidla, se nazývá jednoduchou LL(1) gramati-kou, začíná-li pro každý nonterminál A každá pravá strana terminálním symbolem a jsou-li tytoterminály v rámci A-pravidel vzájemně různé.

Gramatika z předchozího příkladu, stejně jako gramatika, jejíž pravidla jsou uvedena v tabulce7.1, je jednoduchou LL(1) gramatikou. V jednoduché LL(1) gramatice tedy k dané dvojici(A, a), A ∈ N, a ∈ Σ existuje nanejvýš jedno pravidlo tvaru A→ aα.

Věta 7.1 Nechť G = (N,Σ, P, S) je gramatika. G je LL(k) gramatika právě, když platí: JestližeA → α1 a A → α2 jsou dvě různá pravidla z P , pak FIRSTk(α1β) ∩ FIRSTk(α2β) = ∅ provšechna β, pro která platí S⇒∗wAβ.

Důkaz:

Část „jen kdyžÿ:

Předpokládejme, že FIRSTk(α1β)∩FIRSTk(α2β) obsahuje řetězec x. Pak podle definice množinyFIRST existují derivace

S∗⇒wAβ ⇒ wα1β ⇒ wxy

S∗⇒wAβ ⇒ wα2β ⇒ wxz

pro nějaké y, z.

Je-li |x| < k, pak y = z = ε. Protože α1 6= α2, G není LL(k) gramatikou.

Část „kdyžÿ:

Předpokládejme, že G není LL(k). Pak existují dvě derivace

S∗⇒wAβ ⇒ wα1β

∗⇒wx,

S∗⇒wAβ ⇒ wα2β

∗⇒wy

takové, že řetězce x a y jsou shodné v prvních k symbolech, avšak α1 6= α2. Pak A→ α1 a A→ α2

jsou různá pravidla v P a FIRSTk(α1β) i FIRSTk(α2β) obsahuje FIRSTk(x) = FIRSTk(y).

Věta 7.1 má důležitou aplikaci na určitou třídu LL(1) gramatik: 2

Věta 7.2 Nechť G = (N,Σ, P, S) je gramatika, která nemá žádná ε-pravidla. G je LL(1) gra-matika, právě když pro všechny nonterminály A z N má každá množina A-pravidel A → α1 |α2 | . . . | αn tu vlastnost, že množiny FIRST(α1), FIRST(α2), . . . , FIRST(αn) jsou všechnypo dvojicích disjunktní.

Důkaz: Tvrzení je bezprostředním důsledkem věty 7.1 a skutečností, že G neobsahuje ε-pravidla.V tom případě je FIRST1(αβ) = FIRST1(α) pro všechna S⇒∗ γAβ a A→ α. 2

Page 100: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

96 0 0 1

Ve větě 7.2 byl předpoklad, že G neobsahuje žádné ε-pravidlo, podstatný. Dříve, než uvedemevětu, která stanovuje LL(1) podmínku pro gramatiku, která připouští i ε-pravidla, rozšířímedefinici množiny FIRST (definice 7.1) takovým způsobem, aby ji bylo možno konstruovat i promnožinu n řetězců.

Definice 7.6 Nechť G = (N,Σ, P, S) je gramatika a nechť L ⊆ (N ∪ Σ)∗. Pak

FIRSTk(L) =⋃α∈L

FIRSTk(α)

Věta 7.3 Gramatika G = (N,Σ, P, S) je LL(1) gramatikou právě když platí implikace: Jsou-liA→ α1 a A→ α2 dvě různá pravidla pro libovolné A ∈ N , pak

FIRST(α1FOLLOW(A)) ∩ FIRST(α2FOLLOW(A)) = ∅.

Důkaz: Důkaz se provede analogicky důkazu věty 7.1. Ponecháme jej jako cvičení.

Na základě věty 7.3 lze formulovat dvě nutné a postačující podmínky pro LL(1) gramatiky. 2

Věta 7.4 Gramatika G je LL(1) gramatikou, právě když pro každou množinu A-pravidel A→α1 | α2 | . . . | αn platí tyto podmínky:

(1) FIRST(α1),FIRST(α2), . . . ,FIRST(αn) jsou po dvojicích disjunktní (podmínka FF)

(2) Jestliže αi⇒∗ ε, pak FIRST(αj) ∩ FOLLOW(A) = ∅ pro 1 ≤ j ≤ n, i 6= j (podmínka FFL)

Připomeňme, že relace αi⇒∗ ε může platit nanejvýš pro jediné pravidlo A → αi. V opačnémpřípadě by nebyla splněna podmínka FF, poněvadž by průnik dvojice množin FIRST obsahovalε.

Příklad 7.9 Uvažujme gramatiku G = ({E, T, F}, {i,+, ∗, (, )}, P, S) s pravidly

E → E + T | TT → T ∗ F | FF → i | (E)

popisující strukturu aritmetických výrazů. Tato gramatika nemůže být LL gramatikou, pro-tože obsahuje levou rekurzi. Po odstranění levé rekurze (viz příklad 4.14) dostaneme gramatikus pravidly

E → TE′ | TE′ → +TE′ | +TT → FT ′ | FT ′ → ∗FT ′ | ∗FF → (E) | i

Vidíme, že ani tato gramatika není LL gramatikou, protože např. průnik FIRSTk(TE′) ∩FIRSTk(T ) je neprázdný pro libovolné k.

Page 101: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 97

Připustíme-li, že daná gramatika může obsahovat ε-pravidla, pak můžeme uvedená pravidlav jistém smyslu zjednodušit:

E → TE′

E′ → +TE′ | εT → FT ′

T ′ → ∗FT ′ | εF → (E) | i

Podle věty 7.4 nyní vyšetříme, zda tato gramatika je LL(1) gramatikou. Nejdříve musíme spo-čítat množiny FIRST a FOLLOW:

FIRST(E) = FIRST(T ) = FIRST(F ) = {(, i}FIRST(E′) = {+, ε}FIRST(T ′) = {∗, ε}

FOLLOW(E) = FOLLOW(E′) = {), ε}FOLLOW(T ) = FOLLOW(T ′) = {+, ), ε}FOLLOW(F ) = {+, ∗, ), ε}

Vidíme, že F -pravidla neobsahují ε-pravidlo a splňují podmínku FF. E′-pravidla i T ′-pravidlasplňují jak podmínku FF, tak i FFl a tudíž je tato gramatika LL(1) gramatikou.

Definice 7.7 Nechť G je gramatika. Jestliže pro každá dvě různá A-pravidla A→ α1 a A→ α2

z P platíFIRSTk(α1FOLLOWk(A)) ∩ FIRSTk(α2FOLLOWk(A)) = ∅,

pak G se nazývá silná LL(k) gramatika.

Z věty 7.3 plyne, že každá LL(1) gramatika je silná LL(1) gramatika. Tento poznatek, jakilustruje následující příklad, nelze zobecnit pro k > 1.

Příklad 7.10 Uvažujme gramatiku G s pravidly

S → aAaa | bAbaA → b | ε

Podle věty 7.1 se můžeme snadno přesvědčit, že G je LL(2) gramatikou. Spočítáme-li všakFOLLOW2(A) = {aa, ba} a vyhodnotíme-li podmínku pro silné LL(k) gramatiky, dostanemepro A-pravidla.

FIRST2(b FOLLOW2(A)) ∩ FIRST2(FOLLOW2(A)) = {ba}

a vidíme tedy, že G není silná LL(2) gramatika.

Věta 7.5 Nechť G je gramatika, jež obsahuje levou rekurzi. Pak G není LL(k) gramatika prožádné k.

Důkaz: Podle definice levé rekurze existuje v G pro některý nonterminál A derivace A⇒+ Aα.Předpokládejme, že G nemá zbytečné symboly, takže platí A⇒+ u a α⇒∗ v pro jisté řetězceu, v ∈ Σ∗. Pak můžeme zkonstruovat tyto derivace:

S∗⇒wAδ

+⇒wαkδ+⇒wuvkx a

Page 102: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

98 0 0 1

S∗⇒wAδ

+⇒wAαkδ+⇒wAαk+1δ

+⇒wuvk+1x

Protože však FIRSTk(uvkx) = FIRSTk(uvk+1x) pro libovolné k, nemůže být LL(k) gramatikou.2

Následující věta shrnuje některé důležité poznatky o LL(k) gramatikách a jazycích.

Věta 7.6 (1) Každá LL(k) gramatika je jednoznačná.

(2) Je-li G bezkontextová gramatika, která není LL(k) gramatikou pro dané k1, pak je neroz-hodnutelné, zda G má ekvivalentní LL(k) gramatiku pro některé k2 > k1.

(3) Pro k ≥ 0 jsou LL(k) jazyky vlastní podmnožinou LL(k + 1) jazyků.

Tvrzení (2) a (3) vylučují existenci algoritmu, který vždy transformuje danou bezkontextovougramatiku na LL(k) gramatiku, nebo danou LL(k) gramatiku na LL(1) gramatiku. V odstavci7.5 ukážeme, jakým způsobem lze však v některých případech dílčími transformacemi získatLL(1) gramatiku. S jednou z nich jsme se již setkali v příkladě 7.8; je to odstranění levé rekurze.

7.4 Algoritmus syntaktické analýzy pro LL(k) gramatiky

Algoritmus syntaktické analýzy pro LL(k) gramatiky patří do skupiny tzv. prediktivních al-goritmů rozkladu, protože provádí predikci přepisovacích pravidel podle příštích terminálníchsymbolů analyzované věty. Výstupem tohoto algoritmu je levý rozklad, jehož definice je analo-gická definici pravého rozkladu.

Definice 7.8 Nechť G je gramatika a nechť všechna pravidla z P jsou očíslována indexy1, 2, . . . , p. Nechť α ∈ (N ∪ Σ)∗ je větná forma v G. Levým rozkladem řetězce α nazývámeposloupnost indexů přepisovacích pravidel, jež byla postupně aplikována v levé derivaci větnéformy α, tj. je-li

Spi1⇒ δ1

pi2⇒ δ2

pi3⇒ . . .pin⇒ δn = α

levá derivace větné formy α, pak π = pi1pi2 . . . pin je levý rozklad této větné formy.

Algoritmus rozkladu pro LL(k) gramatiky používá vstupní pásky, zásobníku, tzv. rozkladovétabulky a výstupní pásky (viz obr. 7.1). Podobně, jako v algoritmu 6.2, použijeme k jeho popisukonfigurací a přechodů mezi konfiguracemi.

Obrázek 7.1: Prediktivní algoritmus rozkladu

Na vstupní pásce je uložen řetězec terminálních symbolů (vstupních symbolů) wx, jehož levýrozklad π, existuje-li, bude zobrazen na výstupní pásce. Položme wx = wux′.

Page 103: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 99

Podřetězec w reprezentuje již zpracovanou část vstupního řetězce, x je zbývající část vstupníhořetězce; podřetězec u = FIRSTk(x) reprezentuje prefix (délky k) řetězce x.

Zásobník obsahuje řetězec Xα], kde Xα je řetězec nad abecedou zásobníku, kterou označímesymbolem Γ. Speciální koncový znak ] indikuje konec zásobníku. Symbol X je na vrcholu zá-sobníku.

Výstupní páska obsahuje řetězec π, jenž je tvořen čísly (indexy) přepisovacích pravidel. Konfi-gurace algoritmu je dána trojicí (x,Xα, π), kde:

1) x je dosud nezpracovaná část vstupního řetězce

2) Xα je obsah zásobníku (X je vrchol)

3) π je řetězec na výstupní pásce

Přechod z jedné konfigurace do druhé je předepsán rozkladovou tabulkou M , která reprezentujezobrazení z (Γ ∪ {]})× Σ∗k do množiny obsahující tyto prvky:

1) (β, i), kde β je řetězec z Γ∗, i je číslo přepisovacího pravidla

2) pop (indikuje odstranění symbolu ze zásobníku)

3) accecpt (indikuje přijetí vstupního řetězce)

4) error (indikuje syntaktickou chybu)

Nyní, je-li na vrcholu zásobníku symbol X a je-li u = FIRSTk(x) podřetězec reprezentujícík příštích symbolů vstupního řetězce, pak M(X,u) předepisuje tyto typy přechodů (přechodbudeme označovat symbolem `):

(1) (x,Xα, π) ` (x, βα, πi), je-li M(X,u) = (β, i)

Symbol X na vrcholu zásobníku je přepsán řetězcem β; k řetězci π je připojen index i. Neníčten příští vstupní symbol.

(2) (x,Xα, π) ` (x′, α, π), je-li M(X,u) = pop, x = ax′, X = a

Shoduje-li se první symbol řetězce x se symbolem X na vrcholu zásobníku, je symbol z vr-cholu odstraněn a čtecí hlava je posunuta o jeden symbol doprava.

(3) Přejde-li algoritmus do konfigurace (ε, ], π), pak rozklad končí. Předpokládáme, že M(], ε)je vždy accept. Řetězec π je levým rozkladem původního vstupního řetězce.

(4) Jestliže algoritmus rozkladu přejde do konfigurace (x,Xα, π) a M(X,u) = error , pakvstupní řetězec není syntakticky správně utvořen.

Příklad 7.11 Ilustrujme činnost uvedeného algoritmu na příkladě LL(1) gramatiky z příkladu7.8, jež má pravidla:

S → aAS(1)

S → b(2)

A → a(3)

A → bSA(4)

Page 104: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

100 0 0 1

Symbol X na vrcholu zásobníku

u = FIRST(x)

a b εS aAS, 1 b, 2 errorA a, 3 bSA, 4 errora pop error errorb error pop error] error error accept

Tabulka 7.6:

Prediktivní algoritmus používá rozkladové tabulky, tab. 7.6.

Bude-li na vstupní pásce uložen řetězec abbab, pak algoritmus projde těmito konfiguracemi:

(abbab, S], ε) ` (abbab, aAS], 1)

` (bbab,AS], 1)

` (bbab, bSAS], 14)

` (bab, SAS], 14)

` (bab, bAS], 142)

` (ab,AS], 142)

` (ab, aS], 1423)

` (b, S], 1423)

` (b, b], 14232)

` (ε, ], 14232)

Pro první přechod je M(S, a) = (aAS, 1), takže vrchol zásobníku S je přepsán řetězcem aAS;na výstupní pásku je zapsána 1. Pro další přechod je M(a, a) = pop, což odpovídá odstraněnísymbolu a z vrcholu zásobníku a posuvu čtecí hlavy o jeden symbol doprava. Pokračujeme-litakto, dosáhneme koncové konfigurace (ε, ], 14232). Řetězec abbab je tedy větou jazyka L(G).Jeho levý rozklad je π = 14232.

Z tab. 7.6 vidíme, že rozkladová tabulka pro LL(1) gramatiku má jednoduchý tvar. Popsanýprediktivní algoritmus provádí pro záznamy typu (β, i) přímou derivaci X ⇒ β, (X je vrcholzásobníku), podle i-tého pravidla X ⇒ β. Z toho pak vyplývá, že v případě LL(1) gramatiky jeabeceda zásobníku Γ = (N ∪ Σ ∪ {]}). Nad touto abecedou je také definována tabulka M .

Ke každé LL(k) gramatice existuje rozkladová tabulka M , která definuje popsaný prediktivníalgoritmus realizující rozklad vět LL(k) jazyka. Nyní ukážeme, jakým způsobem lze sestrojitrozkladovou tabulku pro LL(1) gramatiky.

Algoritmus 7.3 Konstrukce rozkladové tabulky pro LL(1) gramatiku

Vstup: LL(1) gramatika G = (N,Σ, P, S), jejíž každé pravidlo je opatřeno indexem.

Výstup: Rozkladová tabulka M pro gramatiku G

Metoda: Tabulka M je definována na (N ∪ Σ ∪ {]})× (Σ ∪ {ε}) takto:

Page 105: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 101

(1) Je-li A → α i-té pravidlo z P , pak M(A, a) = (α, i) pro všechna a z množinyFIRST(α), a 6= ε. Je-li také ε prvkem množiny FOLLOW (A).

(2) M(a, a) = pop pro všechna a z množiny Σ

(3) M(], ε) = accept

(4) V ostatních případech M(X, a) = error , pro X ∈ N ∪ Σ ∪ {]}, a ∈ Σ ∪ {ε}

Příklad 7.12 Uvažujme LL(1) gramatiku z příkladu 7.10. Nejdříve očíslujeme její pravidla:

E → TE′(1)

E′ → +TE′(2)

E′ → ε(3)

T → FT ′(4)

T ′ → ∗FT ′(5)

T ′ → ε(6)

F → (E)(7)

F → i(8)

Pro ilustraci ukažme, jak podle algoritmu 7.3 vypočítáme první a druhý řádek příslušné roz-kladové tabulky M . Celá tabulka je uvedena v tabulce 7.7. Prázdná políčka reprezentují prvkyerror.

i ( ) + ∗ εE TE′, 1 TE′, 1E′ ε, 3 +TE′, 2 ε, 3T FT ′, 4 FT ′, 4T ′ ε, 6 ε, 6 ∗FT ′, 5 ε, 6F i, 8 (E), 7i pop( pop) pop+ pop∗ pop] accept

Tabulka 7.7:

Poněvadž FIRST(TE′) = {(, i}, bude M [E, (] = (TE′, 1) a M [E, i] = (TE′, 1). Všechny ostatnípoložky prvního řádku jsou error. Ke druhému řádku se vztahují přepisovací pravidla (2) a (3).Nejdříve vypočteme FIRST(+TE′) = {+}, takže M [E′,+] = (+TE′, 2). Poněvadž FIRST(ε) ={ε}, musíme vypočítat FOLLOW (E′) = {ε, )}. Opět podle bodu (1) algoritmu 7.3 je M [E′, ε] =M [E′, )] = (ε, 3).

Prediktivní algoritmus používající rozkladové tabulky z tab. 7.7 prochází, např pro vstupnířetězec (i*i), touto posloupností konfigurací:

[(i ∗ i), E], ε] ` [(i ∗ i), TE′], 1]

Page 106: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

102 0 0 1

` [(i ∗ i), FT ′E′], 14]

` [(i ∗ i), (E)T ′E′], 147]

` [i ∗ i), E)T ′E′], 147]

` [i ∗ i), TE′)T ′E′], 1471]

` [i ∗ i), FT ′E′)T ′E′], 14714]

` [i ∗ i), iT ′E′)T ′E′], 147148]

` [∗i), T ′E′)T ′E′], 147148]

` [∗i), ∗FT ′E′)T ′E′], 1471485]

` [i), FT ′E′)T ′E′], 1471485]

` [i), iT ′E′)T ′E′], 14714858]

` [), T ′E′)T ′E′], 14714858]

` [), E′)T ′E′], 147148586]

` [), )T ′E′], 1471485863]

` [ε, T ′E′], 1471485863]

` [ε, E′], 14714858636]

` [ε, ], 147148586363]

Je-li k > 1, je konstrukce rozkladové tabulky pro LL(k) gramatiky poněkud složitější. Rozkla-dová tabulka je v tomto případě definována jako zobrazení z množiny (Γ ∪ {]}) × Σk, kde Γobsahuje kromě terminálních a nonterminálních symbolů jména tzv. LL(k) tabulek, které sevytvářejí pro jednotlivá pravidla LL(k) gramatiky. Důležitá je však skutečnost, že složitější jepouze konstrukce rozkladové tabulky a nikoliv vlastní algoritmus rozkladu.

7.5 Problém transformace na L(1) gramatiku

Ve třídě LL(k) gramatik mají pro praktické aplikace zvláštní význam právě LL(1). Tento významplyne ze dvou skutečností:

(1) Algoritmus pro konstrukci rozkladové tabulky, včetně algoritmů pro výpočet množin FIRSTa FOLLOW, je jednodušší pro k = 1 než pro k > 1.

(2) Rozkladová tabulka (pro reálné programovací jazyky) není pro vyšší hodnoty k praktickyuložitelná v paměti počítače. (Sloupce tabulky jsou označeny nejen řetězci délky k, ale iřetězci délky menší než k, viz tab. 7.5). Z věty 7.6 však víme, že LL(1) jazyky jsou vlastnípodtřídou LL(k) jazyků pro k ≤ 2, tj. neplatí, že pro každou LL(k) gramatiku existujeekvivalentní LL(1) gramatika.

Přes tyto skutečnosti nacházejí LL(1) gramatiky při implementaci syntaktického analyzátoruprogramovacích jazyků značné využití. Teoretické překážky, které vyplývají z věty 7.6 se obchá-zejí už při definici jazyka (jeho syntax je volena tak, aby byla bezprostředně popsatelná LL(1)gramatikou; viz jazyk PASCAL). Dále je pak možné, v případě, když daná gramatika jazykanení LL(1) gramatikou, aplikovat určité transformace, jež mohou vést k LL(1) gramatice. Takovétransformace budeme nyní diskutovat.

Page 107: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 103

1 Odstranění levé rekurze

Tato transformace je důležitá pro všechny syntaktické analyzátory shora–dolů včetně analyzá-torů, jež pracují s návraty. Jádrem transformace pro odstranění levé rekurze je podle algoritmu4.6 náhrada A-pravidel

A→ Aα1 | Aα2 | . . . | Aαn | β1 | . . . | βm

pravidly

A → β1 | β2 | . . . | βm | β1A′ | . . . | βmA′

A′ → α1 | α2 | . . . | αn | α1A′ | . . . | αnA′

Pro transformaci na LL(1) gramatiku však tato náhrada není vhodná, protože zavedená A-pravidla a A′-pravidla nesplňují podmínku FF z věty 7.4 (FIRST(βi) = FIRST(βiA′) stejnějako FIRST(αi) = FIRST(αiA′)).

Připusťme, na rozdíl od algoritmu 4.6, že výsledná gramatika bez levé rekurze může obsahovatε-pravidla. Pak lze levou rekurzi nonterminálu A odstranit nahrazením uvedených A-pravidelpravidly

A → β1A′ | β2A

′ | . . . | βmA′

A′ → α1A′ | α2A

′ | . . . | αnA′ | ε,

jež generují právě takové řetězce, jako A a A′-pravidla z algoritmu 4.6.

Poznamenejme, že kdybychom na gramatiku pro aritmetický výraz z příkladu 7.8 aplikovalitento způsob odstranění levé rekurze, získali bychom okamžitě výslednou LL(1) gramatiku.

2 Faktorizace

Tato transformace se uplatňuje u pravidel tvaru

A→ βα1 | βα2 | . . . | βαn,

t.j A-pravidel, jejichž pravé strany mají společný prefix β, β ∈ (N∪Σ)+. Je zřejmé, že tato vlast-nost vede k nesplnění podmínky FF. Faktorizace je postup analogický „vytýkání před závorkuÿv aritmetice. Spočívá v nahrazení uvedených A-pravidel pravidly

A → βA′

A′ → α1 | α2 | . . . | αn

kde A′ je nový nonterminál.

Příklad 7.13 Uvažujme gramatiku s pravidly

S → aS | a

Tato gramatika je LL(2) gramatikou, avšak ne LL(1) gramatikou. Po faktorizaci dostanemeekvivalentní gramatiku

S → aS′

S′ → S | ε

Page 108: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

104 0 0 1

která je LL(1) gramatikou, poněvadž FIRST(S) = {a} a FOLLOW(S′) = {ε}.

Faktorizace se často uplatňuje ve spojení s eliminací pravidla gramatiky podle věty 4.7. Jestližese v gramatice vyskytují pravidla

A→ α1 | α2 | . . . | αn

která nesplňují podmínku FF věty 7.4, přičemž tato pravidla nelze faktorizovat, pak je možnéopakovanou eliminací některých pravidel získat faktorizovatelná A-pravidla.

Příklad 7.14 Uvažujme pravidla

A → aB | CDC → aE | bF

Vidíme, že A-pravidla nesplňují podmínku FF. Eliminujeme-li pravidlo A → CD dostávámenová A-pravidla

A→ aB | aED | bFD

která po faktorizaci

A → aA′ | bFDA′ → B | ED

již podmínku FF splňují.

3 Redukce množiny FOLLOW(A)

Tato transformace se může úspěšně uplatnit v případě nesplnění podmínky FFL věty 7.4, tj.v případě že existují A-pravidla A→ α1 | α2 taková, že α1⇒∗ ε a FIRST(α2)∩FOLLOW(A) 6= ∅.Transformace spočívá v přidání nového nonterminálu gramatiky, který vede ke zmenšení počtuprvků množiny FOLLOW(A) a případně k disjunktnosti množiny FIRST(α2) a FOLLOW(A).Na druhé straně však tato úprava může zapříčinit změnu ve splnění podmínky FF věty 7.4.

Příklad 7.15 Uvažujme gramatiku s pravidly

A → BaC

B → abC | εC → cBb | a

Poněvadž FOLLOW(B) = {a, b} a FIRST(abC) ∩ FOLLOW(B) = {a}, tato gramatika neníLL(1) gramatikou. Redukujme proto množinu FOLLOW(B) zavedením nového nontermináluD = 〈BA〉 a příslušných D-pravidel

D → abCa | a

V ekvivalentní gramatice

A → DC

B → abC | εC → cBb | aD → abCa | a

Page 109: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

7.6. Cvičení 105

již platí FOLLOW(B) = {b} a tudíž FIRST(abC)∩FOLLOW(B) = ∅. Po faktorizaci D-pravideldostáváme gramatiku

A → DC

B → abC | εC → cBb | aD → aD′

D′ → bCa | ε

která již je LL(1) gramatikou (FOLLOW(D′) = {c, a}).

Na závěr znovu zdůrazněme, že uvedené transformace nemusí vést nutně k cíli, a to ani v případě,že pro daný jazyk LL(1) gramatika existuje.

Příklad 7.16 Uvažujme gramatiku G s pravidly

S → A | BA → a | cAB → b | cB

S-pravidla nesplňují podmínku FF a je tedy třeba nejdříve provést jejich eliminaci:

S → a | cA | b | cB

Po faktorizaci těchto nových S-pravidel dostáváme

S → a | b | cS′

S′ → A | B

Vidíme, že jsme dospěli k výchozímu problému (tentokrát u S′-pravidel) a opakování tohotopostupu dále již nemá smysl. Přitom jazyk L(G) = {cna | n ≥ 0} ∪ {cnb | n ≥ 0} je LL(1)jazykem a může být generován LL(1) gramatikou s pravidly

S → a | b | BAA → a | bB → cC

C → ε | cC

7.6 Cvičení

Cvičení 7.6.1 Gramatika G s pravidly

E → TE′(1)

E′ → +E(2)

Page 110: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

106 KAPITOLA 7. LL jazyky a jejich syntaktická analýza

E′ → ε(3)

T → FT ′(4)

T ′ → T(5)

T ′ → ε(6)

F → PF ′(7)

F ′ → ∗F ′(8)

F ′ → ε(9)

P → (E)(10)

P → a(11)

P → b(12)

P → ε(13)

popisuje regulární výrazy nad abecedou {a, b}; ε značí prázdný symbol výrazu.

a) Pro každý nonterminál této gramatiky vypočítejte množiny FIRST a FOLLOW

b) Ukažte, že G je LL(1) gramatika

c) Vytvořte rozkladovou tabulku pro G

d) Realizujte rozklad věty ε+ ab∗ + a∗b

Cvičení 7.6.2 Ukažte, že každý regulární jazyk je LL(1) jazykem. Dále ukažte, že jazyk gene-rovaný LL(0) gramatikou má nanejvýš jednu větu.

Cvičení 7.6.3 Ukažte, že gramatika s pravidly S → aaSbb | a | ε je LL(2) gramatikou. Na-lezněte ekvivalentní LL(1) gramatiku.

Cvičení 7.6.4 Sestrojte LL(1) gramatiku jazyka PL0, jehož grafy syntaxe jsou uvedeny v pří-loze. Na základě této gramatiky sestrojte rozkladovou tabulku.

Page 111: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Kapitola 8

LR jazyky a jejich syntaktickáanalýza

LR(k)1 gramatiky reprezentují největší třídu gramatik, ke kterým lze vždy sestrojit determinis-tický syntaktický analyzátor zdola–nahoru. Důležitost LR jazyků plyne z těchto dvou skuteč-ností:

(1) Pro všechny programovací jazyky, které lze popsat bezkontextovou gramatikou, můžemeprakticky sestrojit LR syntaktické analyzátory.

(2) Metody syntaktické analýzy LR jazyků jsou obecnější, než metody analýzy jednoduchýchnebo operátorových precedenčních jazyků nebo metody deterministické syntaktické analýzyshora–dolů a přitom vedou ke stejně efektivním analyzátorům.

Zásadní nevýhodou syntaktické analýzy LR(k) jazyků je přílišná pracnost implementace. Přiaplikacích na typické programovací jazyky je prakticky nemožné konstruovat LR analyzátorručně, bez použití konstruktoru LR analyzátoru. Tímto problémem se budeme zabývat v odst.8.2 a 8.3.

8.1 Definice LR(k) gramatiky

Předpokládejme, že G = (N,Σ, P, S) je jednoznačná gramatika, a že w = a1a2 . . . an je větouz L(G). Pak existuje jednoznačná posloupnost větných forem δ0, δ1, . . . , δm, které tvoří pravouderivaci věty w:

δ0 = S

δi ⇒pi δi+1, i = 0, 1, . . . ,m− 1

δm = w

pi značí index přepisovacího pravidla, kterého jsme použili pro expanzi nejpravějšího nontermi-nálu větné formy δi. Řetězec indexů pm−1pm−2 . . . p1p0 reprezentuje pravý rozklad věty w.

1Název LR je odvozen z „Left to rightÿ a „Right parseÿ.

107

Page 112: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

108 0 0 1

Neformálně řečeno, jestliže můžeme jednoznačně určit l-frázi každé větné formy δi pro i =m,m − 1, . . . , 1 a nonterminál, k němuž bude l-fráze redukována tak, že prohlížíme symbolyvětné formy δi zleva doprava, přičemž nám „stačíÿ nanejvýš k symbolů za koncem l-fráze, pakgramatiku G nazýváme LR(k) gramatikou. Je-li tedy

δi−1 = βAz,

δi = βαz

(tj. α je l-frází větné formy δi) pak na základě nejvýše k symbolů řetězce z (tj. k příštích vstupníchsymbolů) dovedeme jednoznačně určit l-frázi α a nonterminál A, ke kterému se redukuje (podlepravidla A→ α). V případě LR(k) gramatiky je tak jednoznačně určena relace δi−1⇒rm δi;⇒rm

značí pravou derivaci.

Aby v průběhu syntaktické analýzy LR(k) jazyků nevznikaly komplikace a výskytem výchozíhosymbolu na pravé straně pravidla, definujeme tzv. rozšířenou gramatiku (augmented grammar).

Definice 8.1 Nechť G = (N,Σ, P, S) je gramatika. Gramatika G′ = (N∪{S′}, P∪{S′ → S}, S′)se nazývá rozšířenou gramatikou gramatiky G.

Rozšířená gramatika G′ je zřejmě ekvivalentní s gramatikou G; přitom zaručuje, že pro δi = S′

proces syntaktické analýzy zdola–nahoru končí přijetím vstupního řetězce. Pravidlu S′ → Sobvykle přiřadíme index 0.

Definice 8.2 Nechť G = (N,Σ, P, S) je gramatika a G′ její rozšířená gramatika. Jestliže prokaždé dvě pravé derivace v gramatice G′

S′ ⇒∗ βAz ⇒ βαz

S′ ⇒∗ γBv ⇒ βαu

pro které FIRSTk(z) = FIRSTk(u) platí βAz = γBv (tj. β = γ,A = B a z = v), pak G senazývá LR(k) gramatikou, k ≥ 0.

Příklad 8.1 Uvažujme pravou lineární gramatiku G s pravidly

S → C | DC → aC | bD → aD | c

Ukážeme, že G je LR(1) gramatika. Každá (pravá) derivace v rozšířené gramatice gramatiky Gmá tvar

S′ ⇒ S ⇒ Ci⇒ aiC ⇒ aib

neboS′ ⇒ S ⇒ D

i⇒ aiD ⇒ aic

Ve shodě s definicí 8.2 uvažujme derivace tvaru

S′ ⇒∗ βAz ⇒ βαz

S′ ⇒∗ γBv ⇒ βαu

Poněvadž G je pravá lineární gramatika, musí platit z = v = ε. Je-li (podle definice) FIRST(z) =FIRST(u), pak je ale také u = ε. Musíme proto ukázat, že βA = γB, tj. β = γ a A = B.

Předpokládejme, že v derivaci γBv ⇒ βαu jsme použili pravidla B → δ. Existují tři situace,které musíme uvažovat:

Page 113: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 109

(1) A = S′, tj. derivace S′⇒∗ βAz je triviální.

Pak je ovšem β = ε a α = S. Protože existuje pouze jedna cesta, jak získat větnou formu S,je γ = ε a B = S′ a tedy β = γ a A = B.

(2) A = C

Pak α je buď aC, nebo b. V prvním případě B = C, protože pouze nonterminály C a Smají pravidla, jež končí na C. Kdyby platilo B = S, pak by z tvaru derivace v G muselobýt γ = ε. Protože γB 6= βα, platí tedy B = C, δ = aC a γ = β. V druhém případě (α = b)platí B = C také, poněvadž pouze nonterminál C má pravidlo, jež končí symbolem b. Opětdostáváme B = A a γ = β.

(3) A = D

Tento případ je symetrický s případem (2).

Poznamenejme, že G je ve skutečnosti LR(0) gramatika a že G není LL(1) gramatika.

Příklad 8.2 Gramatika s pravidly

S → Ab | BcA → Aa | εB → Ba | ε

je ekvivalentní s gramatikou z předchozího příkladu. Uvažujme dvě pravé derivace v její rozšířenégramatice:

S′ ⇒ S ⇒∗ Aakb⇒ akb

S′ ⇒ S ⇒∗ Bakc⇒ akc

Tyto dvě derivace splňují předpoklad definice 8.2 pro β = ε, α = ε, z = akb, γ = ε, v = akc.Poněvadž A 6= B, pro libovolné k, není uvažovaná gramatika LR gramatikou.

Příklad 8.3 Uvažujme gramatiku G s pravidly

S → AB

A → a

B → CD | aEC → ab

D → bb

E → bba

a dvě pravé derivace v její rozšířené gramatice:

S′ ⇒ S ⇒ AB ⇒ ACD ⇒ ACbb⇒ Aabbb

S′ ⇒ S ⇒ AB ⇒ AaE ⇒ Aabba

Ve větné formě Aabz nemůžeme určit, zda se pravý konec l-fráze nachází mezi b a z (kdyžz = bb), nebo hned napravo od A (když z = ba), pouze na základě prvního symbolu řetězce z.G tudíž není LR(1) gramatikou. Dá se však ukázat, že G je LR(2) gramatikou.

Na obrázku 8.1 je názorně ukázána situace při konstrukci derivačního stromu v případě LR(k)a LL(k) gramatiky. Vyšrafovaná oblast znázorňuje již sestrojenou část derivačního stromu.

Page 114: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

110 0 0 1

Obrázek 8.1: Syntaktická analýza věty vlevo: LR(k), vpravo: LL(k) jazyka

Následující věta shrnuje důležité poznatky o LR gramatikách a jazycích. Uvádíme ji bez důkazu.

Věta 8.1

(1) Každá LR(k) gramatika je jednoznačná.

(2) Každý deterministický jazyk je generovatelný nějakou LR(k) gramatikou.

(3) Každý LR(k) jazyk má LR(1) gramatiku.

Vidíme, že tvrzení (2) a (3) se zcela liší od obdobných poznatků ve třídě LL(k) gramatik a jazyků.Na obr. 8.1 je znázorněna celá hierarchie tříd deterministických bezkontextových jazyků, s nimižjsme se seznámili.

Ze skutečnosti, že každý deterministický jazyk lze popsat LR(1) gramatikou, vyplývá, že LR(1)gramatiky mají pro praktické aplikace mimořádný význam. Proto se v další části této kapitolyomezíme pouze na LR(1) gramatiky a jejich podtřídy – jednoduché LR(1) gramatiky a LALR(1)gramatiky, jež vedou k jednodušší konstrukci syntaktického analyzátoru.

8.2 Syntaktická analýza LR-jazyků

LR analyzátor se skládá, podobně jako LL analyzátor, ze dvou částí: řídící části a rozkladovétabulky (8.2). Řídící část analyzátoru zůstává stejná pro různé LR analyzátory; mění se pouzerozkladová tabulka. Z tohoto důvodu se problém automatické konstrukce LR analyzátoru prak-ticky redukuje na implementaci algoritmu, jež pro danou LR gramatiku vytváří rozkladovoutabulku. Funkci konstruktoru LR analyzátoru ilustruje obr. 8.2.

8.2.1 Algoritmus syntaktické analýzy

Syntaktický analyzátor LR jazyků představuje, podobně jako analyzátor jazyků precedenčních,realizaci rozšířeného zásobníkového automatu. Jeho struktura je uvedena na obr. 8.2.1.

Syntaktický analyzátor operuje nad vstupní páskou, jež obsahuje vstupní řetězec a je čtena zlevadoprava, zásobníkem a rozkladovou tabulkou, která zobrazuje funkce, jež jsou realizovány řídícíčástí. Vstupní řetězec je ukončen vždy symbolem ]. Výstupní páska obsahuje, v případě úspěšněukončené analýzy, pravý rozklad vstupní věty. Zásobník obsahuje řetězce tvaru

s0X1s1X2s2 . . . Xmsm,

Page 115: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0 0 1 111

Obrázek 8.2: Hierarchie deterministických bezkontextových jazyků

Obrázek 8.3: Schéma LR analyzátoru

sm je vrchol zásobníku. Každý symbol Xi reprezentuje terminální nebo nonterminální symbolgramatiky. Zásobníkové symboly si budeme nazývat stavy. Stav sm na vrcholu zásobníku su-marizuje informaci o celém obsahu zásobníku a slouží k rozhodnutí, zda se má provést redukce,nebo přesun vstupního symbolu do zásobníku.

Jádrem analyzátoru je rozkladová tabulka, která reprezentuje dvě dvouargumentové funkce,funkci akcí a funkci přechodů. Označme Sz množinu stavů (zásobníková abeceda Γ = Sz∪N∪Σ).

Funkce akcí je definována jako zobrazení

AKCE: Sz × (Σ ∪ {]})→ {shift s, reduce i, error , accept}.

Funkce přechodů je definována jako zobrazení

PŘECHOD: Sz × (Σ ∪N)→ Sz

a je ve skutečnosti, jak uvidíme později, přechodovou funkcí deterministického konečného auto-matu.

Page 116: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

112 0 0 1

Obrázek 8.4: Konstruktor LR analyzátoru

Obrázek 8.5: Struktura LR syntaktického analyzátoru

Konfigurací LR analyzátoru budeme rozumět trojici řetězců

(s0X1s1X2s2 . . . Xmsm, aiai+1 . . . an], i1i2 . . . ik)

z nichž první představuje obsah zásobníku, druhý dosud nezpracovanou část vstupního řetězcea třetí, tvořící se pravý rozklad vstupního řetězce.

Příští činnost analyzátoru je určena na základě čteného vstupního symbolu ai, vrchol zásobníkusm a hodnoty funkce akcí AKCE[sm, ai]:

1. Je-li AKCE[sm, ai] = shift s, pak analyzátor provede přesun do zásobníku a přejde dokonfigurace

(s0X1s1X2s2 . . . Xmsmais, ai+1 . . . an], i1i2 . . . ik)

To tedy znamená, že do zásobníku se přesunul přečtený vstupní symbol ai a stav a =PŘECHOD[sm, ai]. Příštím vstupním symbolem se stává ai+1.

2. Je-li AKCE[sm, ai] = reduce i, pak analyzátor provede redukci podle i-tého pravidla gra-matiky A→ α.

Výsledná konfigurace má tvar

(s0X1s1X2s2 . . . Xm−rsm−rAs, aiai+1 . . . an], i1i2 . . . iki)

kde s = PŘECHOD[sm−r, A], r je délka pravé strany α i-tého pravidla gramatiky. Ze zásob-níku bylo nejdříve odstraněno 2r symbolů (r symbolů gramatiky a r stavových symbolů),

Page 117: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 113

takže na vrcholu zásobníku se objevil symbol sm−r. Pak analyzátor uložil na vrchol zásob-níku nonterminál A a stav s = PŘECHOD[sm−r, A] a do výstupního řetězce přidal index ipřepisovacího pravidla, podle něhož proběhla redukce. Vstupní symbol zůstává nezměněn.Poznamenejme, že hodnota AKCE[sm, ai] = reduce i vlastně říká, že Xm−r+1 . . . Xm = αje l-fráze, a že má být redukována k nonterminálu A.

3. Je-li AKCE[sm, ]] = accept , pak rozklad věty byl úspěšně dokončen. Řetězec i1i2 . . . iktvoří pravý rozklad věty.

4. Je-li AKCE[sm, ai] = error , pak byla objevena syntaktická chyba. Vstupní symbol ai lzechápat jako její velmi blízkou lokalizaci.

Celou činnost analyzátoru lze nyní popsat velmi jednoduše. Na počátku je analyzátor v počátečníkonfiguraci

(s0, a1a2 . . . an], ε)

kde s0 je vyznačený (počáteční) stavový symbol a a1 . . . an je vstupní řetězec.

Podle popsaného postupu se pak provádí přechody mezi konfiguracemi tak dlouho, pokud ne-nastane případ AKCE[sm, ai] = accept , nebo AKCE = error .

Příklad 8.4 Tab. 8.1 je rozkladová tabulka pro gramatiku

E → E + T(1)

E → T(2)

T → T ∗ F(3)

T → T(4)

F → (E)(5)

F → i(6)

Hodnoty funkce akcí jsou kódovány tímto způsobem:

si – shift irj – reduce j

acc – accept– error

Hodnota funkce přechodů PŘECHOD[sm, a] pro a ∈ Σ ∪ {]} je v tab. 8.1 zobrazena v částiAKCE společně s kódem pro přesun do zásobníku (společně s akcí shift). V části PŘECHODjsou pak zobrazeny hodnoty funkce přechodů pro nonterminály; uplatňují se v případě redukce.

S uvedenými konvencemi kódování funkcí akcí a přechodů ilustrujme činnost analyzátoru provstupní řetězec i ∗ i+ 1. Odpovídající posloupnost konfigurací je uvedena v tab. 8.2.

V řádku 1 je analyzátor v počáteční konfiguraci. Poněvadž podle rozkladové tabulky (tab. 8.1)je AKCE[0, i] = s5, přesune se vstupní symbol a stavový symbol 5 do zásobníku (viz řádek 2).Nyní je pod čtecí hlavou symbol ∗ a protože AKCE[5, ∗] = r6, provede se redukce podle 6-téhopravidla F → i takto:

(1) odstraní se 2 symboly ze zásobníku, takže na vrcholu se objeví stav 0,

Page 118: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

114 KAPITOLA 8. LR jazyky a jejich syntaktická analýza

Stav Akce Přechodai

sm i + ∗ ( ) ] E T F0 s5 s4 1 2 31 s6 acc2 r2 s7 r2 r2

3 r4 r4 r4 r4

4 s5 s4 8 2 35 r6 r6 r6 r6

6 s5 s4 9 37 s5 s4 108 s6 s11

9 r1 s7 r1 r1

10 r3 r3 r3 r3

11 r5 r5 r5 r5

Tabulka 8.1: Rozkladová tabulka

(2) poněvadž PŘECHOD[0, F ] = 3, do zásobníku se uloží symboly F a 3 a na výstup indexpravidla F → i, tj. 6 (viz řádek 3).

Podobným způsobem se pokračuje až do okamžiku, kdy AKCE[1, ]] = acc (řádek 14), kdyčinnost analyzátoru končí. Na výstupu je řetězec 64632641 reprezentující pravý rozklad větyi ∗ i+ 1.

8.3 Konstrukce rozkladové tabulky

Jádrem implementace LR analyzátoru je zřejmě konstrukce rozkladové tabulky. Existuje několikmetod vytváření rozkladové tabulky, které se liší jak v pracnosti jejich konstrukce, požadavcíchna paměť, tak také v mocnosti metod jednoznačně definovat funkci akcí pro danou gramatiku.

V této podkapitole se seznámíme se třemi metodami vytváření rozkladové tabulky:

– pro jednoduché LR(1) gramatiky

– pro LR(1) gramatiky

– pro LALR(1) gramatiky

První případ představuje nejméně pracnou, avšak také nejomezenější cestu k získání rozkladovétabulky. LR(1) gramatiky jsou velmi univerzální; rozkladová tabulka pro LR(1) gramatiku jevšak náročná na paměť a její konstrukce je velmi pracná. Rozkladová tabulka pro LALR(1)gramatiku představuje kompromis mezi jednoduchými LR(1) a LR(1) gramatikami. Obě pod-třídy LR(1) gramatik vymezíme prostřednictvím algoritmu vytváření jejich rozkladové tabulky;nebudeme uvádět její formální definice. Lze je nalézt např. v [3].

Page 119: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

8.3. Konstrukce rozkladové tabulky 115

Obsah zásobníku Vstup Výstup1 O i ∗ i+ i]

2 Oi5 ∗i+ i]

3 OF3 ∗i+ i] 64 OT2 ∗i+ i] 645 OT2 ∗ 7 i+ i] 646 OT2 ∗ 7i5 +i] 647 OT2 ∗ 7F10 +i] 6468 OT2 +i] 64639 OE1 +i] 64632

10 OE1 + 6 i] 6463211 OE1 + 6i5 ] 6463212 OE1 + 6F3 ] 64632613 OE1 + 6T9 ] 646326414 OE1 ] 64632641

Tabulka 8.2: Činnost LR analyzátoru

8.3.1 Kanonický soubor LR(0) položek, konstrukce SLR rozkladové tabulky

Definice 8.3 Nechť G = (N,Σ, P, S) je gramatika. Řetězec γ ∈ (N ∪ Σ)∗ se nazývá perspek-tivním prefixem (viable prefix) v gramatice G, jestliže existuje pravá derivace S⇒∗ βAz ⇒ βαztaková, že γ je prefixem řetězce βα.

Perspektivní prefix je tedy takovým prefixem pravé větné formy, který neobsahuje žádný symbolza pravým koncem l-fráze této větné formy. Označení „perspektivníÿ plyne ze skutečnosti, žeje možné vždy za perspektivní prefix přidat řetězec terminálních symbolů a dostat tak pravouvětnou formu v G. Je-li

(s0X1s1 . . . Xmsm, aiai+1 . . . an, i1 . . . ik)

konfigurace analyzátoru taková, že AKCE[sm, ai] 6= error , pak právě X1X2 . . . Xm představujeperspektivní prefix v gramatice G. V této podkapitole ukážeme konstrukci deterministického ko-nečného automatu, který je schopen rozpoznávat perspektivní prefixy. To, že lze takový konečnýautomat sestrojit, patří k pozoruhodným výsledkům teorie LR-jazyků. Zřejmě je tedy množinaperspektivních prefixů gramatiky G kvalitativně odlišná od jazyka generovaného gramatikou G.

Definice 8.4 Nechť G = (N,Σ, P, S) je gramatika. Říkáme, že [A → α1 · α2, u], α1, α2 ∈ (N ∪Σ)∗, u ∈ Σ∗k je LR(k) položka pro gramatiku G a dané k, jestliže A → α1α2 je pravidlo z P .Říkáme, že LR(k) položka [A→ α1 ·α2, u] je platná pro řetězec βα1, jestliže existuje v G praváderivace

S∗⇒βAz ⇒ βα1α2z

taková, že u = FIRSTk(z). (Řetězec βα1 je tedy perspektivním prefixem).

Konvence 8.1 V případě, že to nebude na újmu srozumitelnosti, budeme, namísto LR(k) po-ložka pro G a dané k, říkat krátce položka a v zápisu položky vynechávat hranaté závorky. Je-lik = 0, pak je v položce druhá složka u vždy rovna ε a budeme ji také vynechávat.

Page 120: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

116 0 0 1

Příklad 8.5 Například pravidlo A→ XY Z generuje čtyři LR(0) položky:

A → ·XY ZA → X · Y ZA → XY · ZA → XY Z·

Pravidlo A→ ε generuje jedinou položku

A→ ·

Intuitivně, každá položka indikuje pozicí tečky, jakou část l-fráze „vidímeÿ v procesu rozkladupřed provedením redukce podle daného pravidla. V příkladě 8.5 první položka říká, že očekávámeřetězec derivovatelný z XY Z, druhá říká, že na vstupu vidíme řetězec derivovatelný z X aočekáváme řetězec derivovatelný z Y Z.

Jednotlivé položky můžeme interpretovat jako stavy nedeterministického konečného automatu,který rozpoznává perspektivní prefixy v gramatice G

Jednotlivé položky můžeme interpretovat jako stavy nedeterministického konečného automatu,který rozpoznává perspektivní prefixy v gramatice G. Sdružením položek do určitých množinmůžeme dospět ke stavům LR analyzátoru, které, jak již jsme uvedli, přísluší deterministickémuautomatu. Tento automat, jak uvidíme, definuje funkci přechodu rozkladové tabulky.

Soubor množin LR(0) položek, nazývaný kanonický LR(0) soubor, tvoří základ konstrukce roz-kladové tabulky pro třídu LR gramatik – jednoduchých LR gramatik, krátce SLR gramatik(Simple LR). Ukážeme nyní způsob vytváření tohoto kanonického LR(0) souboru.

Nejdříve je třeba definovat dvě funkce, které nazveme UZÁVĚR a GOTO.

Definice 8.5 Nechť I je množina LR(0) položek gramatiky G. Množina položek UZÁVĚR(I)je definována těmito pravidly:

(1) Každá položka z I je v množině UZÁVĚR(I).

(2) Je-li [A → α1 · Bα2] v množině UZÁVĚR(I) a β → γ je pravidlo gramatiky, pak [B → ·γ]je také v množině UZÁVĚR(I).

Intuitivně, je-li [A→ α1 ·Bα2] ∈ UZÁVĚR(I), pak to znamená, že v jistém okamžiku rozkladuočekáváme na vstupu řetězec derivovatelný z Bα2. Existence pravidla B → γ pak implikuje, žev tomto okamžiku můžeme případně očekávat řetězec derivovatelný z γ, a proto je v množiněUZÁVĚR(I) také položka [B → ·γ].

Příklad 8.6 Uvažujme rozšířenou gramatiku

E′ → E

E → E + T | TT → T ∗ F | FF → (E) | i

Page 121: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 117

Jestliže I je množina s jedinou položkou {[E′ → ·E]}, pak UZÁVĚR(I) obsahuje položky

E′ → ·EE → ·E + T

E → ·TT → ·T ∗ FT → ·FF → ·(E)

F → ·i

Položka [E′ → ·E] je v množině UZÁVĚR(I) na základě pravidla (1). Protože tečka leží bez-prostředně před nonterminálem E, pak na základě pravidla (2) definice 8.5 a E-pravidel grama-tiky, jsou v množině UZÁVĚR(I) obsaženy položky [E → ·E + T ] a [E → ·T ]. Nyní, protože[E → ·T ] ∈ UZÁVĚR(I) platí (podle pravidla (2)) [T → ·T ∗ F ] ∈ UZÁVĚR(I) a [T → ·F ] ∈UZÁVĚR(I) plyne [F → ·(E)] ∈ UZÁVĚR(I). Jiné položky množina UZÁVĚR{(E′ → ·E)}neobsahuje.

Definice 8.6 Nechť I je množina LR(0) položek a X je symbol gramatiky, X ∈ (N∪Σ). FunkceGOTO(I,X) je definována jako množina UZÁVĚR({[A→ α1X · α2] | [A→ α1 ·Xα2] ∈ I}), tj.uzávěr všech položek [A→ α1X · α2] takových, že [A→ α ·Xα2] leží v I.

Intuitivně, je-li I množina položek, které jsou platné pro perspektivní prefix γ, pak GOTO(I,X)je množina položek, jež jsou platné pro perspektivní prefix γX (viz definice 8.4).

Příklad 8.7 Je-li I množina položek {[E′ → E·], [E → E · +T ]}, pak GOTO(I,+) obsahujeprávě položky:

E → E + ·TT → ·T ∗ FT → ·FF → ·(E)

F → ·i

Protože první položka množiny I neobsahuje symbol +, nemá vliv na hodnotu funkceGOTO(I,+). Druhá položka neobsahuje symbol + právě za tečkou. Proto posuneme tečku za+, dostaneme položku [E → E + ·T ] a spočítáme UZÁVĚR({E → E + ·T}).

Nyní již můžeme formulovat algoritmus pro výpočet kanonického souboru množin LR(0) položek.

Algoritmus 8.1 Výpočet kanonického souboru množin LR(0) položek.

Vstup: Rozšířená gramatika ke gramatice G = (N,Σ, P, S)

Výstup: Kanonický soubor C množin LR(0) položek

Metoda:

(1)

I0 := UZÁVĚR({S → ·S′})C := {I0}r := 0

Page 122: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

118 0 0 1

(2) pro všechna Ik ∈ C, k = 0, 1, . . . , r a pro všechna X ∈ (N ∪ Σ) proveď: je-liGOTO(Ik, X) 6= ∅ ∧GOTO(Ik, X) 6∈ C pak

(a) r := r + 1

(b) Ir := GOTO(Ik, X)

(c) C := C ∪ {Ir}(3) opakuj krok (2) tak dlouho, pokud lze k souboru C přidávat novou množinu Ir.

Algoritmus 8.1 zřejmě končí, poněvadž při výpočtu funkce GOTO se posouvá tečka vždy o jedensymbol doprava.

Příklad 8.8 Uvažujme gramatiku z příkladu 8.6. Její kanonický soubor C LR(0) položek mátvar:

C = {I0, I1, . . . , I11}

kde množiny položek Ik obsahují položky:

I0 = UZÁVĚR({E′ → ·E}): E′ → ·E I5 = GOTO(I0, i): F → i·E → ·E + T I6 = GOTO(I1,+): E → E + ·TE → ·T T → ·T ∗ FT → ·T ∗ F T → ·FT → ·F F → ·(E)F → ·(E) F → ·iF → ·i

I1 = GOTO(I0, E): E′ → E· I7 = GOTO(I2, ∗): T → T ∗ ·FE → E ·+T F → ·(E)

I2 = GOTO(I0, T ): E → T · F → ·iE → T · ∗F I8 = GOTO(I4, E): F → (E·)

I3 = GOTO(I0, F ): T → F · E → E ·+TI4 = GOTO(I0, (): F → (·E) I9 = GOTO(I6, T ): E → E + T ·

E → ·E + T T → T · ∗FE → ·T I10 = GOTO(I7, F ): T → T ∗ F ·F → ·T ∗ F I11 = GOTO(I8, )): F → (E)·T → ·FF → ·(E)F → ·i

Funkce GOTO představuje funkci deterministického konečného automatu

D = (N ∪ Σ, C, I0, δ, C), kde δ(I,X) = GOTO(I,X),

jehož vstupní abecedou je množina terminálních a nonterminálních symbolů, stavy jsou repre-zentovány množinami Ik, I0 je počáteční stav a každý stav může být koncovým stavem. AutomatD rozpoznává množinu perspektivních prefixů v gramatice G. Tento překvapující fakt (automatD je deterministický pro každou gramatiku) plyne z konstrukce množin Ik podle algoritmu 8.1.Ekvivalentní nedeterministický automat je definován tak, že jeho stavy jsou jednotlivé LR(0)položky a přechodová funkce δ je konstruována takto:

δ([A→ α ·Xβ], x) obsahuje [A→ αX · β]

Page 123: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 119

δ([A→ α ·Bβ], ε) obsahuje [B → ·γ], B → γ je pravidlo v G.

Na obr. 8.6 je diagram přechodů konečného deterministického automatu D pro kanonický soubormnožin LR(0) položek z příkladu 8.8. V tomto diagrama jsou zobrazeny samozřejmě i ty hodnotyfunkce GOTO, které jsme při konstrukci kanonického souboru explicitně nevypisovali, např.GOTO(I4, () = I4.

Obrázek 8.6: Diagram přechodů automatu D

Jeden z hlavních teorému teorie rozkladu LR jazyků říká, že množinou platných položek properspektivní prefix γ je právě množina položek dosažitelná z počátečního stavu automatu D pocestě, jež odpovídá řetězci γ. Ukažme platnost tohoto tvrzení na předchozím příkladě.

Příklad 8.9 Uvažujme gramatiku G z příkladu 8.6 a její kanonický soubor množin LR(0) po-ložek z příkladu 8.8. Řetězec E + T∗ je perspektivní prefix v této gramatice. Automat na obr.8.6 po zpracování řetězce E + T∗ bude ve stavu I7; stav I7 zahrnuje položky

T → T ∗ ·FF → ·(E)

F → ·i

které představují právě platné položky pro perspektivní prefix E+T∗. Podle definice 8.4 je LR(0)položka [A→ α1 · α2] platnou pro prefix βα1, jestliže existuje v G pravá derivace S⇒∗ βAz ⇒βα1α2z. Uvažujme proto následující tři pravé derivace v G.

(1) E′ ⇒ E ⇒ E + T ⇒ E + T ∗ F(2) E′ ⇒ E ⇒ E + T ⇒ E + T ∗ F ⇒ E + T ∗ (E)(3) E′ ⇒ E ⇒ E + T ⇒ E + T ∗ F ⇒ E + Ti

⇒ . . .⇒ E + T ∗ z, z ∈ Σ∗

Page 124: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

120 0 0 1

Z první, resp. druhé, resp. třetí derivace plyne, že [T → T ∗ ·F ] resp. [F → ·(E)], resp. [F → ·i]je platnou položkou pro řetězec E + T∗. Dá se ukázat, že pro tento řetězec jiná platná položkaneexistuje.

Nyní popíšeme postup, jak lze získat z kanonického souboru LR(0) položek, definujícího automatD, funkci akcí a funkci přechodů rozkladové tabulky. Obecně uvažovaný soubor nemusí obsahovatdostačující informaci pro konstrukci jednoznačné rozkladové tabulky. Popsaná metoda budeúspěšná pouze pro jednoduché LR(1) jazyky (SLR(1) jazyky); v mnoha případech je všakúspěšná i v aplikacích z oblasti programovacích jazyků.

Algoritmus 8.2 Konstrukce SLR(1) rozkladové tabulky.

Vstup: Kanonický soubor C množin LR(0) položek pro rozšířenou gramatiku G′.

Výstup: Rozkladová tabulka zahrnující funkci akcí a přechodů, je-li G SLR(1) gramatika.

Metoda: Nechť C = {I0, I1, . . . , In}. Stavové symboly analyzátoru jsou 0, 1, . . . , n; stav i od-povídá množině položek Ii. Funkce akcí AKCE[i, a] je definována takto:

(1) Je-li [A → α · aβ] ∈ Ik a GOTO(Ik, a) = Ij , pak AKCE[k, a] = shift j. Symbol a jeterminál.

(2) Je-li [A → α·] ∈ Ik, A → α je i-té pravidlo, pak AKCE[k, a] = reduce i pro všechnaa, pro která a ∈ FOLLOW(A). Pokud S′⇒∗ γA, pak ] ∈ FOLLOW(A).

(3) Je-li [S′ → S·] ∈ Ik, pak AKCE[k, ]] = accept .

(4) Je-li GOTO(Ik, A) = Ij , A ∈ N , pak PŘECHOD[k,A] = j.

(5) Místa rozkladové tabulky, jež nebyla definována body (1)–(4), mají hodnotu error.

(6) Počáteční stav analyzátoru odpovídá množině I0, která obsahuje položku [S′ → ·S].

Jestliže v algoritmu 8.2 vznikne z bodů (1) a (2) nejednoznačnost v definici funkce AKCE, pakpro danou gramatiku nelze zkonstruovat SLR(1) rozkladovou tabulku. Říkáme, že gramatika Gnení jednoduchá LR(1) gramatika. Množina FOLLOW nám dává k dispozici jeden terminál zal-frází, podle něhož určujeme, ke kterému pravidlu se má l-fráze redukovat.

Příklad 8.10 Aplikujeme algoritmus 8.2 na gramatiku z příkladu 8.6. Opět využijeme kano-nického souboru LR(0) položek z příkladu 8.8 a příslušejícího automatu D z obr. 8.6

Uvažujme položku, která konstituuje počáteční stav analyzátoru

I0 : E′ → ·EE → ·E + T

E → ·TT → ·T ∗ FT → ·FF → ·(E)

F → ·i

Položka [F → ·(E)] implikuje AKCE[0, (] = shift 4, položka [F → ·i] implikuje AKCE[0, i] =shift 5.

Page 125: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 121

Uvažujme

I1 : E′ → E ·E → E ·+T

První položka dává AKCE[1, ]] = accept , druhá, AKCE[1,+] = shift 6.

Uvažujme

I2 : E → T ·T → T · ∗F

Protože FOLLOW(E) = {],+, )} a E → T je 2. pravidlo, z první položky plyne AKCE[2, ]] =AKCE[2,+] = AKCE[2, )] = reduce 2. Z druhé položky plyne AKCE[2, ∗] = shift 7.Pokračujeme-li stejným způsobem, získáme celou rozkladovou tabulku (viz tab. 8.1).

Zřejmě každá SLR(1) gramatika je jednoznačná. Následující příklad ilustruje existenci jedno-značné gramatiky, která není SLR(1) gramatikou.

Příklad 8.11 Uvažujme gramatiku G s pravidly

S → L = R(1)

S → R(2)

L → ∗R(3)

L → i(4)

R → L(5)

Kanonický soubor množin LR(0) položek získaný algoritmem 8.1 má tvar:

I0: S′ → ·S I5: L → i·S → ·L = R I6: S → L = ·RS → ·R R → ·LL → · ∗R L → · ∗RL → ·i L → ·iR → ·L I7: L → ∗R·

I1: S′ → S· I7: L → ∗R·I2: S → L· = R I8: R → L·

R → L· I9: S → L = R·I3: S → R·I4: L → ∗ ·R

R → ·LL → · ∗RL → ·i

Uvažujme množinu I2. První položka implikuje AKCE[2,=] = shift 6. Protože FOLLOW(R)obahuje =, (viz derivaci S ⇒ L = R⇒ ∗R = R), z druhé položky plyne AKCE[2,=] = reduce 5.Protože tedy hodnota AKCE[2,=] není jednoznačně definována (ve stavu 2 při vstupním sym-bolu = vzniká konflikt typu shift – reduce), není G SLR(1) gramatikou.

Page 126: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

122 0 0 1

8.3.2 Konstrukce kanonické LR rozkladové tabulky

Zůstaňme ještě u situace z předchozího příkladu, která je zdrojem nejednoznačné definice funkceAKCE. Tato situace, jež vede k selhání metody konstrukce SLR rozkladové tabulky, vznikáproto, že analyzátor je ve stavu k, Ik obsahuje položku [A→ α·], zásobník obsahuje perspektivníprefix βα a ač je a ∈ FOLLOW(A), neexistuje v gramatice větná forma s prefixem βAa. To tedyznamená, že hodnota AKCE[k, a] = reduce i je irelevantní. Skutečně, v gramatice z předchozíhopříkladu neexistuje větná forma tvaru R = · · ·, takže ve stavu 2, který odpovídá perspektivnímuprefixu L je nesprávné provést redukci podle pravidla R→ L.

Konflikty v definice rozkladové tabulky mohou být ve většině případů (v případě LR(1) gramatikvždy) odstraněny použitím LR(1) položek. Podle definice 8.3 má LR(1) položka tvar

[A→ α1 · α2, a], a ∈ (Σ ∪ {]}).

Tato položka je platná pro perspektivní prefix βα1, jestliže existuje pravá derivace S⇒∗ βAz]⇒βα1α2z] taková, že a = FIRST(z]). Druhá složka LR(1) položky se nevyužívá v případě α2 6= ε,avšak položka tvaru [A→ α1·, a] vede k redukci pouze v případě, že příštím vstupním symbolemje symbol a.

Příklad 8.12 Uvažujme gramatiku s pravidly

S → BB

B → aB | b

a pravou derivaciS∗⇒ aaBab⇒ aaaBab

v této gramatice.

Vidíme, že položka [B → a · B, a] je platná pro perspektivní prefix βα1 = aaa (β = aa, α1 =a,A = B,α2 = B, z = ab). Pro pravou derivaci S⇒∗BaB⇒BaaB je pro perspektivní prefixBaa platnou položkou položka [B → a ·B, ]].

Metoda výpočtu souboru množin platných LR(1) položek je v podstatě stejná jako metodavýpočtu kanonického souboru množin LR(0) položek. Opět potřebujeme funkce UZÁVĚR aGOTO, podobné stejnojmenným funkcím z odst. 8.3.1.

Uvažujme položku tvaru [A → α1 · Bα2, a], jež je v množině platných položek pro perspek-tivní prefix βα1. Pak existuje pravá derivace tvaru S⇒∗ βAax⇒ α1Bα2ax. Předpokládejme, žeřetězec α2ax derivuje terminální řetězec by. Pak pro každé pravidlo tvaru β → γ dostanemederivaci S⇒∗ βα1Bby⇒ βα1γby, tedy [B → ·γ, b] je platnou položkou pro perspektivní pre-fix βα1. Zřejmě je b prvkem množiny FIRST(α2a). V případě, že α2⇒∗ ε je b = a. Poněvadža ∈ (Σ ∪ {]}) je FIRST(α2ax) = FIRST(α2a).

Nyní již přistoupíme ke konstruktivním definicím funkcí UZÁVĚR a GOTO pro LR(1) položky.

Definice 8.7 Nechť I je množina LR(1) položek gramatiky G. Množina položek UZÁVĚR(I)je definována těmito pravidly:

(1) Každá položka z I je prvkem UZÁVĚR(I).

Page 127: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 123

(2) Je-li [A → α1 · Bα2, a] v množině UZÁVĚR(I) a je-li B → γ pravidlo gramatiky, pakpro každý terminál b z množiny FIRST(α2a) je položka [B → ·γ, b] také prvkem množinyUZÁVĚR(I).

Definice 8.8 Nechť I je množina LR(1) položek a X symbol gramatiky G. Funkce GOTO(I,X)je definována jako množina

UZÁVĚR({[A→ α1X · α2, a] | [A→ α1 ·Xα2, a] ∈ I})

Algoritmus 8.3 Výpočet množin LR(1) položek.

Vstup: Rozšířená gramatika G′.

Výstup: Soubor C množin LR(1) položek platných pro perspektivní prefixy gramatiky G′.

Metoda:

(1)

I0 := UZÁVĚR({[S′ → ·S, ]]})C := {I0}r := 0

(2) pro všechna Ik ∈ C, k = 0, 1, . . . , r a pro všechna X ∈ (N ∪ Σ) proveď:je-li GOTO(Ik, X) 6= ∅ ∧GOTO(Ik, X) 6∈ C pak

(a) r := r + 1(b) Ir := GOTO(Ik, X)(c) C := C ∪ {Ir}

(3) Opakuj krok (2), pokud lze k souboru C přidat novou množinu Ir.

Aplikaci algoritmu 8.3 spolu s výpočtem funkcí UZÁVĚR a GOTO nyní ukážeme na příkladě.Pro zkrácení, zápisem [A→ α1 ·α2, a1 | a2] budeme rozumět dvě LR(1) položky [A→ α1 ·α2, a1]a [A→ α1 · α2, a2].

Příklad 8.13 Uvažujme rozšířenou gramatiku s pravidly

S′ → S(1)

S → CC(2)

C → cC(3)

C → d(4)

Začneme výpočtem množiny I0 = UZÁVĚR({[S′ → ·S, ]]}). Podle definice 8.6 musíme k položce[A → α1 · Bα2, a] přidat položky [B → ·γ, b] pro každé B-pravidlo a každé b ∈ FIRST(α2a);zde je A = S′, α1 = ε, B = S, α2 = ε, a = ]. Poněvadž gramatika obsahuje jediné S-pravidlo aFIRST(]) = {]}, přidáme k I0 položku [S → ·CC, ]]. V této položce je α1 = ε, B = C,α2 = Ca poněvadž gramatika obsahuje dvě C-pravidla a FIRST(C]) = {c, d}, dostáváme v I0 tytopoložky:

I0 : S′ → ·S, ]S → ·CC, ]C → ·cC, c | dC → ·d, c | d

Page 128: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

124 0 0 1

Protože žádná z nových položek nemá nonterminál bezprostředně za tečkou, nelze již žádné dalšípoložky přidat a I0 má tedy 6 položek.

Nyní spočítáme množiny Ik = GOTO(I0, X) pro různé symboly X gramatiky.

I1 = GOTO(I0, S) = UZÁVĚR({[S′ → S·, ]]})

Tento uzávěr je triviální, a protoI1 : S′ → S·, ]

PokračujemeI2 = GOTO(I0, C) = UZÁVĚR({[S → C · C, ]]}),

tedy

I2 : S → C · C, ]C → ·cC, ]C → ·d, ]

Pro X = c jeI3 = GOTO(I0, c) = UZÁVĚR({[C → c · C, c | d]}),

tj.

I3 : C → c · C, c | dC → ·cC, c | dC → ·d, c | d

Pro X = d jeI4 = GOTO(I0, d) = UZÁVĚR({[C → d·, c | d]}),

tj.I4 : C → d·, c | d

Z funkcí GOTO(I1, X) nedostaneme žádnou novou množinu položek. Z množiny I2 však plyne

I5 = GOTO(I2, C) = UZÁVĚR({[S → CC·, ]]}),

tedyI5 : S → CC·, ]

Podobně

I6 = GOTO(I2, c) = UZÁVĚR({[C → c · C, ]]}), tj.

I6 = C → c · C, ]C → ·cC, ]C → ·d, ]

Povšimněme si rozdílu mezi množinami I3 a I6. Jednotlivé položky se liší pouze ve druhé složce.První složky, totožné s jedinými složkami LR(0) položek se u I3 a I6 shodují. Obecně, vytvoříme-li pro tutéž gramatiku množiny LR(0) položek, pak každá taková množina odpovídá jedné nebo

Page 129: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 125

více množinám LR(1) položek. Nyní dokončíme konstrukci souboru množin LR(1) položek:

I7 = GOTO(I2, d)

I7 : C → d·, ]I8 = GOTO(I3, C)

I8 : C → cC·, c | dI9 = GOTO(I6, C) = {[C → cC·, ]]}

žádné další nové množiny Ik nelze již vytvořit.

Deterministický konečný automat D, který přísluší souboru LR(1) položek, se vytváří stejnýmzpůsobem jako v případě kanonického souboru množin LR(0) položek. Jeho diagram přechodůje na obr. 8.7.

Obrázek 8.7: Diagram přechodů pro množiny LR(1) položek

Na závěr tohoto odstavce uvedeme algoritmus konstrukce kanonické LR rozkladové tabulky.

Algoritmus 8.4 Konstrukce kanonické LR(1) rozkladové tabulky.

Vstup: Rozšířená gramatika G′.

Výstup: Kanonická LR rozkladová tabulka v případě, že G je LR(1).

Metoda:

(1) Vytvoř soubor C množin LR(1) položek pro gramatiku G′. Nechť C = {I0, I1, . . . , In}.(2) Množině Ik, k = 0, 1, . . . , n odpovídá stav k analyzátoru. Funkce akcí pro stav k je

definována takto:

(a) Je-li [A→ α1 · aα2, b] ∈ Ik a GOTO(Ik, a) = Ij , pak polož AKCE[k, a] = shift j.

(b) Je-li [A → α·, a] ∈ Ik, A → α je i-té pravidlo gramatiky G′, polož AKCE[k, a] =reduce i.

Page 130: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

126 0 0 1

(c) Je-li [S′ → S·, ]] ∈ Ik, pak polož AKCE[k, ]] = accept

Jestliže v tomto bodě vznikne nejednoznačnost v definici funkce AKCE, pak vstupnígramatika není LR(1) gramatikou.

(3) Funkce přechodů pro stav k je definována takto: Je-li GOTO(Ik, A) = Ij , pakPŘECHOD[k,A] = j.

(4) Všechny položky rozkladové tabulky, které nebyly doposud definovány, mají hodnotuerror.

(5) Počáteční stav analyzátoru odpovídá množině konstruované z položky [S → ·S′, ]].

Příklad 8.14 Tab. 8.3 reprezentuje rozkladovou tabulku pro gramatiku z příkladu 8.13, získa-nou aplikací algoritmu 8.4. Používáme stejného kódování jak v tab. 8.1.

Stav Akce Přechodc d ] S C

0 s3 s4 1 21 acc2 s6 s7 53 s3 s4 84 r3 r3

5 r1

6 s6 s7 97 r3

8 r2 r2

9 r2

Tabulka 8.3: Rozkladová tabulka

Poznamenejme, že pro tuto gramatiku lze sestrojit SLR rozkladovou tabulku, jež má pouze 7stavů. Obecně každá SLR(1) gramatika je LR(1) gramatikou, nikoli však naopak.

8.3.3 Konstrukce LALR rozkladové tabulky

V tomto odstavci popíšeme metodu konstrukce LALR2 rozkladové tabulky. Tato metoda vedek výrazně menší rozkladové tabulce, než je kanonická LR tabulka a přitom většina obecných syn-taktických konstrukcí programovacích jazyků může být přirozeně LALR gramatikou popsána.I když téměř totéž platí pro SLR gramatiky, existují konstrukce (viz př. 8.11), které nelzepohodlně SLR technikou zpracovat.

Pro srovnání velikostí syntaktických analyzátorů má SLR a LALR rozkladová tabulka řádověstejný počet stavů, který dosahuje u jazyků typu Algol 60, několika stovek. Kanonická rozkladovátabulka má pro stejně rozsáhlý jazyk několik tisíců stavů. Proto je mnohem snazší a ekonomičtějšíkonstruovat SLR nebo LALR rozkladovou tabulku.

Uvažujme opět gramatiku z příkladu 8.13, jež má pravidla

S → S′(1)

S → CC(2)2LookAhead LR

Page 131: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 127

C → cC(3)

C → d(4)

spolu s jejími množinami LR(1) položkami. Vezměme dvojici „podobnýchÿ množin např. I4 aI7. Obě mají stejnou první složku položky, C → d·. Druhá složka, (lookahead), je v I4 tvořenaterminály c nebo d a v I7 pouze symbolem ].

Abychom pochopili rozdíl mezi rolí stavu I4 a I7 analyzátoru, uvažme, že G generuje jazykL(G) = {w | w = c∗dc∗d}. Při zpracování vstupního řetězce cc · · · cdcc · · · · · cd, (viz tab. 8.3),analyzátor přesouvá první skupinu symbolů c a následující symbol d do zásobníku. Po přečtenítohoto d je analyzátor ve stavu 4. Pak se požaduje redukce podle C → d, za předpokladu, ževstupním symbolem je c nebo d, tj. symbol začínající zbývající část c∗d vstupního řetězce. Je-livšak vstupním symbolem ], pak se správně hlásí chyba (např. ccd není v L(G)).

Po přečtení druhého d přejde analyzátor do stavy 7. Aby vstupní řetězec patřil do L(G), musíjiž být na vstupní pásce pouze symbol ]. Proto je správné, že ve stavu 7, při vstupu ], docházík redukci a při vstupu c nebo d k indikaci chyby.

Nahraďme nyní množiny I4 a I7 jejich sjednocením I47. Bude obsahovat tři položky: [C →d·, c | d | ]]. Funkce GOTO (viz obr. 8.6) z I0, I2, I3 a I6 pak při vstupu d nabude hodnoty I47.Takto modifikovaný analyzátor se bude chovat v podstatě stejně jako původní, s tím rozdílem,že např. při vstupu ccd nebo cdcdc provede redukci, kdežto původní analyzátor ohlásí chybu.Hlášení chyby se v modifikovaném analyzátoru oddálí do dalšího kroku.

Obecněji, v souboru množin LR(1) položek můžeme vyhledat ty množiny, které mají stej-nou množinu prvních složek položek – tzv. jádro. V příkladě 8.13 to jsou dvojice množin(I4, I7), (I3, I6) a (I8, I9) s odpovídajícími jádry {C → d·}, {C → c · C,C → ·cC,C → ·d} a{C → cC·}. Množiny se stejným jádrem sjednotíme do jediné množiny položek. Poznamenejme,že jádrem je vlastně množina LR(0) položek. Protože jádro množiny GOTO(I,X) závisí pouzena jádru množiny I, mohou být funkční hodnoty funkce GOTO pro sjednocené množiny takésjednoceny a může být tak provedena modifikace funkce GOTO. Funkce akcí je modifikovánatak, že zachovává všechny akce různé od error všech množin položek daného sjednocení.

Podívejme se nyní na problém, zda slučováním stavů analyzátoru nemohou vznikat konfliktyv definici funkce akcí. Předpokládejme, že vyjdeme z množin LR(1) položek LR(1) gramatiky,tj. z množin, které nevedou k žádným konfliktům. Předpokládejme, že ve sjednocení množin sestejným jádrem je konflikt typu shift–reduce, tj. že toto sjednocení obsahuje položku [A→ α·, a],která při vstupním symbolu a implikuje redukci a položku [B → α1 · aα2, b], která při témževstupním symbolu implikuje přesun do zásobníku. Pak některá množina LR(1) položek, jež ječástí sjednocení, obsahuje položku [A→ α·, a], a protože jádro sjednocovaných množin je stejné,také položku [B → α1 · aα2, c] pro nějaké c. To ovšem znamená, že už v původní gramaticeje konflikt typu shift–reduce a soubor množin nepřísluší, proti předpokladu, LR(1) gramatice.Ze vzniklého sporu vyvozujeme, že uvedené slučování množin LR(1) položek nezavléká žádnékonflikty typu shift–reduce v definici funkce akcí. Příklad 8.15 však ukazuje, že sloučení množinLR(1) položek se stejným jádrem mohou vzniknout konflikty typu reduce–reduce.

Příklad 8.15 uvažujme gramatiku G s pravidly

S′ → S

S → aAd | bBd | aBf | bAfA → c

B → c

Page 132: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

128 0 0 1

která generuje čtyři řetězce acd, acf, bcd a bcf . Vytvořením souboru množin LR(1) platnýchpoložek se lze přesvědčit, že G je LR(1) gramatika. Uvažujme množinu {[A→ c·, d], [B → c·, f ]},která má položky platné pro perspektivní prefix ac a množinu {[A→ c·, f ], [B → c·, d]} položekplatných pro bc. Tyto množiny mají stejné jádro a nejsou zdrojem žádných konfliktů v definicifunkce akcí. Provedeme-li však jejich sjednocení, dostaneme položky

A → c·, d | fB → c·, d | f

které jsou jasně zdrojem konfliktu, protože předepisují při vstupním symbolu d nebo f redukcipodle pravidla A→ c a zároveň podle pravidla B → c.

Nyní již přistoupíme k formulaci algoritmu konstrukce LALR rozkladové tabulky.

Algoritmus 8.5 Konstrukce LALR rozkladové tabulky.

Vstup: Rozšířená gramatika G′.

Výstup: LALR rozkladová tabulka, je-li G LALR(1) gramatika.

Metoda:

(1) Vytvoř kanonický soubor C = {I0, I1, . . . , In}LR(1) položek gramatiky G′.

(2) Pro každé jádro LR(1) položek nalezni všechny množiny LR(1) položek a proveď jejichsjednocení. Nový soubor množin LR(1) položek označme C ′ = {J0, J1, . . . , Jm}.

(3) Soubor C ′ odpovídá množině stavů LALR analyzátoru. Pro každý stav k, k =0, 1, . . . ,m je z množiny položek Jk konstruována funkce akcí AKCE[k, a], a ∈ (Σ∪{]})stejným způsobem jako podle algoritmu 8.4. Jestliže výsledná definice funkce akcínení jednoznačná, pak G není LALR(1).

(4) Nechť množina Jk vznikla sjednocením množin Ii1 , Ii2 , . . . , Iir . Pak jádra mno-žin GOTO(Ii1 , X),GOTO(Ii2 , X), . . . ,GOTO(Iir , X) jsou táž, poněvadž množinyIi1 , . . . , Iir mají stejná jádra. Nechť Jj = GOTO(Ii1 , X) ∪ . . . ∪ GOTO(Iir , X). Pakupravená funkce GOTO má hodnotu GOTO(Jk, X) = Jj a příslušná hodnota funkcepřechodů je PŘECHOD[k,X] = j.

Algoritmus 8.5 je jednoduchý. Pro praktické použití však není vhodný, poněvadž je časově aprostorově stejně náročný, jako algoritmus vytváření kanonické LR(1) tabulky. Tato skutečnostje důsledkem bodu (1) algoritmu 8.5. V [2], [3] lze nalézt efektivnější algoritmus konstrukceLALR rozkladové tabulky, který počítá LALR(1) položky (sjednocením množin LR(1) položek)přímo.

Příklad 8.16 Uvažujme opět gramatiku

S′ → S(1)

S → CC(2)

C → cC(3)

C → d(4)

Její soubor LR(1) položek je uveden v příkladě 8.13, příslušný graf funkce GOTO zobrazuje obr.8.7.

Page 133: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 129

Podle bodu (2) algoritmu 8.5 obdržíme tato, již zmíněná, sjednocení množin LR(1) položek.

I36 : C → c · C, c | d | ]C → ·cC, c | d | ]C → ·d, c | d | ]

I47 : C → d·, c | d | ]I89 : C → cC·, c | d | ]

Nový soubor má tvar C ′ = {I0, I1, I2, I36, I47, I5, I89}.

Výsledná LALR rozkladová tabulka je uvedena jako tab. 8.4. Podívejme se, jak se vytváříupravená funkce GOTO a příslušná funkce přechodů.

Stav Akce Přechodc d ] S C

0 s36 s47 1 21 acc2 s36 s47 5

36 s36 s47 8947 r3 r3 r3

5 r1

89 r2 r2 r2

Tabulka 8.4: LALR rozkladová tabulka

Uvažujme např. hodnotu GOTO(I36, C). Protože v původním souboru LR(1) položek platiloGOTO(I3, C) = I8 a GOTO(I6, C) = I9 je nyní GOTO(I36, C) = I89 a tedy PŘECHOD[36, C] =89. Podobně, z GOTO(I2, c) = I6 a I6 ⊂ I36 plyne GOTO(I2, c) = I36, a proto AKCE[2, c] =shift 36.

Je-li na vstupu věta c∗dc∗d, pak LR(1) analyzátor (tab. 8.3) i LALR(1) analyzátor (tab. 8.4)provádí přesně stejnou posloupnost přechodů a redukcí, lišící se pouze ve jménech stavů, kterýchanalyzátor nabývá (uloží-li LR analyzátor na vrchol zásobníku např. stav 3 nebo 6, pak LALRanalyzátor uloží v obou případech stav 36). Obecně, v případě syntakticky správného vstupu seLR a LALR analyzátory chovají ekvivalentně.

Jiná situace však nastává, je-li na vstupu řetězec, který nepatří do L(G). V tom případě můžeLALR analyzátor provést redukci v místě, kde kanonický LR analyzátor indikuje chybu. Je všakdůležité, že i když takový případ nastane, LALR analyzátor také ohlásí chybu, a to dříve, než bydošlo k přesunu dalšího vstupního symbolu do zásobníku. Například při vstupu ccd] kanonickýLR analyzátor (viz tab 8.3) uloží do zásobníku řetězec

0 c 3 c 3 d 4

a ve stavu 4, při vstupu ] ohlásí chybu. Na druhé straně LALR analyzátor provede odpovídajícíposloupnost přechodů a uloží do zásobníku řetězec

0 c 36 c 36 c d 47.

Protože však AKCE[47, ]] = reduce 3. změní se obsah zásobníku na

0 c 36 c 36 C 89.

Page 134: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

130 KAPITOLA 8. LR jazyky a jejich syntaktická analýza

Hodnota AKCE[89, ]] = reduce 2, proto nový obsah zásobníku bude

0 c 36 C 89.

Ještě jednou provede analyzátor tutéž redukci

0 C 2

a teprve nyní, protože AKCE[2, ]] = error , indikuje chybu.

8.4 Cvičení

Cvičení 8.4.1 Pro gramatiku G s pravidly

S → AS | bA → SA | a

(a) vypište všechny její LR(0) položky

(b) zkonstruujte nedeterministický konečný automat, jehož stavy jsou LR(0) položky, kterýpřijímá perspektivní prefixy gramatiky G

(c) vytvořte kanonický soubor LR(0) položek gramatiky G a odpovídající konečný determinis-tický automat D. Ukažte, že tento automat je ekvivalentní automatu z (b)

(d) je G SLR gramatika? Pokud ano, vytvořte SLR rozkladovou tabulku

(e) je G LALR gramatika? Je G LR(1) gramatika?

Cvičení 8.4.2 Vytvořte SLR analyzátor pro gramatiku

E → E + T | TT → TF | FF → F ∗ | (E) | a | b | ε

jež popisuje regulární výrazy nad {a, b}.

Cvičení 8.4.3 Určete, které z těchto gramatik jsou LR(1)

(a) S → AB, A→ 0A1 | ε, B → 1B | 1

(b) S → 0S1 | A, A→ 1A | 1

(c) S → S +A | A, A→ (S) | a(S) | a

Cvičení 8.4.4 Vytvořte kanonickou LR(1) rozkladovou tabulku pro tyto gramatiky:

Page 135: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

0.50 0 0 131

(a)

S → ABAC

A → aD

B → b | cC → c | dD → D0 | 0

(b) S → aSS | b

(c) S → SSa | b

Která z těchto gramatik je LALR?

Cvičení 8.4.5 Gramatika z příkladu 8.11 není SLR(1). Je LALR(1) nebo LR(1)?

Cvičení 8.4.6 Ukažte, že gramatika z příkladu 8.15 je skutečně LR(1).

Page 136: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

132 0 0 1

Page 137: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Literatura

[1] ADA Reference Manual. ACM Sigplan Notices, June 1979.

[2] A. V. Aho, J. D. Ullman. Principles of Compiler Design. Addison-Wesley PublishingCompany, 1978.

[3] A. V. Aho, J. D. Ullman. Teorija sintaksičeskovo analiza, perevoda i kompilaciji. Mir,Moskva, 1978. z angl. originálu The theory of parsing, translation and compiling, En-gelWood Cliffs, New Jersey, Prentice-Hall 1972.

[4] J. M. Foster. Automatická syntaktická analýza. ALFA, Bratislava, 1973.

[5] J. E. Hopcroft, J. D. Ullmann. Formálne jazyky a automaty. ALFA, Bratislava, 1978.z angl. originálu Formal languages and their relation to automa Addison-Wesley PublishingCompany, Reading Massachusetts 1969.

[6] K. Jensen, N. Wirth. Pascal – User Manual and Report. Springer Verlag, New York, 1974.

[7] J. Kolář. Algebra a grafy. Skriptum ES ČVUT. Praha, 1982.

[8] B. Liskov, R. Atkinson, T. Bloom, E. Moss, C. Schaffert, B. Scheifler, A. Snyder. CLUReference manual. M.I.T. Compilation Structures Group, October 1979.

[9] B. Melichar. Gramatiky automaty (skriptum ČVUT Praha). ČVUT Praha, 1978.

[10] Překladače programovacích jazyků 1978. Sborník přednášek semináře, ČSVTS při FEL aÚV ČVTS Praha, 1978.

[11] J. Rajchl. Programování v Algolu. Academia, Praha, 1971.

[12] Z. Rábová, M. Češka. Základy systémového programování I. Učební texty vysokých škol.Ediční středisko VUT Brno, 1979.

[13] Z. Rábová, M. Češka, J. Honzík, T. Hruška. Programovací techniky. Učební texty vysokýchškol. Ediční středisko VUT Brno, 1985.

133

Page 138: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

134 LITERATURA

Page 139: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

Příloha

Grafy syntaka jazyka PL0

Program

Blok

135

Page 140: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

136 LITERATURA

Příkaz

Podmínka

Výraz

Člen

Page 141: U¨EBN˝ TEXTY VYSOKÝCH 'KOL

LITERATURA 137

Činitel