Obsah

Pojmy z jazyků, gramatik a automatů

Některé důležité pojmy ze státnicových otázek z EaI - předmět PJP (snad nikomu nebude vadit, že jsem to sem dal :), pokud by to vadilo, tak to smáznu )

Abecedy a jazyky

Gramatiky

Derivační stromy

napr. věta: a+a+a (pro tuto větu lze vyvořit 2 derivační stromy → tato gramatika je víceznačná) soubor: derivacnistrom.jpg

Konečný automat

(deterministický) Konečný automat (DKA, DFA) je pětice A = (Q, T, δ, q0, F), kde

Vztah mezi nimi

Regulární gramatika generuje věty regulárního jazyka, konečný automat tyto věty přijímá (rozpoznává) - je formálním modelem procedury, jejímž vstupem je posloupnost symbolů a výstupem je odpověď, zda je vstup větou daného jazyka.

Pozn:

Jazyk přijímaný DFA je množina všech slov, která po přečtení uvedou DFA z počátečního do nějakého koncového stavu. POZOR: Konečný automat skončí činnost po přečtení posledního vstupního symbolu a přijme tehdy, pokud se v tomto okamžiku nachází v koncovém stavu. Představa, že DFA skončí čtení po dosažení koncového stavu je NESPRÁVNÁ. Konečné automaty jsou schopné rozpoznat regulární jazyky.

Lexikální analyzátor je aplikací konečného automatu. Používá se jako první blok překladače, který čte vstupní text (program) a přemění jej na tok lexikálních elementů (tokens). Při tom vynechává nevýznamné mezery, konce řádků a komentáře. Jeho výstupem není boolská hodnota přijato/nepřijato, ale (většinou) hodnota typu integer nebo enum, která udává jaký lexikální element byl načten. Přikladem lexikálního elementu je číslo, identifikátor, if, =, := a pod. Základní rozdíly mezi konečným automatem (KA) a lexikálním analyzátorem (LA) jsou:

  1. KA přečte celý zadaný vstupní řetězec a na jeho konci rozhodne (svým stavem), zda řetězec patří do daného jazyku. LA přečte pouze část řetězce (tj. LA je volán pro zadaný řetězec opakovaně nějakou vyšší vrstvou překladače) a vrací jaký jeden načtený lexikální element nalezl, případně chybu, pokud nenalezl (nerozpoznal) žádný.
  2. KA končí poté, co přečte celý svůj vstup. LA naproti tomu skončí čtení vstupu, pokud již nemůže provést žádný další přechod. Pokud byl LA v okamžiku, kdy již nemohl provést následující přechod v koncovém stavu, vrací „nalezen lexikalni element xxx“ (kde xxx zaleží na tom, ve kterém z koncových stavů se LA nacházel), pokud v koncovém stavu nebyl, vrací chybu (nerozpoznaný žádný lexikální element, obvykle se to projeví chybou překladače „syntax error“ nebo „unrecognized statement“).
  3. LA přeskakuje komentáře a nevýznamné mezery.
  4. LA může provádět sémantické akce, počítat hodnoty atributů. Příkladem je lexikální element cislo, který míva atribut hodnota.
  5. LA může být spojen s preprocesorem, rozpoznávat bloky podmíněného překladu (#ifdef … #endif ) a expandovat makra.

Podobně jako KA, i LA můžeme realizovat pomocí tabulky přechodů nebo řídící struktury.

Vytvoření konečného automatu z regulární gramatiky

  1. množina stavů Q = N ∪ {K}, K ∉ N
  2. vstupní abeceda automatu M je rovna množině terminálních symbolů T gramatiky G
  3. zobrazení δ sestrojíme takto:
    1. je-li v P pravidlo A → aB, pak δ(A, a) obsahuje B
    2. je-li v P pravidlo A → a, pak δ(A, a) obsahuje K
  4. q0 = S
  5. jestliže je v P pravidlo S → ε, pak F = {S, K}, jinak F = {K}

Převod nedeterministického konečného automatu na deterministický

  1. definujeme Q' = q0, stav {q0} považujeme za neoznačený
  2. jestliže v Q' jsou již všechny stavy označeny, pokračujeme krokem 4
  3. vybereme z Q' neoznačený stav q' a provedeme tyto operace:
    1. definujeme přechodovou funkci δ'(q', a) pro všechna a ∈ T takto: δ'(q', a) = ∪δ(p, a) pro každý stav p ∈ q'
    2. přidáme do Q' každý stav δ'(q', a), který v ní ještě není, a stav q' označíme
    3. pokračujeme krokem 2
  4. počáteční stav q0' je {q0}
  5. množina koncových stavů F' je tvořena všemi stavy q', které obsahují alespoň jeden koncový stav q ∈ F