<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[12pt]{beamer}
\mode&lt;presentation&gt;

\author{Aleksej Saushev \\ \texttt{asau@inbox.ru}}
\date{Some day}
\title[Crash course]{Parsing for Impatient}

\begin{document}
\frame{\titlepage}

\begin{frame}[fragile]{Context-free grammars}
  Context-free grammar (CFG) is:
  \begin{itemize}
  \item Alphabet, set of terminal symbols, ``terminals.''
  \item Set of non-terminal symbols, ``nonterminals.''
  \item Starting symbol.
  \item Rules (productions) like:
    \begin{eqnarray*}
      S &amp; \rightarrow &amp; S_0 S_1 S_2 ... S_{n-1} \\
      S &amp; \rightarrow &amp; \_
    \end{eqnarray*}
  \end{itemize}

  Terminals and nonterminals are disjunctive.

  Recursive rules allowed.
\end{frame}

\begin{frame}[fragile]{Context-free grammars}
  Sample grammar:
  \begin{itemize}
  \item Alphabet of decimal digits and arithmetic operations ``$+$'' and ``$-$''.
  \item $E$ is the only nonterminal.
  \item $E$ is starting symbol
  \item Rules:
    \begin{eqnarray*}
      E &amp; \rightarrow &amp; 1 \\
      E &amp; \rightarrow &amp; E + E
    \end{eqnarray*}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Context-free grammars}
  CFG is ``generative''
  \begin{equation*}
    E \rightarrow E + E \rightarrow E + E + E \rightarrow E + 1 + E \rightarrow E + 1 + 1 \rightarrow 1 + 1 + 1
  \end{equation*}
  Sentences of the language are \underline{produced} from start symbol
  by rewriting strings of symbols following given rules.
\end{frame}

\begin{frame}[fragile]{Unger}
  Straightforward interpretation of grammar rule: \\
  symbols or rules matche substring of input string between given points.

  \begin{itemize}
  \item Terminal symbol matches substring of length 1
    and only if the input symbol matches.
  \item Non-terminal symbol matches,
    if there's rule for that symbol that matches.
  \item Empty rule matches empty substring.
  \item Rule $S \rightarrow S_0 S_1 S_2 ... S_{n-1}$
    matches substring of input string between points $p$ and $p'$,
    if there exist points
    $p = p_0 \leq p_1 \leq p_2 \leq ... \leq p_{n-1} \leq p_n = p'$
    such that $S_k$ matches substring between points $p_{k}$ and $p_{k+1}$,
    terminal symbols match equal terminal symbols
  \end{itemize}

  Input string matches start symbol.
\end{frame}

\begin{frame}[fragile]{Unger}
  Formally:
  \begin{itemize}
  \item $s(S, w, p, p') := t(S), p' = p + 1, w[p] \sim T$,
  \item $s(S, w, p, p') := nt(S), r(S \rightarrow S_0 ... S_{n-1}, w, p, p')$,
  \item $r(S \rightarrow \_, w, p, p') := p' = p$,
  \item 
  \begin{multline*}
      r(S \rightarrow S_0 ... S_{n-1}, w, p, p') := \\
    \begin{aligned}
      &amp; p = p_0 \leq ... \leq p_{n-1} \leq p_n = p', \\
      &amp; s(S_0, w, p_0, p_1), \\
      &amp; s(S_1, w, p_1, p_2), \\
      &amp; ... \\
      &amp; s(S_{n-1}, w, p_{n-1}, p_n).
    \end{aligned}
  \end{multline*}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Unger}
  Strings are finite:
  \begin{equation*}
    0 \leq p \leq l
  \end{equation*}

  \pause
  \begin{center}
    Brute force search.
  \end{center}
\end{frame}

\begin{frame}[fragile]{Unger}
  Left recursion:
  \begin{eqnarray*}
    S &amp; \rightarrow &amp; S S, \\
    S &amp; \rightarrow &amp; \_
  \end{eqnarray*}

  \begin{eqnarray*}
    &amp;&amp; s(S, w, 0, 0), \\
    &amp;&amp; r(S \rightarrow S S, w, 0, 0), \\
    &amp;&amp; s(S, w, 0, 0), s(S, w, 0, 0), \\
    &amp;&amp; r(S \rightarrow S S, w, 0, 0), s(S, w, 0, 0), \\
    &amp;&amp; ...
  \end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{Unger}
  Left recursion:
  \begin{eqnarray*}
    S &amp; \rightarrow &amp; S S
  \end{eqnarray*}

  \begin{eqnarray*}
    &amp;&amp; s(S, w, 0, 0), \\
    &amp;&amp; r(S \rightarrow S S, w, 0, 0), \\
    &amp;&amp; s(S, w, 0, 0), s(S, w, 0, 0), \\
    &amp;&amp; r(S \rightarrow S S, w, 0, 0), s(S, w, 0, 0), \\
    &amp;&amp; ...
  \end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{Unger}
  Reentered rule matcher with the same arguments.

  Elimination of non-producing cases.
\end{frame}

\begin{frame}[fragile]{Unger}
  Recursion elimination.

  \begin{multline*}
    \begin{aligned}
      r(S \rightarrow S_0 ... S_{n-1}, w, p, p') := \\
      {\rm (if~matching~already,~fail~immediately;} \\
      {\rm otherwise~mark~matching),}\\
      p = p_0 \leq ... \leq p_{n-1} \leq p_n = p', \\
      s(S_0, w, p_0, p_1), \\
      s(S_1, w, p_1, p_2), \\
      ... \\
      s(S_{n-1}, w, p_{n-1}, p_n).
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Unger}
  Exponential time.

  \begin{multline*}
    \begin{aligned}
      r(S \rightarrow S_0 ... S_{n-1}, w, p, p') := \\
      {\rm (if~matching~already,~fail~immediately;} \\
      {\rm otherwise~mark~matching),} \\
      {\rm (if~have~result,~return~result~immediately),} \\
      p = p_0 \leq ... \leq p_{n-1} \leq p_n = p', \\
      s(S_0, w, p_0, p_1), \\
      s(S_1, w, p_1, p_2), \\
      ... \\
      s(S_{n-1}, w, p_{n-1}, p_n), \\
      {\rm (remember~result).}
    \end{aligned}
  \end{multline*}

  No longer exponential. (Books fail to tell you that!)
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{eqnarray*}
    r'(R, w, p) &amp; := &amp; \{p' | r(R, w, p, p')\}. \\
    s'(S, w, p) &amp; := &amp; \{p' | s(S, w, p, p')\}.
  \end{eqnarray*}

  \begin{eqnarray*}
    r'(S \rightarrow S_0 ... S_{n-1}, w, p) &amp; := &amp; \{p' | r(S \rightarrow S_0 ... S_{n-1}, w, p, p')\}. \\
    s'(S, w, p) &amp; := &amp; \{p' | s(S, w, p, p')\}.
  \end{eqnarray*}

  \begin{eqnarray*}
    r(R, w, p, p') &amp; \Leftrightarrow &amp; p' \in r'(R, w, p). \\
    s(S, w, p, p') &amp; \Leftrightarrow &amp; p' \in s'(S, w, p).
  \end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    r'(S \rightarrow \_, w, p) = \{p' | r(S \rightarrow _, w, p, p')\} = \{p' | p' = p\} = \{p\}.
  \end{equation*}

  \begin{multline*}
    s'(T, w, p)
    = \{p' | s(T, w, p, p')\} \\
    = \{p' | p' = p + 1, w[p] \sim T\} \\
    = \{p+1 | w[p] \sim T\}.
  \end{multline*}

  \begin{eqnarray*}
    s'(T, w, p) &amp; = &amp; \{p+1\},\quad {\rm when~} w[p] \sim T. \\
    s'(T, w, p) &amp; = &amp; \{\}, \quad {\rm otherwise}.
  \end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    s'(S, w, p) = \{p' | s(S, w, p, p')\} \\
    = \{p' | R = S \rightarrow S_0 ... S_{n-1}, r(R, w, p, p')\} \\
    = \{p' | R = S \rightarrow S_0 ... S_{n-1}, p' \in r'(R, w, p)\} \\
    = \bigcup \{r'(R, w, p) | R = S \rightarrow S_0 ... S_{n-1}\}.
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    r'(S \rightarrow S_0 ... S_{n-1}, w, p)
    = \{p' | r(S \rightarrow S_0 ... S_{n-1}, w, p, p')\}
  \end{equation*}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p' | &amp; p = p_0 \leq ... \leq p_{n-1} \leq p_n = p', &amp; \\
               &amp; s(S_0, w, p_0, p_1), &amp; \\
               &amp; s(S_1, w, p_1, p_2), &amp; \\
               &amp; ... &amp; \\
               &amp; s(S_{n-1}, w, p_{n-1}, p_n)\} &amp; \\
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p' | &amp; p = p_0 \leq ... \leq p_{n-1} \leq p_n = p', \\
               &amp; s(S_0, w, p_0, p_1), \\
               &amp; s(S_1, w, p_1, p_2), \\
               &amp; ... \\
               &amp; s(S_{n-1}, w, p_{n-1}, p_n)\} \\
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p' | &amp; p_0 = p, p' = p_n, \\
               &amp; p_1 \in s'(S_0, w, p_0), \\
               &amp; p_2 \in s'(S_1, w, p_1), \\
               &amp; ... \\
               &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p' | &amp; p_0 = p, p' = p_n, \\
               &amp; p_1 \in s'(S_0, w, p_0), \\
               &amp; p_2 \in s'(S_1, w, p_1), \\
               &amp; ... \\
               &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_1 \in s'(S_0, w, p), \\
                &amp; p_2 \in s'(S_1, w, p_1), \\
                &amp; ... \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_1 \in s'(S_0, w, p), \\
                &amp; p_2 \in s'(S_1, w, p_1), \\
                &amp; ... \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_{n-1} \in \{p_{n-1} | &amp; p_1 \in s'(S_0, w, p), &amp; \\
                                      &amp; &amp; p_2 \in s'(S_1, w, p_1), &amp; \\
                                      &amp; &amp; ... &amp; \\
                                      &amp; &amp; p_{n-1} \in s'(S_{n-2}, w, p_{n-2})\}, &amp; \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\} &amp;
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_{n-1} \in \{p_{n-1} | &amp; p_1 \in s'(S_0, w, p), &amp; \\
                                      &amp; &amp; p_2 \in s'(S_1, w, p_1), &amp; \\
                                      &amp; &amp; ... &amp; \\
                                      &amp; &amp; p_{n-1} \in s'(S_{n-2}, w, p_{n-2})\}, &amp; \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\} &amp;
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_{n-1} \in r'(S \rightarrow S_0 ... S_{n-2}, w, p) \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    \{y | x \in X, y \in f(x)\} = \bigcup \{f(x) | x \in X\} = u(m(f, X)),
  \end{equation*}
  where $m(f, X)$ is pointwise map of set X (``map''),
  $u(Y)$ is union of set of sets.
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    \{y | x \in X, y \in f(x)\} = \bigcup \{f(x) | x \in X\} = u(m(f, X)),
  \end{equation*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
      = \{p_n | &amp; p_{n-1} \in r'(S \rightarrow S_0 ... S_{n-2}, w, p) \\
                &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\} &amp;
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p)
      = u(m(&amp;(p \mapsto s'(S_{n-1}, w, p)), \\
            &amp;r'(S \rightarrow S_0 ... S_{n-2}, w, p)
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{multline*}
    \begin{aligned}
      r'(S \rightarrow S_0 ... S_{n-1}, w, p)
      = u(m(&amp;(p \mapsto s'(S_{n-1}, w, p)), \\
            &amp;r'(S \rightarrow S_0 ... S_{n-2}, w, p)
    \end{aligned}
  \end{multline*}
%
  \begin{multline*}
    r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
    \begin{aligned}
      = u(m(&amp;(p \mapsto s'(S_{n-1}, w, p)), \\
            &amp;u(m(&amp;(p \mapsto s'(S_{n-2}, w, p)), \\
            r'(S \rightarrow S_0 ... S_{n-2}, w, p)
    \end{aligned}
  \end{multline*}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = {p_n | p_1 &lt;- s'(S_0, w, p),
          p_2 &lt;- s'(S_1, w, p_1),
          ...
          p_{n-1} &lt;- s'(S_{n-1}, w, p_{n-2}),
          p_n &lt;- s'(S_{n-1}, w, p_{n-1})}
 = {p_n | p_{n-1} &lt;- {p_{n-1} | p_1 &lt;- s'(S_0, w, p),
                                p_2 &lt;- s'(S_1, w, p_1),
                                ...
                                p_{n-1} &lt;- s'(S_{n-1}, w, p_{n-2})},
          p_n &lt;- s'(S_{n-1}, w, p_{n-1})}
 = {p_n | p_{n-1} &lt;- r'(S -&gt; S_0 ... S_{n-2}, w, p),
          p_n &lt;- s'(S_{n-1}, w, p_{n-1})}
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = {p_n | p_{n-1} &lt;- r'(S -&gt; S_0 ... S_{n-2}, w, p),
          p_n &lt;- s'(S_{n-1}, w, p_{n-1})}
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
        r'(S -&gt; S_0 ... S_{n-2}, w, p)))
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
        u(m((p +-&gt; s'(S_{n-2}, w, p)),
             r'(S -&gt; S_0 ... S_{n-3}, w, p)))))
 = ...
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
        u(m((p +-&gt; s'(S_{n-2}, w, p)),
             ...
             u(m((p +-&gt; s'(S_1, w, p)),
                  r'(S -&gt; S_0, w, p)))))))
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
        u(m((p +-&gt; s'(S_{n-2}, w, p)),
             ...
             u(m((p +-&gt; s'(S_1, w, p)),
                  r'(S -&gt; S_0, w, p)))))))
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
        u(m((p +-&gt; s'(S_{n-2}, w, p)),
             ...
             u(m((p +-&gt; s'(S_1, w, p)),
                  s'(S_0, w, p)))))))
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
       u(m((p +-&gt; s'(S_{n-2}, w, p)),
           ...
           u(m((p +-&gt; s'(S_1, w, p)),
               s'(S_0, w, p)))))))
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    \{f(x)\} = u(\{\{f(x)\}\}) = u(m(f, \{x\})).
  \end{equation*}

\begin{verbatim}
{f(x)} = u({{f(x)}}) = u(m(f, {x})).

r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
       u(m((p +-&gt; s'(S_{n-2}, w, p)),
           ...
           u(m((p +-&gt; s'(S_1, w, p)),
               s'(S_0, w, p)))))))
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
       u(m((p +-&gt; s'(S_{n-2}, w, p)),
           ...
           u(m((p +-&gt; s'(S_1, w, p)),
               u(m((p +-&gt; s'(S_0, w, p)), {p})))))))).
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
\begin{verbatim}
r'(S -&gt; S_0 ... S_{n-1}, w, p)
 = u(m((p +-&gt; s'(S_{n-1}, w, p)),
       u(m((p +-&gt; s'(S_{n-2}, w, p)),
           ...
           u(m((p +-&gt; s'(S_1, w, p)),
               u(m((p +-&gt; s'(S_0, w, p)), {p})))))))).
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{Combinators}
  \begin{equation*}
    z_i(x) := u(m((p \mapsto s'(S_i, w, p)), x))
  \end{equation*}
  
  \begin{equation*}
    r'(S \rightarrow S_0 ... S_{n-1}, w, p) = (z_{n-1} \circ ... \circ z_0)({p}).
  \end{equation*}
\end{frame}

%% \begin{frame}[fragile]{Combinators}
%%   \begin{multline*}
%%     r'(S \rightarrow S_0 ... S_{n-1}, w, p) \\
%% %
%%     = \{p_n | p_1 \in s'(S_0, w, p), \\
%%               p_2 \in s'(S_1, w, p_1), \\
%%               ... \\
%%               p_n \in s'(S_{n-1}, w, p_{n-1})\}
%% %
%%     = 
%%     \begin{aligned}
%%       \{p_n | &amp; p_1 \in s'(S_0, w, p), \\
%%               &amp; p_2 \in s'(S_1, w, p_1), \\
%%               &amp; ... \\
%%               &amp; p_n \in s'(S_{n-1}, w, p_{n-1})\}
%%     \end{aligned}
%% %
%%     = u(m((p \mapsto s'(S_{n-1}, w, p)),
%%           \{p_{n-1} | p_1 \in s'(S_0, w, p),
%%                      p_2 \in s'(S_1, w, p_1)
%%                      ...
%%                      p_{n-1} \in s'(S_{n-2}, w, p_{n-2})\}))
%% %
%%     = u(m((p \mapsto s'(S_{n-1}, w, p)),
%%           \{p_{n-1} | p_1 \in s'(S_0, w, p),
%%                      p_2 \in s'(S_1, w, p_1)
%%                      ...
%%                      p_{n-1} \in s'(S_{n-2}, w, p_{n-2})\}))
%% %
%%  = u(m((p \mapsto s'(S_{n-1}, w, p)), \\
%%        u(m((p \mapsto s'(S_{n-2}, w, p)), \\
%%            ... \\
%%            u(m((p \mapsto s'(S_1, w, p)), \\
%%                s'(S_0, w, p))))))) \\
%%   \end{multline*}
%% \end{frame}

\begin{frame}[fragile]{Combinators}
  Rule: $S \rightarrow S_0 ... S_{n-1}$. \\
  Recognizer: $r'' = s''_0 * ... * s''_{n-1}$. \\
  Recognizer for symbols combines all respective rules: \\
  $s = r''_0 + ... + r''_{m-1}.$
\end{frame}

\begin{frame}[fragile]{Combinators}
  If mapping symbols to sets of symbols:
  \begin{eqnarray*}
    (s''_A * s''_B)(p) = u(m(s''_B, s''_A(p))) = u(m(s''_B, u(m(s''_A, \{p\})))). \\
    (r''_1 + r''_2)(p) = u(\{r''_1(p), r''_2(p)\}) = r''_A(p) \cup r''_B(p).
  \end{eqnarray*}

  If mapping sets of symbols to sets of symbols:
  \begin{eqnarray*}
    (s''_A * s''_B)(P) = u(m(s''_B, u(m(s''_A, P)))). \\
    (r''_1 + r''_2)(P) = u(\{r''_1(p), r''_2(p)\}) = m(r''_1, P) \cup m(r''_2, P).
  \end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{Monads}
  $\{p\}$ is ``unit'', $m$ is ``map'', $u$ is ``union''.

  Haskell does it alternatively:
  \begin{equation*}
    (x &gt;&gt;= f) = u(m(f, x))
  \end{equation*}
\end{frame}

\begin{frame}[fragile]{LL(1)}
  Predicting the rule using lookahead information.

  \pause
  LL(0) is either empty or single sentence.

  \pause
  LL(1)
\end{frame}

\begin{frame}[fragile]{LL(1)}
\begin{equation*}
s'(S, w, p) := r'(R, w, p), \quad {\rm where~} R = c(S, w[p]).
\end{equation*}

\begin{verbatim}
S -&gt; S_0 ... S_{n-1}
...
S' -&gt; ... S S{k+1} ... S_{m-1}
\end{verbatim}
\end{frame}

\begin{frame}[fragile]{LL(1)}
\begin{verbatim}
S -&gt; S_0 ... S_{n-1}
...
S' -&gt; ... S S{k+1} ... S_{m-1}
\end{verbatim}

%% \begin{equation*}
%%   w[p] \in {\rm FIRST}(S_0 ... S_{n-1}) \vee ({\rm NULLABLE}(S_0 ... S_{n-1}) \wedge w[p] \in {\rm FOLLOW}(S'))
%% \end{equation*}
\begin{equation*}
  w[p] \in {\rm FIRST}(S_0 ... S_{n-1})
\end{equation*}
\begin{equation*}
  {\rm NULLABLE}(S_0 ... S_{n-1}) \wedge w[p] \in {\rm FOLLOW}(S')
\end{equation*}
\end{frame}

\begin{frame}[fragile]{``Nullable''}
\begin{eqnarray*}
  {\rm NULLABLE}(\_) \\
  {\rm NULLABLE}(S_0 ... S_{n-1}) \Leftrightarrow \forall i {\rm NULLABLE}(S_i) \\
  {\rm NULLABLE}(R) \Leftrightarrow {\rm NULLABLE}({\rm rhs}(R)) \\
  {\rm NULLABLE}(S) \Leftrightarrow \exists R (R = S \rightarrow ...) \Rightarrow {\rm NULLABLE}(R)
\end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{``First''}
\begin{eqnarray*}
  {\rm FIRST}(\_) = \{\} \\
  {\rm FIRST}(S_0 ... S_{n-1}) \Leftrightarrow ... \\
  {\rm FIRST}(S) \Leftrightarrow \bigcup {\rm FIRST}({\rm rhs}(R)) \\
\end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{``Follow''}
\begin{eqnarray*}
  {\rm FOLLOW}(S) = \bigcup_R ({\rm FIRST}(S_{k+1} ... S_{m-1}) \cup {\rm FOLLOW}({\rm lhs}(R))
\end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{``Predict''}
\begin{eqnarray*}
  {\rm PREDICT}(R) &amp; = &amp; {\rm FIRST}(R) \cup {\rm FOLLOW}({\rm lhs}(R)), \quad {\rm when~} {\rm NULLABLE}(R) \\
  {\rm PREDICT}(R) &amp; = &amp; {\rm FIRST}(R), \quad {\rm otherwise}
\end{eqnarray*}
\end{frame}

\begin{frame}[fragile]{LL(1)}
  At input string termination we choose ${\rm NULLABLE}$ rules.
\end{frame}
\end{document}
</pre></body></html>