You are on page 1of 21

Compiler Construction

1. FOLLOW SETS Computation


2. Left Factorization
FOLLOW Sets
⚫ Definition:
Follow (A), where A is non-terminal can be defined as:

“ set of terminals (without є ) that immediately follow A, in any string


occurring on the RHS of productions of the grammar.”

Note:
⚫ Є cannot come inside a Follow set. The Follow set shall consists
of terminals only.
⚫ Follow set can be generated for non-terminals on RHS only.

2
FOLLOW Sets (Cont’d…)
⚫ In Follow sets computation, we will need First sets.
⚫ Follow sets computation is a three-step process.

1. Add $ to FOLLOW(S) where S is the start non-terminal.


2. If there is a production A  aBb, then everything in FIRST(b) – {є} (means
excluding є )
is in FOLLOW(B).
3. If there is a production A  aB, or A  aBb, where in є ϵ FIRST(b) (i.e., b * є),
then everything in FOLLOW(A) is in FOLLOW(B).

3
FIRST Sets (Cont’d…)

Lets explain the procedure by simple example.

A  BCDEFGHI
Step-1:
• Put $ in Follow (B). Then take First( C) excluding є and put in Follow(B).
• If First( C) contains є ,then put First (D) excluding є in Follow(B).
• If First(D) contains є , then put First(E) excluding є in Follow(B) and so on…
• If First sets do not contain є, then stop putting in Follow(non-terminals) sets.
• Repeat the same procedure for all Follow sets till you reach on the last symbol i.e. I in
the above grammar on RHS.
Step-2:
• For I, put Follow(A) in Follow(I).
If First(I) contains є, then also put Follow(A) in Follow(H) and so on till є is not in
First sets.

4
FIRST Sets (Cont’d…)
Lets explain the procedure by simple example

S-> XYZ
Y-> a | b

Solution:

Follow(X) = First(Y) = {a,b}


Follow (Z) = Follow (S) = {$}

Follow () never contain є


If Non-Terminal found on RHS then take first of (NT)
FIRST Sets (Cont’d…)
Lets explain the procedure by simple example

S-> aSbS |bSaS | є

Solution:

Follow(S) = {$, b, a}
Example 1: Given grammar below calculate Follow sets.

i. A 
BCD
ii.
iii. A
B CD
CD
iv. B  eDg
v. C  hiA
vi. C  є
vii. D  ki
viii. D  є

7
Example 1: Given grammar below calculate Follow sets.

i. A  The pre-calculated First Sets are:


BCD First (A) = { є, e, k, h}
ii.
iii. A
B CD
CD First (B) = {є, e, k, h}
iv. B  eDg First (C) = { є, h}
v. C  hiA First (D) = {є, k}
vi. C  є
vii. D  ki
viii. D  є

8
⚫ Lets apply procedure for calculating Follow sets step by step.
A  BCD The pre-calculated
⚫ For production (i), calculating Follow sets for non-terminals First Sets are:
on RHS. A  CD First (A) = { є, e, k,
B  h}
A  BCD First (B) = {є, e, k,
CD
h}
Put $ in Follow (B). Take First(C)-{є} and put in Follow B  eDg
First (C) = { є, h}
(B). C  hiA
First (D) = {є, k}
Follow(B) = {$, h} Cє
D  єki
[if Check if then
it was No First(C ) contains
we would є ? (yes)
stop putting in FOLLOW(B) and will calculate FOLLOW(C )]
Take First(D)-{є} and put in Follow(B).
Follow(B) = {$, h , k}

Put $ in Follow (C ). Take First(D)-{є} and put in Follow (C).


Follow(C ) = {$, k}
Now we have reached last non-terminal symbol i.e. D.

9
Put $ in Follow(D). Take Follow(A) and put in Follow(D).
A  BCD The pre-calculated
Follow(D) = {$, Follow(A)} [since Follow(A) is yet to calculate] First Sets are:
Check if First(D) contains є ? (yes) A  CD First (A) = { є, e, k,
B  h}
Put Follow(A) in Follow(C ). First (B) = {є, e, k,
CD
h}
Follow(C ) = {$, k, Follow(A)} B  eDg
First (C) = { є, h}
Check if First(C ) contains є ? (yes) C  hiA
First (D) = {є, k}
Cє
Put Follow(A) in Follow(B).
D  ki
Follow(B) = {$, h, k, Follow(A)} Dє

Production (i) is complete. Now production (ii).

⚫ For production (ii) calculating Follow sets.


A  CD
We have already calculated Follow(C ) and Follow(D) in production (i).
⚫ For production (iii) calculating Follow sets.
B  CD
We have already calculated Follow(C ) in previous production steps. When reached last
non-terminal symbol D, we will put Follow(B) in Follow(D).
1
0
Follow(D) = {$, Follow(A), h, k}
A  BCD The pre-calculated
Check if First(D) contains є ? (yes) First Sets are:
Put Follow(B) in Follow(C ). A  CD First (A) = { є, e, k,
B  h}
Follow(C ) = {$, k, Follow(A), h} First (B) = {є, e, k,
CD
h}
Production (iii) is complete. Now production (iv). B  eDg
First (C) = { є, h}
C  hiA
First (D) = {є, k}
Cє
⚫ For production (iv) calculating Follow sets. D  ki
B  eDg Dє

There is only one non-terminal i.e. D on RHS of (iv).


Take First(g) and put in Follow(D).
Follow(D) = {$, Follow(A), h, k, g}

⚫ For production (v)


C  hiA
Since there is only one non-terminal A on RHS and that is the last
symbol, Put Follow(C ) in Follow(A).

1
1
Follow(A) = {$,k, h}
A  BCD The pre-calculated
First Sets are:
Now rest of the productions (vi, vii, viii) have only A  CD First (A) = { є, e, k,
B  h}
terminals on RHS. So, calculation is complete. First (B) = {є, e, k,
CD
Now replace set Follow(A) members in all the above calculated h}
B  eDg
First (C) = { є, h}
Follow sets by eliminating duplicates. We have finally, C  hiA
First (D) = {є, k}
Cє
D  ki
Follow(A) = {$, k, h} Dє
Follow(B) = {$, h, k}
Follow(C ) = {$, k, h}
Follow(D) = {$, h, k, g}

1
2
Example 2: Consider the grammar

S  The pre-calculated First Sets are:


ABc A First (S) = { a, b, c}
First (A) = {a, є}
a
First (B) = { b, є}
Aє
B 
b B
 є
Calculating Follow sets for non-terminals on RHS of first production:
Follow(A) = {$, First(B)- є} = {b}
Since First(B) contains є , so put First(c) in Follow(A).
Follow(A) = {$, b, First( c)} = {b, c} [since First sets of terminals contains the terminals it self]
Now calculating Follow(B) in first production.
Follow(B) = {$, First(c )} = {c}
In rest of the productions, there are only terminals on RHS. So no further Follow sets. Finally,

Follow(A) = {b, c}
Follow(B) = {c}
10
Home
Task
1. Calculate Follow sets for the grammar:

E  Prefix(E)
E  v Tail
Prefix  f
Prefix  є
Tail  + E
Tail  є
Derive
through step
by step
procedure.

11
Left Factoring

Left factoring transforms the grammar to


make it useful for top-down parsers. In this
technique, we make one production for each
common prefixes and the rest of the
derivation is added by new productions.
Now the parser has only one production per
prefix which makes it easier to take
decisions.
The procedure of converting Non-
Deterministic CFG into Deterministic CFG.
Left Factoring
⚫ Consider the
grammar E  T +
E| T
T  int | int * T |
(E)
It is impossible to predict on which RHS production the LHS non-terminal should
be replaced because for T, two productions start with int. For E, it is not clear
how to predict; the two productions start with the non-terminal T. A grammar
must be left factored before use for predictive parsing.

The procedure to left-factor a grammar is as follows:


⚫ If α ≠ є, replace all
productions A  αβ1| αβ2 |
.... | αβn | γ With
AαZ| γ
Z  β1 | β2 | .... | βn
where Z is a new non-
Left Factoring (Cont’d…)
Example: consider following fragment of expression
grammar

Factor  id| id [ ExprList ] | id

( ExprList ) After left factoring, the

grammar becomes

Factor  id Args
Args  [ ExprList ] | ( ExprList) | є

13
Left Factoring (Cont’d…)

Example 2: consider following Example

S  C + E | C* E | C / E

After left factoring, the grammar becomes

S  C S’
S’  +E | *E | / E

13
Left Factoring (Cont’d…)

Example 3: consider following Example

S  iEtS | iEtSeS | a

After left factoring, the grammar becomes

S  iEtS S’ | a
S’  Є |eS
Learn by Practice

• S-> aSb |abS|ab

S->aS’
S’->Sb|bS|b //still non deterministic
S’->Sb|bS”
S’’->S| Є
Learn by Practice

• S->ab|abc|abcd|b

• S->aAb|aABc|aABcd|aA|a
A->a
B->a

You might also like