Uživatelské nástroje

Nástroje pro tento web


pitel:msz:bezkontextove_gramatiky

Transformace a normální formy bezkontextových gramatik

Derivace a derivační stromy

Gramatika (N, Σ, P, S)

    • Uzly jsou prvky z NΣ
    • Kořen stromu je S
    • Uzly označené prvky z Σ jsou koncové uzly stromu
    • Hrany odpovídají přepisovacím pravidlům gramatiky P
    • Označení koncových uzlů zleva doprava tvoří větnou formu
    • Každé derivaci přísluší jeden derivační strom, ale jednomu stromu může příslušet více derivací (více způsobů jak sestavit stejný strom).
  • Levá/pravá derivace
    • Při sestavování je vždy přepsán nejlevější/nejpravější nonterminál
  • Fráze větné formy
    • Řada symbolů na koncových uzlech některého podstromu derivačního stromu (řada symbolů, které lze získat derivacemi z jednoho nonterminálu)
    • β je frází větné formy pokud S* αAγA ⇒⁺ β
  • Jednoduchá fráze větné formy
    • Řada sybmolů na koncových uzlech jednopatrového podstormu derivačního stromu
    • β je jednoduchou frází větné formy pokud S* αAγAβ
  • Nejlevější jednoduchá fráze (l-fráze)
    • Fráze větné formy, která se nachází nejvíce vlevo
  • Víceznačnost
    • Věta je víceznačná pokud existuje více derivačních stromů tvořících tuto větu
    • Existují jazyky, které nelze generovat bez víceznačnosti
    • Gramatika, která obsahuje cykly je vždy víceznačná
  • ε-pravidlo
    • Aε (přepisují nonterminál na prázdný řetezec)
  • A-pravidla
    • Všechna pravidla, která mají A na levé straně
  • Jednoduchá pravidlo
    • AB (přepisují nonterminál na jiný nonterminál)
  • Zbytečné symboly
    • Nedostupné symboly (nelze jich dosáhnout žádným přepisem) a symboly negenerující terminální řetězce (nikdy nevytvoří větnou formu)
  • Cyklus
    • A →⁺ A
  • Vlastní gramatika
    • Gramatika bez zbytečných symbolů, bez cyklů a bez ε-pravidel
  • Rekurzivní pravidla
    • Rekurzivní zleva: A
    • Rekurzivní zprava: AαA
    • Rekurzivní: AαAβ
    • Každý bezkontextový jazyk lze generovat gramatikou bez levé rekurze
    • Všechna pravidla s levou rekurzí lze nahradit pravidly s pravou rekurzí

Transformace

Odstranění nedostupných symbolů

Převod gramatiky (N, Σ, P, S) na gramatiku bez nedostupných stavů (N′, Σ′, P′, S)

  1. Najdeme všechny dostupné terminály a nonterminály
    1. i = 0
    2. V₀ = {S} (tj. v nultém kroku je dostupný pouze počáteční stav)
    3. repeat
      1. Vᵢ₊₁ = Vᵢ ∪ {X | AαXβPAVᵢ} (tj. do množiny dostupných přidáme všechny terminály a nonterminály, kterlé lze získat přepisem z některého nonterminálu z množiny dostupných z předchozího kroku)
      2. i++ (tj. přejdeme k dalšímu kroku)
    4. until Vᵢ₊₁ = Vᵢ₋₁ (tj. končíme pokud se nám v posledním kroku množina dostupných nezměnila)
  2. Novou gramatiku sestavíme jako:
    • N′ = VᵢN (tj. použijeme pouze dosažitelené nonterminály)
    • Σ′ = VᵢΣ (tj. použijeme pouze dosažitelené terminály)
    • P′ ⊂ P obsahuje pouze pravidla používající pouze symboly z Vᵢ

Odstranění zbytečných symbolů

Převod gramatiky (N, Σ, P, S) na gramatiku bez nedostupných stavů (N′, Σ, P′, S)

  1. Nalezení nonterminálů, které produkují terminální řetězce
    1. i = 0
    2. N₀ = ∅ (tj. v nultém kroku začínáme s prázdnou množinou nonterminálů generujících terminální řetězce)
    3. repeat
      1. Nᵢ₊₁ = Nᵢ ∪ {A | AαP ∧ α ∈ (NᵢΣ)*} (tj. do množiny všechny terminály, které lze přepsat na řetězce skladádající se pouze z terminálů nebo nonterminálů, které jsou již v množině nonterminálů generujících terminální řetězce)
      2. i++ (tj. přejdeme k dalšímu kroku)
    4. until Nᵢ₊₁ = Nᵢ₋₁ (tj. končíme pokud se nám v posledním kroku množina nezměnila)
  2. Vytvoříme gramatiku bez nonterminálů, které neprodukují terminální řetězce:
    • N′ = Nᵢ
    • P′ ⊂ P obsahuje pouze pravidla používající pouze symboly z Nᵢ
  3. Odstraníme nedostupné symboly z gramatiky

Odstranění ε-pravidel

Převod gramatiky (N, Σ, P, S) na gramatiku bez ε-pravidel (N′, Σ′, P′, S′)

  1. Sestavení množiny nonterminálů, které mohou generovat ε Nε
    • Postup je obdobný jako krok 1 algoritmu odstranění zbytečných symbolů pouze Nᵢ₊₁ = Nᵢ ∪ {A | AαPα ∈ (Nᵢ ∪ {ε})*}, Nε = Nᵢ
  2. Sestavíme novou množinu přepisovacích pravidel P
    • Jestliže AαBα₁…BₖαₖP, k ≥ 0 a všechna Bᵢ jsou v Nε a žádný symbol αᵢ není v Nε pak k P′ přidej všechny prvidla tvaru AαXαX₂…Xₖαₖ kde Xᵢ je buď Bᵢ nebo ε. Nepřidává se pravidlo A → ε.
    • Tj. od každého pravidla sestavíme všechny možné kombinace, kde jsou jednotlivé částí přepsatelné na ε vynechány
  3. Zavedeme nový počáteční nonterminál S
  4. Jestliže je S v Nε pak přidáme do P′ pravidla S′ → ε a S′ → S

Odstranění jednoduchých pravidel

Převod gramatiky bez ε-pravidel (N, Σ, P, S) na gramatiku bez jednoduchých pravidel (N, Σ, P′, S)

  1. Pro každé AN sestrojíme množinu NA = {B | A* B}
    1. i = 0
    2. N₀ = {A}
    3. repeat
      1. Nᵢ₊₁ = Nᵢ ∪ {C | BCPBNᵢ}
      2. i++
    4. until Nᵢ = Nᵢ₋₁ (tj. končíme pokud se nám v posledním kroku množina nezměnila)
    5. NA = Nᵢ
  2. Sestavíme novou množinu P
    • Pro všechna nejednoduchá pravidla Bα přidáme do P′ pravidla Aα pro všechna A pro něž platí BNA, tj. pro každého nejednoduché pravidlo najdeme všechny nonterminály A, které jdou jednoduchými pravidly přepsat na B, a vytvoříme všechny varianty pravidla, kde levou stranu nahradíme za A.

Odstranění levé rekurze

Převod vlastní gramatiky (N, Σ, P, S) na gramatiku bez levé rekurze (N′, Σ, P′, S).

Nonterminály vyjádříme jako N = {A₁, A₂, …, Aₙ} tj. zvolíme pořadí jednotlivých nonterminálů.

Gramatiku budeme transformovat tak, že je-li Aᵢα pravidlo pak α začíná buď terminálem nebo nonterminálem Aj, který je v pořadí až za Aᵢ (j > i).

  1. i = 1 (tj. začneme prvním nonterminálem v pořadí)
  2. Vezmeme všechna Aᵢ-pravidla, která jsou buď ve tvaru AᵢAᵢαₓ nebo Aᵢβₓ, kde β nezačíná nonterminálem, který je v pořadí před Aᵢ
    1. Přidáme nový nonterminál Aᵢ′ do N
    2. Všechna Aᵢ-pravidla nahradíme za:
      • Aᵢβ₁ | β₂ | … | βₓ (tj. přepisy na β zachováme)
      • AᵢβAᵢ′ | βAᵢ′ | … | βₓAᵢ′ (tj. pro všechny přepisy na β vytvoříme pravidla s vpravo přidaným Aᵢ′)
      • Aᵢ′ → α₁ | α₂ | … | αₓ (tj. u přepisů na Aᵢα vytvoříme pravidla pouze s α)
      • Aᵢ′ → αAᵢ′ | αAᵢ′ | … | αₓAᵢ′ (tj. u přepisů na Aᵢα vytvoříme pravidla s odstraněným Aᵢ a vpravo přidaným Aᵢ
      • Tím dosáhneme toho, že všechna Aᵢ-pravidla začínají buď terminálem nebo nonterminálem, který je v pořadí až za Aᵢ)
  3. Pokud jsme již prošli všechny nontermínály (i = n) končíme
  4. i++
  5. Pro všechny dosud procházené nonterminály Aj (1 < j < i)
    1. Pravidlo AᵢAjα odstraníme
    2. Pro každé Aj-pravidlo (Ajβ) vytvoříme Aᵢβα, tj. vezmeme všechna Aᵢ-pravidla, jejichž pravá strana začíná nonterminálem Aj, který je v pořadí před Aᵢ, a nahradíme je za pravidla ve kterých je Aj nahrazeno všemi řetězci na které jej lze přepsat.
  6. Jdeme na krok 2

Normální formy

Chomského normální forma (CNF)

Chomsky normal form

Přepisovací pravidla jsou pouze ve tvaru:

  • ABC
  • Aa
  • Případně Sε pokud εL(G) a S nesmí být na pravé straně žádného přepisovacího pravidla.

Převod vlastní gramatiky bez jednoduchých pravidel (N, Σ, P, S) na gramatiku v CNF (N′, Σ, P′, S′)

  1. Množina P′ obsahuje všechny pravidla z P ve tvaru ABC a Aa, případně Sε.
  2. Každé pravidlo tvaru AXX₂…Xₖ (k > 2) přepíšeme do P′ jako sérii pravidel:
    1. AXX₂′
    2. X₂′ → XX₃′
    3. Xₖ₋₁′ → Xₖ₋₁Xₖ
  3. Zavedeme nové non-terminální symboly AX₂′…Xₖ₋₁′ (tj. pravidla mající pravou stranu delší než dva prvky rozdělíme na navazující sérii pravidel majících napravo jen dva prvky)
  4. Ve všech pravidlech v P′ které nejsou ve tvaru Aa, kde se vyskytují na pravé straně terminály, nahradíme tyto terminály a za nové non-terminály A′ a přidáme pravidlo A′ → a (tj. nepovolená pravidla s terminály na pravé straně upravíme tak, že terminál nahradíme nonterminálem, který se přepisuje na původní terminál)

Greibachové normální forma (GNF)

Greibach normal form

  • Nejsou žádná ε pravidla
  • Přepisovací pravidla ve tvaru A kde N*
  • Případně Sε pokud εL(G) a S nesmí být na pravé straně žádného přepisovacího pravidla

Převod vlastní gramatiky bez levé rekurze (N, Σ, P, S) na gramatiku v GNF (N′, Σ, P′, S′):

  1. Seřadíme všechny nonterminály tak, aby pravá strana žádného přepisovacího pravidla nezačínala nonterminálem, který je v pořadí před přepisovaným nonterminálem. (v podstatě stejná pořadí v jakém máme nonterminály během algoritmu odstranění levé rekurze): N = {A₁, A₂, …, Aₙ}
  2. Postupně pro všechny nonterminály Aᵢ od Aₙ₋₁ sestupně po A₁:
    1. Pro každé pravidlo AᵢAjα:
      1. Odstraň toto pravidlo
      2. Pro všechna Aj-pravidla (Ajαβ) vytvoř nová pravidla ve tvaru Aᵢβα (tj. všechna pravidla jejichž pravé strana začíná nonterminálem rozepíšeme tento nonterminál na všechny možnosti na jaké jej lze přepsat)
    2. Po dokončení tohoto kroku všechny pravidla mají pravou stranu začínající terminálem.
    3. Ve všech pravidlech v P′ ve kterých se na pravé straně vyskytují terminály na jiné než první pozici nahradíme tyto terminály a za nové non-terminály A′ a přidáme pravidlo A′ → a (tj. nepovolená pravidla s terminály na pravé straně upravíme tak, že terminál nahradíme nonterminálem, který se přepisuje na původní terminál)
/var/www/wiki/data/pages/pitel/msz/bezkontextove_gramatiky.txt · Poslední úprava: 30. 12. 2022, 13.43:01 autor: 127.0.0.1