# What is a Grammar?

An unrestricted grammar is a quadruple $G=(V,\Sigma,R,S)$, where $V$ is an alphabet; $\Sigma$ is the set of terminal symbols ($\Sigma\subseteq{}V$); $(V-\Sigma)$ is the set of non-terminal symbols; $S$ is the initial symbol; and $R$ is a set of rules (a finite subset of $(V^*(V-\Sigma)V^*)\times{}V^*$).

The following are defined:

• Direct derivation: $u\underset{G}{\Rightarrow}v\;\text{iff}\;\exists_{w_1,w_2\in{}V^*}: \exists_{(u',v')\in{}R}: u=w_1u'w_2 \wedge v=w_1v'w_2$
• Derivation: $w_0\underset{G}{\Rightarrow}w_1\underset{G}{\Rightarrow}\cdots\underset{G}{\Rightarrow}w_n\;\Leftrightarrow{}w_0\overset{*}{\underset{G}{\Rightarrow}}w_n$
• Generated language: $L(G) = \{ w\: |\: w \in \Sigma^* \wedge{}S\overset{*}{\underset{G}{\Rightarrow}}w \}$

## Context-free Grammars

The above grammar is unrestricted in its derivation capabilities and directly supports context-dependent rules.

In our study of programming language processing, though, only context-free grammars will be considered. This means that the $R$ set is defined on $(V-\Sigma)\times{}V^*$, i.e., only non-terminals are allowed on the left side of a rule.

Even though we gave a formal definition of grammar, seldom will we use them described in that form. Most grammars are described in Backus-Naur Form (BNF), Extended Backus–Naur Form (EBNF), or other metasyntax.

Consider the following example grammar:

 E -> E + E | T
T -> T * T | F
F -> ( E ) | val


This grammar provides a description of the syntax of simple additive and multiplicative expressions. The language will be any expression involving the two operators, sets of parentheses and values (val). Tokens (terminals) are in blue. Token val represents any number and is a terminal in this grammar: in a compiler implementation this would be recognized at the lexical level.

# The FIRST and FOLLOW sets

## Computing the FIRST Set

The FIRST set for a given string or symbol can be computed as follows:

1. If a is a terminal symbol, then FIRST(a) = {a}
2. If X is a non-terminal symbol and X -> ε is a production then add ε to FIRST(X)
3. If X is a non-terminal symbol and X -> Y1...Yn is a production, then
a ∈ FIRST(X) if a ∈ FIRST(Yi) and ε ∈ FIRST(Yj), i>j (i.e., Yj $\overset{*}{\Rightarrow}$ ε)

As an example, consider production X -> Y1...Yn

• If Y1 $\overset{*}{\not\Rightarrow}$ ε then FIRST(X) = FIRST(Y1)
• If Y1 $\overset{*}{\Rightarrow}$ ε and Y2 $\overset{*}{\not\Rightarrow}$ ε then FIRST(X) = FIRST(Y1) \ {ε} ∪ FIRST(Y2)
• If Yi $\overset{*}{\Rightarrow}$ ε (∀i) then FIRST(X) = ∪i(FIRST(Yi)\{ε}) ∪ {ε}

The FIRST set can also be computed for a string Y1...Yn much in the same way as in case 3 above.

The FOLLOW set is computed for non-terminals and indicates the set of terminal symbols that are possible after a given non-terminal. The special symbol $is used to represent the end of phrase (end of input). 1. If X is the grammar's initial symbol then {$} ⊆ FOLLOW(X)
2. If A -> αXβ is a production, then FIRST(β)\{ε} ⊆ FOLLOW(X)
3. If A -> αX or A -> αXβ (β $\overset{*}{\Rightarrow}$ ε), then FOLLOW(A) ⊆ FOLLOW(X)

The algorithm should be repeated until the FOLLOW set remains unchanged.

LOOKAHEAD(R -> Body) = FIRST(Body) ∪ FOLLOW(R), when Body $\overset{*}{\Rightarrow}$ ε