Theoretische Grundlagen der Informatik – 11. Tutorium

Tagesthemen

Syntaxbäume

Gegeben eine Grammatik G = (T, V, S, P) und ein Wort w\in{}T^* sodass S \Rightarrow^* w, also w \in L(G).

Ein Syntax- oder Ableitungsbaum für w ist ein Baum, dessen

Syntaxbäume

Die Umkehrung der beiden Aussagen gilt in der Regel nicht.

Dangling Else

Zwei Interpretationen desselben C-Programms. (Einrückung hat keine syntaktische Relevanz.)

1. Interpretation

void
go_for_it(bool like_cookies_p, bool have_money_p)
{
  if (like_cookies_p)
    if (have_money_p)
      buy_cookies();
    else
      steal_cookies();
}

2. Interpretation

void
go_for_it(bool like_cookies_p, bool have_money_p)
{
  if (like_cookies_p)
    if (have_money_p)
      buy_cookies();
  else
    steal_cookies();
}

Chomsky-Normalform

Sei G = (T, V, S, P) eine kontextfreie Grammatik. G ist in Chomsky-Normalform (CNF) genau dann wenn für alle (\alpha, \beta) \in P gilt, dass

Für jede kontextfreie Grammatik G_1 = (T, V_1, S_1, P_1) existiert eine kontextfreie Grammatik G_2 = (T, V_2, S_2, P_2) in Chomsky-Normalform, sodass L(G_1) = L(G_2).

Kontextfreie Grammatik in CNF überführen

  1. Falls (S, \epsilon) \in P: Neues Startsymbol S' einführen und neue Produktion S' \to S | \epsilon hinzunehmen.

  2. Terminale a in nicht-terminierenden rechten Seiten durch neue Nichtterminale X_a ersetzen und neue Produktionen X_a \to a hinzunehmen.

  3. Wiederholen bis nicht mehr anwendbar: A \to BCD ersetzen durch A \to Y_{BC}D und neue Produktion Y_{BC} \to BC hinzunehmen.

  4. \epsilon-Produktionen A \to \epsilon (für A \neq S) streichen und für L \to AR neue Produktion L\to{}R hinzunehmen.

  5. Kettenregeln A \to B streichen und für B \to w neue Produktion A \to w hinzunehmen.

Cocke-Younger-Kasami-Algorithmus

;; Eingabe:  Grammatik G = (T, V, S, P) in CNF und Wort w \in T^* mit |w| = n
;; Ausgabe:  Aussage ob w \in L(G)

FOR i := 1, ..., n DO
    table[i][1] := \emptyset
    FOREACH (l, r) \in P DO  ;; terminierende Produktion
        IF r = w[i] THEN
            table[i][1] := table[i][1] \cup { l }
        FI
    DONE
DONE
FOR j := 2, ..., n DO
    FOR i := 1, ..., n - j DO
        table[i][j] := \emptyset
        FOR k := 1, ..., j DO
            FOREACH (l, (r_1, r_2)) \in P DO  ;; nicht-terminierende Produktionen
                IF r_1 \in table[i][k] \land r_2 \in table[i + k][j - k] THEN
                    table[i][j] := table[i][j] \cup { l }
                FI
            DONE
        DONE
    DONE
DONE
RETURN S \in table[1][n]

Valid XHTML 1.0 Strict