Download as pdf or txt
Download as pdf or txt
You are on page 1of 47

Compiler Construction

Top Down Parsers


Outlines
• First Sets

• Follow Sets

• Construction of Parsing Table

• Types of Parsing

• Top Down Parsers

• Bottom up Parser

• Abstract Syntax Tree (AST)

• Error Recovery

• Non – Context Free Grammar


First and Follow Sets
• An important part of parser table construction is to create first and follow sets.
• These sets can provide the actual position of any terminal in the derivation.
• This is done to create the parsing table where the decision of replacing T[A, t] = α with
some production rule.
• Syntax Analysis, which is really a complex process to implement.
• There can be easier way to sort out this problem:
First and Follow Sets
First Sets
• If the compiler would have come to know in advance, that what is the “first character of
the string produced when a production rule is applied”, and comparing it to the
current character or token in the input string it sees, it can wisely take decision on
which production rule to apply.
• Let’s take the example grammar

• Thus, in the example above, if it knew that after reading character ‘c’ in the input string
and applying S->cAd, next character in the input string is ‘a’, then it would have ignored
the production rule A->bc (because ‘b’ is the first character of the string produced by this
production rule, not ‘a’ ), and directly use the production rule A->a (because ‘a’ is the first
character of the string produced by this production rule, and is same as the current
character of the input string which is also ‘a’).
First and Follow Sets
Follow Sets
• The parser faces one more problem.
• Let us consider below grammar to understand this problem.

• As the first character in the input is a, the parser applies the rule A->aBb.

• Now the parser checks for the second character of the input string which is b, and the Non-
Terminal to derive is B, but the parser can’t get any string derivable from B that contains b as
first character.
• But the Grammar does contain a production rule B -> ε, if that is applied then B will vanish, and the
parser gets the input “ab” , as shown below.
• But the parser can apply it only when it knows that the character that follows B in the
production rule is same as the current character in the input.
First and Follow Sets

• So FOLLOW can make a Non-terminal to vanish out if needed to generate


the string from the parse tree.

• The conclusions is, we need to find FIRST and FOLLOW sets for a given
grammar, so that the parser can properly apply the needed rule at the
correct position.
First Sets - Rules
Example-
First(α) is a set of terminal symbols that begin in strings derived from α.

Consider the production rule-


Rule-01: A → abc / def / ghi

For a production rule X → ∈, Then, we have-


First(X) = { ∈ }
First(A) = { a , d , g }
Rule-02:

For any terminal symbol ‘a’,


First(a) = { a }

Rule-03:

For a production rule X → Y1Y2Y3, Calculating First(Y2Y3)

•If ∈ ∉ First(Y2), then First(Y2Y3) = First(Y2)


Calculating First(X) •If ∈ ∈ First(Y2), then First(Y2Y3) = { First(Y2) – ∈ } ∪ First(Y3)

•If ∈ ∉ First(Y1), then First(X) = First(Y1)


•If ∈ ∈ First(Y1), then First(X) = { First(Y1) – ∈ } ∪ First(Y2Y3)
Follow Sets - Rules
Follow(α) is a set of terminal symbols that appear immediately to the right of α.

Rule-01:

For the start symbol S, place $ in Follow(S).


Important Points
• ∈ may appear in the first function of a non-terminal.
Rule-02: • ∈ will never appear in the follow function of a non-terminal.
• Before calculating the first and follow functions,
For any production rule A → αB, eliminate Left Recursion from the grammar, if present.
Follow(B) = Follow(A) • We calculate the follow function of a non-terminal by
looking where it is present on the RHS of a production rule.

Rule-03:

For any production rule A → αBβ,

•If ∈ ∉ First(β), then Follow(B) = First(β)


•If ∈ ∈ First(β), then Follow(B) = { First(β) – ∈ } ∪ Follow(A)
First and Follow Sets - Problems
Problem-01:

Calculate the first and follow functions for the given grammar-

S → aBDh
B → cC
C → bC / ∈
D → EF
E→g/∈
F→f/∈

First Functions- Follow Functions-

•First(S) = { a } •Follow(S) = { $ }
•First(B) = { c } •Follow(B) = { First(D) – ∈ } ∪ First(h) = { g , f , h }
•First(C) = { b , ∈ } •Follow(C) = Follow(B) = { g , f , h }
•First(D) = { First(E) – ∈ } ∪ First(F) = { g , f , ∈ } •Follow(D) = First(h) = { h }
•First(E) = { g , ∈ } •Follow(E) = { First(F) – ∈ } ∪ Follow(D) = { f , h }
•First(F) = { f , ∈ } •Follow(F) = Follow(D) = { h }
First and Follow Sets - Problems
Problem-02:

Calculate the first and follow functions for the given grammar-

S→A S→A
• The given grammar is left recursive. ➔ A → aBA’
A → aB / Ad
• So, we first remove left recursion from the given grammar. A’ → dA’ / ∈
B→b
C→g B→b
C→g

First Functions-
Follow Functions-
•First(S) = First(A) = { a }
•First(A) = { a }
•Follow(S) = { $ }
•First(A’) = { d , ∈ }
•Follow(A) = Follow(S) = { $ }
•First(B) = { b }
•Follow(A’) = Follow(A) = { $ }
•First(C) = { g }
•Follow(B) = { First(A’) – ∈ } ∪ Follow(A) = { d , $ }
•Follow(C) = NA
First and Follow Sets - Problems
Problem-03:

Calculate the first and follow functions for the given grammar-

S → (L) / a
L → SL’
L’ → ,SL’ / ∈

First Functions-

•First(S) = { ( , a }
•First(L) = First(S) = { ( , a } Follow Functions-
•First(L’) = { , , ∈ }
•Follow(S) = { $ } ∪ { First(L’) – ∈ } ∪ Follow(L) ∪ Follow(L’) = { $ , , , ) }
•Follow(L) = { ) }
•Follow(L’) = Follow(L) = { ) }
First and Follow Sets - Problems
Problem-04:

Calculate the first and follow functions for the given grammar-

S → AaAb / BbBa
A→∈
B→∈
First Functions-

•First(S) = { First(A) – ∈ } ∪ First(a) ∪ { First(B) – ∈ } ∪ First(b) = { a , b }


•First(A) = { ∈ }
•First(B) = { ∈ }
Follow Functions-

•Follow(S) = { $ }
•Follow(A) = First(a) ∪ First(b) = { a , b }
•Follow(B) = First(b) ∪ First(a) = { a , b }
First and Follow Sets - Problems

Problem-05:

Calculate the first and follow functions for the given grammar-

E → TE’
E’ → + TE’ / ∈
T → FT’
T’ → x FT’ / ∈
F → (E) / id

First Functions- ? Follow Functions- ?

•First(E) = First(T) = First(F) = { ( , id } •Follow(E) = { $ , ) }


•First(E’) = { + , ∈ } •Follow(E’) = Follow(E) = { $ , ) }
•First(T) = First(F) = { ( , id } •Follow(T) = { First(E’) – ∈ } ∪ Follow(E) ∪ Follow(E’) = { + , $ , ) }
•First(T’) = { x , ∈ } •Follow(T’) = Follow(T) = { + , $ , ) }
•First(F) = { ( , id } •Follow(F) = { First(T’) – ∈ } ∪ Follow(T) ∪ Follow(T’) = { x , + , $ , ) }
First and Follow Sets - Problems
Problem-06:
S → ACB / CbB / Ba
Calculate the first and follow functions for the given grammar- A → da / BC
B→g/∈
C→h/∈
First Functions- ?

•First(S) = { First(A) – ∈ } ∪ { First(C) – ∈ } ∪ First(B) ∪ First(b) ∪ { First(B) – ∈ } ∪ First(a) = { d , g , h , ∈ , b , a }


•First(A) = First(d) ∪ { First(B) – ∈ } ∪ First(C) = { d , g , h , ∈ }
•First(B) = { g , ∈ }
•First(C) = { h , ∈ }

Follow Functions- ?

•Follow(S) = { $ }
•Follow(A) = { First(C) – ∈ } ∪ { First(B) – ∈ } ∪ Follow(S) = { h , g , $ }
•Follow(B) = Follow(S) ∪ First(a) ∪ { First(C) – ∈ } ∪ Follow(A) = { $ , a , h , g }
•Follow(C) = { First(B) – ∈ } ∪ Follow(S) ∪ First(b) ∪ Follow(A) = { g , $ , b , h }
Parsing Table
First Functions- Follow Functions-
E → TE’ { ( , id } {$,)}
E’ → + TE’ / ∈ {+,∈} {$,)}
T → FT’ { ( , id } {+,$,)} ( id E’) $
T’ → x FT’ / ∈ {x,∈} {+,$,)}
F → (E) / id { ( , id } {x,+,$,)}

id + x ( ) $
E E - > TE’ E - > TE’
E’ E’ - > +TE’ E’ - > ε E’ - > ε
T T - > FT’ T - > FT’
T’ T’ - > ε T’ - > xFT’ T’ - > ε T’ - > ε
F F - > id F - > (E)
Parsing Table – Example of LL(1) parser

Construct the Parsing Table of Following

1.
S → AaAb / BbBa
A→∈
B→∈
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S
S S - > (S) S->∈ S->∈
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S (
S S - > (S) S->∈ S->∈
S

( S )
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S (
S S - > (S) S->∈ S->∈
S

( S )
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S ( ) S (
S S - > (S) S->∈ S->∈
S

( S` )

( S )
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S ( ) S (
S S - > (S) S->∈ S->∈
S

( S` )

( S )
Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S ( ) S (
S S - > (S) S->∈ S->∈
S

( S` )

( S )

Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S ( ) S (
S S - > (S) S->∈ S->∈
S

( S` )

( S )

Parsing Table – Example of LL(1) parser
( ( ) ) $
First Functions- Follow Functions- ?
S → (S)/ ∈ { ( , ∈} {$, ) }

( ) $ $ S ) S ( ) S (
S S - > (S) S->∈ S->∈
S

( S` )

( S )

Types of Parsing
• Syntax analyzers follow production rules defined by means of context-free grammar.
• The way the production rules are implemented (derivation) divides parsing into two types : top-
down parsing and bottom-up parsing.
Types of Parsing
Top-down Parsing

When the parser starts constructing the parse tree from the start symbol and then tries
to transform the start symbol to the input, it is called top-down parsing.
terminals

•Recursive descent parsing : It is a common form of top-down parsing. It is called


recursive as it uses recursive procedures to process the input. Recursive descent
parsing suffers from backtracking.

•Backtracking : It means, if one derivation of a production fails, the syntax analyzer


restarts the process using different rules of same production. This technique may
process the input string more than once to determine the right production.
Types of Parsing
Bottom-up Parsing
start from the terminal & ends on the start symbol

As the name suggests, bottom-up parsing starts with the input symbols and tries to
construct the parse tree up to the start symbol.

Example:
Input string : a + b * c

Production rules:
S → E
E → E + T
E → E * T a + b * c
E → T T + b * c
E + b * c
T → id
E + T * c
Let us start bottom-up parsing E * c
a + b * c E * T
Read the input and check if any production matches with the input: E
S
Top-down Parsing
Top-down Parsing
Recursive Descent Parsing

• Recursive descent is a top-down parsing technique that constructs the parse tree from the top and
the input is read from left to right.
• It uses procedures for every terminal and non-terminal entity.
• This parsing technique recursively parses the input to make a parse tree, which may or may not
require back-tracking.
• But the grammar associated with it (if not left factored) cannot avoid back-tracking.
• A form of recursive-descent parsing that does not require any back-tracking is known as predictive
parsing.
• This parsing technique is regarded recursive as it uses context-free grammar which is recursive in
nature.
Top-down Parsing
Back-tracking
• Top- down parsers start from the root node (start symbol) and match the input string against the
production rules to replace them (if matched). To understand this, take the following example of
CFG:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing
Back-tracking:
Top-down Parsing - Predictive Parser
• Predictive parser is a recursive descent parser, which has the capability to predict which
production is to be used to replace the input string. The predictive parser does not suffer from
backtracking.
• To accomplish its tasks, the predictive parser uses a look-ahead pointer, which points to the
next input symbols. To make the parser back-tracking free, the predictive parser puts some
constraints on the grammar and accepts only a class of grammar known as LL(k) grammar.
Top-down Parsing - Predictive Parser
LL(1) vs. Recursive Descent
Abstract Syntax Trees
• Parse tree representations are not easy to be parsed by the compiler, as they
contain more details than actually needed.
• Take the following parse tree as an example
Abstract Syntax Trees
• If watched closely, we find most of the leaf nodes are single child to their parent nodes.
• This information can be eliminated before feeding it to the next phase.
• By hiding extra information, we can obtain a tree as shown below:

• ASTs are important data structures in a compiler with least unnecessary information.
• ASTs are more compact than a parse tree and can be easily used by a compiler.

You might also like