follow ( c , ∅ ) = ∅ follow ( c , ϵ ) = ∅ follow ( c , a ) = ∅ follow ( c , r 1 r 2 ) = { follow ( c , r 1 ) ∪ follow ( c , r 2 ) ∪ first ( r 2 ) if c ∈ last ( r 1 ) follow ( c , r 1 ) ∪ follow ( c , r 2 ) otherwise follow ( c , r 1 ∣ r 2 ) = follow ( c , r 1 ) ∪ follow ( c , r 2 ) follow ( c , r ∗ ) = { follow ( c , r ) ∪ first ( r ) if c ∈ last ( r ) follow ( c , r ) otherwise \begin{align*}
\text{follow}(c, \emptyset) &= \emptyset \\
\text{follow}(c, \epsilon) &= \emptyset \\
\text{follow}(c, a) &= \emptyset \\
\text{follow}(c, r_1 r_2) &=
\begin{cases}
\text{follow}(c, r_1) \cup \text{follow}(c, r_2) \cup \text{first}(r_2) & \text{if } c \in \text{last}(r_1) \\
\text{follow}(c, r_1) \cup \text{follow}(c, r_2) & \text{otherwise}
\end{cases} \\
\text{follow}(c, r_1 \mid r_2) &= \text{follow}(c, r_1) \cup \text{follow}(c, r_2) \\
\text{follow}(c, r*) &=
\begin{cases}
\text{follow}(c, r) \cup \text{first}(r) & \text{if } c \in \text{last}(r) \\
\text{follow}(c, r) & \text{otherwise}
\end{cases}
\end{align*}
follow ( c , ∅ ) follow ( c , ϵ ) follow ( c , a ) follow ( c , r 1 r 2 ) follow ( c , r 1 ∣ r 2 ) follow ( c , r ∗ ) = ∅ = ∅ = ∅ = { follow ( c , r 1 ) ∪ follow ( c , r 2 ) ∪ first ( r 2 ) follow ( c , r 1 ) ∪ follow ( c , r 2 ) if c ∈ last ( r 1 ) otherwise = follow ( c , r 1 ) ∪ follow ( c , r 2 ) = { follow ( c , r ) ∪ first ( r ) follow ( c , r ) if c ∈ last ( r ) otherwise
first ( ∅ ) = ∅ first ( ϵ ) = ∅ first ( a ) = { a } first ( r 1 r 2 ) = { first ( r 1 ) ∪ first ( r 2 ) if null ( r 1 ) first ( r 1 ) otherwise first ( r 1 ∣ r 2 ) = first ( r 1 ) ∪ first ( r 2 ) first ( r ∗ ) = first ( r ) \begin{align*}
\text{first}(\emptyset) &= \emptyset \\
\text{first}(\epsilon) &= \emptyset \\
\text{first}(a) &= \{a\} \\
\text{first}(r_1 r_2) &=
\begin{cases}
\text{first}(r_1) \cup \text{first}(r_2) & \text{if } \text{null}(r_1) \\
\text{first}(r_1) & \text{otherwise}
\end{cases} \\
\text{first}(r_1 \mid r_2) &= \text{first}(r_1) \cup \text{first}(r_2) \\
\text{first}(r^*) &= \text{first}(r)
\end{align*}
first ( ∅ ) first ( ϵ ) first ( a ) first ( r 1 r 2 ) first ( r 1 ∣ r 2 ) first ( r ∗ ) = ∅ = ∅ = { a } = { first ( r 1 ) ∪ first ( r 2 ) first ( r 1 ) if null ( r 1 ) otherwise = first ( r 1 ) ∪ first ( r 2 ) = first ( r )
null ( ∅ ) = false null ( ϵ ) = true null ( a ) = false null ( r 1 r 2 ) = null ( r 1 ) ∧ null ( r 2 ) null ( r 1 ∣ r 2 ) = null ( r 1 ) ∨ null ( r 2 ) null ( r ∗ ) = true \begin{align*}
\text{null}(\emptyset) &= \text{false} \\
\text{null}(\epsilon) &= \text{true} \\
\text{null}(a) &= \text{false} \\
\text{null}(r_1 r_2) &= \text{null}(r_1) \land \text{null}(r_2) \\
\text{null}(r_1 \mid r_2) &= \text{null}(r_1) \lor \text{null}(r_2) \\
\text{null}(r^*) &= \text{true}
\end{align*}
null ( ∅ ) null ( ϵ ) null ( a ) null ( r 1 r 2 ) null ( r 1 ∣ r 2 ) null ( r ∗ ) = false = true = false = null ( r 1 ) ∧ null ( r 2 ) = null ( r 1 ) ∨ null ( r 2 ) = true
N = is finite set of non-terminal symbols T = is finite set of terminal symbols S ∈ N = is the start symbol (the axiom) R ⊆ N × ( N ∪ T ) = is a finite set of production rules \begin{align*}
N &= \text{ is finite set of non-terminal symbols}\\
T &= \text{ is finite set of terminal symbols}\\
S \in N & =\text{ is the start symbol (the axiom)}\\
R \subseteq N \times (N \cup T) &= \text{ is a finite set of production rules}\\
\end{align*}\\ N T S ∈ N R ⊆ N × ( N ∪ T ) = is finite set of non-terminal symbols = is finite set of terminal symbols = is the start symbol (the axiom) = is a finite set of production rules
example
N = { E } T = { + , ∗ , ( , ) , i n t } S = E R = { ( E , E + E ) , ( E , E ∗ E ) , ( E , ( E ) ) , ( E , i n t ) } \begin{align*}
N&=\{E\}\\
T&=\{+,*,(,),int\}\\
S&=E\\
R&=\{(E,E+E), (E,E*E), (E,(E)), (E,int) \}\\
\end{align*}\\ N T S R = { E } = { + , ∗ , ( , ) , in t } = E = {( E , E + E ) , ( E , E ∗ E ) , ( E , ( E )) , ( E , in t )}
look like this
E → E + E ∣ E ∗ E ∣ ( E ) ∣ i n t \begin{align*}
E \rightarrow & E+E \\
\ | \ & E*E \\
\ | \ &(E) \\
\ | \ & int \\
\end{align*}\\ E → ∣ ∣ ∣ E + E E ∗ E ( E ) in t
u ∈ { ( N ∪ T ) ∗ } v ∈ { ( N ∪ T ) ∗ } X ∈ N β ∈ R \begin{align*}
u&\in \{(N\cup T)^* \}\\
v&\in \{(N\cup T)^* \}\\
X&\in N\\
\beta &\in R \\
\end{align*}\\ u v X β ∈ {( N ∪ T ) ∗ } ∈ {( N ∪ T ) ∗ } ∈ N ∈ R
u = u 1 X u 2 v = u 1 β u 2 \begin{align*}
u&=u_1 X u_2\\
v&=u_1 \beta u_2\\
\end{align*}\\ u v = u 1 X u 2 = u 1 β u 2
E ∗ ( ⏟ u 1 E ⏟ X ) ⏟ u 2 → E ∗ ( E + E ⏟ β ) \begin{align*}
&\underbrace{E* ( \ }_{u_1} &&\underbrace{E}_{X} &\underbrace{ \ )}_{u_2} &\rightarrow E*( && \underbrace{ E+E }_{\beta} &&)
\end{align*}\\ u 1 E ∗ ( X E u 2 ) → E ∗ ( β E + E )
The language defined by a context-free grammar G = ( N , T , S , R ) G = (N, T , S, R) G = ( N , T , S , R )
int ∗ ( int + int ) ∈ L ( G ) \text{int} * ( \text{int} + \text{int} ) ∈ L(G) int ∗ ( int + int ) ∈ L ( G )
give int + int * int
E → E + E → int + E → int + E ∗ E → int + int ∗ E → int + int ∗ int \begin{align*}
E & \rightarrow E+E\\
& \rightarrow \text{int}+E\\
& \rightarrow \text{int}+E*E\\
& \rightarrow \text{int}+\text{int}*E\\
& \rightarrow \text{int}+\text{int}*\text{int}\\
\end{align*}\\ E → E + E → int + E → int + E ∗ E → int + int ∗ E → int + int ∗ int
E → E + E → E + E ∗ E → E + E ∗ int → E + int ∗ int → int + int ∗ int \begin{align*}
E & \rightarrow E+E\\
& \rightarrow E + E * E\\
& \rightarrow E + E * \text{int}\\
& \rightarrow E + \text{int} * \text{int}\\
& \rightarrow \text{int} + \text{int} * \text{int}\\
\end{align*}\\ E → E + E → E + E ∗ E → E + E ∗ int → E + int ∗ int → int + int ∗ int
E → E + T → t T → T ∗ F → F F → ( E ) → int \begin{align*}
E & \rightarrow E + T \\
& \rightarrow t\\
T & \rightarrow T * F \\
& \rightarrow F\\
F & \rightarrow (E) \\
& \rightarrow \text{int}\\
\end{align*}\\ E T F → E + T → t → T ∗ F → F → ( E ) → int
give int + int * int * int
E → E + T → T + T → F + T → int + T → int + T ∗ F → int + T ∗ F ∗ F → int + T ∗ F ∗ F ∗ F → int + int ∗ F ∗ F ∗ F → int + int ∗ int ∗ F ∗ F → int + int ∗ int ∗ int ∗ F → int + int ∗ int ∗ int ∗ int \begin{align*}
E & \rightarrow E + T\\
& \rightarrow T + T \\
& \rightarrow F + T \\
& \rightarrow \text{int} + T \\
& \rightarrow \text{int} + T * F \\
& \rightarrow \text{int} + T * F * F \\
& \rightarrow \text{int} + T * F * F * F \\
& \rightarrow \text{int} + \text{int} * F * F * F \\
& \rightarrow \text{int} + \text{int} * \text{int} * F * F \\
& \rightarrow \text{int} + \text{int} * \text{int} * \text{int} * F \\
& \rightarrow \text{int} + \text{int} * \text{int} * \text{int} * \text{int} \\
\end{align*}\\ E → E + T → T + T → F + T → int + T → int + T ∗ F → int + T ∗ F ∗ F → int + T ∗ F ∗ F ∗ F → int + int ∗ F ∗ F ∗ F → int + int ∗ int ∗ F ∗ F → int + int ∗ int ∗ int ∗ F → int + int ∗ int ∗ int ∗ int
scan the input from left to right
look for right-hand sides of production rules to build the derivation tree from bottom to top
Using an automaton and considering the first k tokens of the input;
this is called LR(k) analysis (LR means “Left to right scanning, Rightmost derivation”)
example
Let α ∈ ( N ∪ T ) ∗ \alpha \in (N \cup T)^* α ∈ ( N ∪ T ) ∗ .
NULL ( α ) \text{NULL}(\alpha) NULL ( α ) holds if and only if we can derive ϵ \epsilon ϵ from α \alpha α , i.e., α ⇒ ∗ ϵ \alpha \Rightarrow^* \epsilon α ⇒ ∗ ϵ
Let α ∈ ( N ∪ T ) ∗ \alpha \in (N \cup T)^* α ∈ ( N ∪ T ) ∗ .
FIRST ( α ) \text{FIRST}(\alpha) FIRST ( α ) is the set of all terminals starting words derived from α \alpha α , i.e., { a ∈ T ∣ ∃ w . α ⇒ ∗ a w } \{a \in T \mid \exists w . \alpha \Rightarrow^* aw \} { a ∈ T ∣ ∃ w . α ⇒ ∗ a w }
Let X ∈ N X \in N X ∈ N .
FOLLOW ( X ) \text{FOLLOW}(X) FOLLOW ( X ) is the set of all terminals that may appear after X X X in a derivation, i.e., { a ∈ T ∣ ∃ u , w . S ⇒ ∗ u X a w } \{a \in T \mid \exists u, w . S \Rightarrow^* uXaw \} { a ∈ T ∣ ∃ u , w . S ⇒ ∗ u X a w }