0% found this document useful (0 votes)
32 views

Compiler Design Unit 2

The document discusses top-down parsing and recursive descent parsing. It begins by explaining that top-down parsers start from the start symbol and match the input string against production rules to replace symbols. Recursive descent parsing is then introduced as a simple top-down parsing algorithm that is easy to implement. The document provides examples of writing recursive procedures for different context-free grammars. It also discusses issues like left recursion and how to remove it through transformations. Finally, it covers left factoring to remove ambiguity from grammars with common prefixes and defines the rules for calculating first and follow sets.

Uploaded by

Shubham Dixit
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

Compiler Design Unit 2

The document discusses top-down parsing and recursive descent parsing. It begins by explaining that top-down parsers start from the start symbol and match the input string against production rules to replace symbols. Recursive descent parsing is then introduced as a simple top-down parsing algorithm that is easy to implement. The document provides examples of writing recursive procedures for different context-free grammars. It also discusses issues like left recursion and how to remove it through transformations. Finally, it covers left factoring to remove ambiguity from grammars with common prefixes and defines the rules for calculating first and follow sets.

Uploaded by

Shubham Dixit
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 84

PARSER

(SYNTAX ANALYZER)
In compiler model, the parser obtains a string of
tokens from lexical analyzer and verifies that the
string can be generated by the grammar for the
source language.
We expect the parser to report any syntax error in
an intelligible fashion. It should also recover from
common occurring errors so that it can be
continue processing the remainder of its input.
TYPES OF PARSER
TOP DOWN PARSING
(Backtracking)
• 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:
W=read
TOP DOWN PARSING
(Recursive Descent Parsing)
• Recursive descent is a simple parsing
algorithm that is very easy to implement.
• It is a top-down parsing algorithm because it
builds the parse tree from the top (the start
symbol) down.
TOP DOWN PARSING
(Recursive Descent Parsing)
Q: Write down the recursive procedure for Top Down parsing
for grammar:
ScAdW
Aab/a
Wcad
Q: Write down the recursive procedure for Top Down parsing
for grammar:
ETA
A+TA/ Ꜫ
TFB
B*FB/ Ꜫ
F(E)/id
TOP DOWN PARSING
(Recursive Descent Parsing) cont…
Sol 1: Procedure to write Recursive Descent Parsing
ScAdW Aab/a Wcad
Procedure S() Procedure A() Procedure W()
{ { {
if (lookahead pointer == ‘c’) if (lookahead pointer = ‘a’) if (lookahead pointer = ‘c’)
{ { {
Match(‘c’); Match(‘a’); Match(‘c’);
} Match(‘b’); Match(‘a’);
A(); } Match(‘d’);
if (lookahead pointer==‘d’) else if (lookahead pointer = ‘a’) }
{ { }
Match(‘d’); Match(‘a’); else
} } Error();
W(); }
}
TOP DOWN PARSING
(Recursive Descent Parsing) cont…
Sol2: Procedure to write Recursive Descent Parsing
ETA A+TA/Ꜫ TFB
Procedure E() Procedure A() Procedure T()
{ { {
T(); if (lookahead pointer = ‘+’) F();
A(); { B();
} Match(‘+’); }
}
T();
A();
Else
return;
}
TOP DOWN PARSING
(Recursive Descent Parsing) cont…
Sol2 cont..:
Procedure to write Recursive Descent Parsing
B*FB/Ꜫ F(E)/id
Procedure B() Procedure F()
{ {
if (lookahead pointer = ‘*’) if (lookahead pointer = ‘(’)
{ {
Match(‘*’); Match(‘(’);
} }
E();
F(); if (lookahead pointer = ‘)’)
B(); {
Else Match(‘)’);
Return; }
}
elseif (lookahead pointer = ‘id’)
{
Match(‘id’);
}
}
LEFT RECURSION
• A grammar becomes left-recursive if it has any non-terminal ‘A’ whose
derivation contains ‘A’ itself as the left-most symbol.
• Left-recursive grammar is considered to be a problematic situation for top-
down parsers.
• Top-down parsers start parsing from the Start symbol, which in itself is non-
terminal.
• So, when the parser encounters the same non-terminal in its derivation, it
becomes hard for it to judge when to stop parsing the left non-terminal and it
goes into an infinite loop.
• Example:
(1) A => Aα | β
(2) S => Aα | β
A => Sd

(1) is an example of immediate left recursion, where A is any non-terminal symbol and
α represents a string of non-terminals.
(2) is an example of indirect-left recursion.
A top-down parser will first parse the A, which in-turn will yield a string
consisting of A itself and the parser may go into a loop forever.
LEFT RECURSION
Problem:1 Direct Recursion
A => A α | β

A => Aα α

A => Aα α α

A => Aα α α α

A => Aα α α α α

A => Aα α α α α α
LEFT RECURSION
Problem:2 Indirect Recursion
S => A α | β

A => Sd α

A => Aα d α

A => Sd α d α

A => Aα d α d α

A => Sd α d α d α
REMOVAL OF LEFT RECURSION
One way to remove left recursion is to use the
following technique:
The production
A => Aα | β
is converted into following productions
A => βA'
A'=> αA' | ε
This does not impact the strings derived from the
grammar, but it removes immediate left
recursion.
LEFT RECURSION
Remove Left Recursion: Eg:

If a production like this E => E + T / T ……1


Compare it with
A => A α | β A => A α | β
So,
……2

Convert this into : A => A α / β


A => βA’ E => E + T / T

A’=> αA’/ Ꜫ So, for removal Left recursion will perform:

A => βA’ : E => T E’

A’=> αA’/ Ꜫ : E’ => +TE’/ Ꜫ


LEFT RECURSION
Problem: Eliminate left recursion-
E→E+T/T
T→T*F/F
F → id
Sol:
After eliminating left recursion is-
E → TE’
E’ → +TE’ / ∈
T → FT’
T’ → *FT’ / ∈
F → id
LEFT RECURSION
Problem: Eliminate left recursion-
A → ABd / Aa / a
B → Be / b
Sol:
After eliminating left recursion is-
A → aA’
A’ → BdA’ / aA’ / ∈
B → bB’
B’ → eB’ / ∈
LEFT FACTORING
If more than one grammar production rules has a
common prefix string, then the top-down parser
cannot make a choice as to which of the production
it should take to parse the string in hand.
A ⟹ αβ | α𝜸

Then it cannot determine which production to


follow to parse the string as both productions are
starting from the same terminal (or non-terminal).
To remove this confusion, we use a technique called
left factoring.
LEFT FACTORING
Suppose the production is :
A ⟹ αβ | α𝜸
Suppose the First element we read according this
production is “α”.
So, What would be the second element ?
Is “β” or “𝜸”?
To remove this problem
The above productions can be written as
A => α A'
A'=> β | 𝜸 | …
Now the parser has only one production per prefix
which makes it easier to take decisions.
LEFT FACTORING
Problem: Eg:
If a production like this: S => iEtS / iEtSeS / a ……1
Compare it with
A ⟹ αβ | α𝜸 A⟹ α β | α 𝜸 ……2
Convert this into : So,

A => α A' A => α β / α 𝜸

A'=> β | 𝜸 | …
S => iEtS Ꜫ / iEtS eS / a

So, for removal Left Factoring will perform:

A => α A' : S => iEtSS’ / a

A'=> β | 𝜸 | … : S’ => eS/ Ꜫ


LEFT FACTORING
Problem: Do left factoring in the following grammar-
A → aAB / aBc / aAc
Sol:
Left factored process
A → aA’
A’ → AB / Bc / Ac
A’ → AB / Ac / Bc
A’ → A A’’/ Bc
A’’ → B/c
Now the left factored grammar is :
A → aA’
A’ → AA’’ / Bc
A’’ → B / c
LEFT FACTORING
Problem: Do left factoring in the following grammar-
S → bSSaaS / bSSaSb / bSb / a
Sol:
Left factored process
S → bSS’ / a
S’ → SaaS / SaSb / b
S’ → SaS’’ / b
S’’ → aS / Sb
Now the left factored grammar :
S → bSS’ / a
S’ → SaS’’/ b
S’’ → aS / Sb
FIRST AND FOLLOW
RULES TO FIND FIRST OF NON-TERMINAL:-
• For a production rule X → ∈,
First(X) = { ∈ }

• For any terminal symbol ‘a’,


First(a) = { a }

• For a production rule X → Y1Y2Y3

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

If ∈ ∈ First(Y1), then First(X) = { First(Y1) – ∈ } ∪ First(Y2Y3)


FIRST AND FOLLOW
RULES TO FIND FOLLOW OF NON-TERMINAL:-
• For the start symbol S, place $ in Follow(S).

• For any production rule A → αB,


Follow(B) = Follow(A)

• For any production rule A → αBβ,


If ∈ ∉ First(β), then Follow(B) = First(β)
If ∈ ∈ First(β), then Follow(B) = { First(β) – ∈ } ∪ Follow(A)
FIRST AND FOLLOW
Important points-
• ∈ may appear in the first function of a non-terminal.

• ∈ will never appear in the follow function of a non-terminal.

• Before calculating the first and follow functions, eliminate Left


Recursion from the grammar, if present.

• We calculate the follow function of a non-terminal by looking


where it is present on the RHS of a production rule.
FIRST AND FOLLOW
Examples:
Consider the production rule:
A → abc / def / ghi
OR
Can we written
Non terminal First
A → abc
A a, d, g
Adef
Aghi

So,
First(A) ={a, d, g}
FIRST AND FOLLOW
Examples:
Calculate the first functions for the given grammar-
S→A Non terminal First
A → aC / Bd
S a,b
B→b
A a,b
C→g
B b
C g
So,
First(S) =
{ First (A) } = { First{ aC} U {First (Bd)} = { {a} U {First(B)} } = { {a} U {b} } = {a , b}

First(A) =
{ First{ aC} U {First (Bd)} = { {a} U {First(B)} } = { {a} U {b} } = {a,b}

First(B) = { b}

First(C) = { g}
FIRST AND FOLLOW
Examples:
Calculate the first functions for the given grammar-
S → aBDh Non terminal First
B → cC
S a
C → bC / ∈
B c
D → EF
C b,∈
E→g/∈
D g,f,∈
F→f/∈
E g, ∈
F f,∈
So,
First(S) = { First (aBDh) } = { a }
First(B) = { First (cC) } = { c }
First(C) = { First (bC) U First (∈)} = { b , ∈ }
First(D) = { First(E) – ∈ } ∪ First(F) = { g , f , ∈ }
First(E) = { First(g) U First(∈) } = { g , ∈}
First(F) = {First (f) U First (∈) } = { f , ∈ }
FIRST AND FOLLOW
Examples:
Calculate the follow functions for the given grammar-
S→A Non terminal First Follow
A → aC / Bd
S a,b $
B→b
A a,b $
C→g
B b d
C g $
So,
Follow(S) = { $ } : For the start symbol S, place $ in Follow(S).

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

Follow(B) = First( d ) = { d }

Follow(C) = Follow( A ) = { $ }
FIRST AND FOLLOW
Examples:
Calculate the Follow functions for the given grammar-
S → aBDh Non terminal First Follow
B → cC
S a $
C → bC / ∈
D → EF B c g, f, h
E→g/∈ C b,∈ g, f, h
F→f/∈ D g,f,∈ h
E g, ∈ f, h
So,
Follow(S) = { $ } F f,∈ h
Follow(B) = { First (Dh) } = First( D) = { g,f, ∈} = while put ∈ in place of D it looks First(h) =
{h}
So, Follow (B) = {g, f, h}
Follow(C) = Follow(B) U Follow (C) = {g, f, h} U Follow(C) = { g, f, h}
Follow(D) = First(h) = { h }
Follow(E) = First(F) = {f , ∈ } = while put ∈ in place of F so we find Follow (D)={ h}
So,, Follow(E)={ f, h }
Follow(F) = Follow(D) = { h }
FIRST AND FOLLOW

• Q: Find First and Follow

EE+T/T
TT*F/F After Removal LF and
LR
F(E)/id
FIRST AND FOLLOW

• Sol:
NON TERMINAL
FIRST FOLLOW
E {id, (} {$,)}
E’ {+, Ꜫ} {$,)}
T {id, (} {+,$,)}
T’ {*, Ꜫ} {+,$,)}
F {id, (} {*,+,$,)}
FIRST AND FOLLOW

• Q: Find First and Follow:


FIRST AND FOLLOW
NON TERMINAL
• Solution: FIRST FOLLOW
S {a,b,c,d,e} {$}

A {c, Ꜫ} {a, b, e, d, $}

B {a, d, e} {a, b, e}
C {e, Ꜫ} {a, b, c, d, $}

D {a, b} {a, b, e, d, $}
TOP DOWN PARSING
(Non-Recursive Descent Parsing)
The parser is controlled by a program
that behaves as follows:
• If X=a=$, the parser halts and
announces successful completion of
parsing.
• If X=a!=$, the parser pops X off the stack
and advances the I/P pointer to the next
I/P symbol.
• If X is a Non-terminal, the program
consults entry M[X,a] of the parsing
table M. This entry will be either an X-
production of the grammar or an error
entry.
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
• Q1. Consider this grammar
ETE’
E’+TE’/ Ꜫ
TFT’
T’*FT’/Ꜫ
F(E)/id
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
• Sol:
NON TERMINAL
FIRST FOLLOW
E {id, (} {$,)}
E’ {+, Ꜫ} {$,)}
T {id, (} {+,$,)}
T’ {*, Ꜫ} {+,$,)}
F {id, (} {*,+,$,)}
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
• Sol: Predictive Parsing Table..
Non
terminal + * ( ) id $

E ETE’ ETE’

E’ E’+TE’ E’Ꜫ E’Ꜫ

T TFT’ TFT’

T’ T’Ꜫ T’*FT’ T’Ꜫ T’Ꜫ

F F(E) Fid
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
Finding the sequence of moves for Input : id + id * id
STACK INPUT ACTION STACK INPUT ACTION
$E Id +id *id $ $E’T’F id $
$ E’ T Id +id *id $ ETE’ $E’T’ id id $ Fid
$ E’T’F Id + id *id $ TFT’ $E’T’ $
$ E’T’ id Id + id *id $ Fid $E’ $ T’Ꜫ
$ E’T’ + id *id $ $ $ E’Ꜫ
$ E’ + id *id $ T’Ꜫ
$ E’T+ + id *id $ E’+TE’
$E’T id *id $
$E’T’F id *id $ TFT’
$E’T’ id id *id $ Fid
$E’T’ * id $
$E’T’F* * id $ T’*FT’
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
• Q2. Consider this grammar
SiEtSS’/a
S’eS/ Ꜫ
Eb
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…
• Sol:
NON TERMINAL
FIRST FOLLOW
S {i, a} {$,e}
S’ {e, Ꜫ} {$,e}
E {b} {t}
TOP DOWN PARSING
(Non-Recursive Descent Parsing) Cont…

Non
terminal a b e i t $
S Sa SiEtSS’

S’eS
S’ S’Ꜫ
S’Ꜫ
E Eb
Because of Multiple entries in the table the Grammar is not LL1
BOTTOM UP PARSING
(SR parser)
Bottom-up parsing starts from the leaf nodes of a tree and works in
upward direction till it reaches the root node. Here, we start from a
sentence and then apply production rules in reverse manner in
order to reach the start symbol.
Shift-Reduce Parsing
Shift-reduce parsing uses two unique steps for bottom-up parsing.
These steps are known as shift-step and reduce-step.
• Shift step: The shift step refers to the advancement of the input
pointer to the next input symbol, which is called the shifted symbol.
This symbol is pushed onto the stack. The shifted symbol is treated
as a single node of the parse tree.
• Reduce step : When the parser finds a complete grammar rule
(RHS) and replaces it to (LHS), it is known as reduce-step. This
occurs when the top of the stack contains a handle. To reduce, a
POP function is performed on the stack which pops off the handle
and replaces it with LHS non-terminal symbol.
BOTTOM UP PARSING
(SR parser)
On the basis of these operation the String may be accepted or
return an Error.
• Accept: If only start symbol is present in the stack and the
input buffer is empty then, the parsing action is called accept.
When accept action is obtained, it is means successful parsing
is done.
• Error : This is the situation in which the parser can neither
perform shift action nor reduce action and not even accept
action.
BOTTOM UP PARSING
SR PARSER
Finding the sequence of moves for Input : “ ( a , ( a , a ) ) ”
STACK INPUT ACTION
S( L ) $ (a,(a,a))$

$( a,(a,a))$ Shift (
S a
$(a ,(a,a))$ Shift a
LL , S $(S ,(a,a))$ Reduced by S a

,(a,a))$ Reduced by L S
$(L
L--> S
$(L, (a,a))$ Shift ,

$(L,( a,a))$ Shift (

$(L,(a ,a))$ Shift a

$(L,(S ,a))$ Reduced by S a

$(L,(L ,a))$ Reduced by L S

$(L,(L, a))$ Shift ,

$(L,(L,a ))$ Shift a


BOTTOM UP PARSING
SR PARSER
Finding the sequence of moves for Input : “ ( a , ( a , a ) ) ”
STACK INPUT ACTION
S( L ) $(L,(L,a ))$ Shift a

$(L,(L,S ))$ Reduced by S a


S a
$(L,(L ))$ Reduced by L L , S
LL , S $(L,(L) )$ Shift )

$(L,S )$ Reduced by S ( L )
L--> S
$(L )$ Reduced by L L , S

$(L) $ Shift )

$S $ Reduced by S ( L )

$S $ Accepted
Operator Precedence Parsing
Operator precedence is kinds of shift reduce
parsing method. It is applied to a small class of
operator grammars.
It is used for OPG.
A grammar is said to OPG if it has following
properties.
• It doesn’t contain Ꜫ at the right side of the
production.
• Two consecutive Non terminal can not be
present in the right side of production.
Operator Precedence Parsing

Eg.
E  E A E | id
Not an Operator Grammar
A+|*

The above grammar is not an operator grammar


but after substitution it can be made:

E  E + E | E* E | id Now Operator Grammar


Operator Precedence Parsing
There are some rules that are followed for
making precedence relation:
• If a has higher precedence over b; a .> b
• If a has lower precedence over b; a <. b
• If a and b have equal precedence; a =. b
Note:
– id has higher precedence than any other symbol
– $ has lowest precedence.
– if two operators have equal precedence, then we
check the Associativity of that particular operator.
Operator Precedence Parsing
Basic Principle:
• Scan input string left to right, try to detect .>
and put a pointer on its location.
• Now scan backwards till reaching <.
• String between <. And .> is our handle.
• Replace handle by the head of the respective
production.
• REPEAT until reaching start symbol.
Handle
• A “handle” of a string is a substring that matches the RHS of a production and
whose reduction to the non-terminal (on the LHS of the production) represents
one step along the reverse of a rightmost derivation toward reducing to the start
symbol.
If S → αAw → αβw, then A → β in the position following α is a handle of αβw.
In such a case, it is suffice to say that the substring β is a handle of αβw, if the
position of β and the corresponding production are clear.

Consider the following grammar:


E → E + E | E * E | (E) | id
and a right-most derivation is as follows:
E → E + E → E+ E * E → E + E * id3 → E + id2 * id3 → id1 + id2 * id3
The id’s are subscripted for notational convenience.

Note that the reduction is in the opposite direction from id1 + id2 * id3 back to E,
where the handle at every step is underlined.
Operator Precedence Parsing
Consider grammar EE+E EE*E Eid

Id + * $
Id ∙> ∙> ∙>

+ <∙ ∙> <∙ ∙>

* <∙ ∙> ∙> ∙>

$ <∙ <∙ <∙

$ <∙ id ∙> + <∙ id ∙> * <∙ id ∙> $ $ <∙ + <∙ * ∙> $

$ E + <∙ id ∙> * <∙ id ∙> $ $ <∙ + <∙ * ∙> $

$ E + <∙ id ∙> * <∙ id ∙> $ $E+E$

$ E + E* <∙ id ∙> $ $ <∙ + ∙> $


$ <∙ + ∙> $
$ E + E* <∙ id ∙> $
$E$
$ E + E* E $
Operator Precedence Parsing
Now constructing a graph that represents precedence function:

Fid Gid

F+ G+

F* G*

F$ G$

From the previous graph we extract the following precedence functions: You have to find the longest path of Fid and Gid .

Fid G* F+ G+ F$
Gid F* G* F+ G+ F$

id + * $ Note: During the construction


of a graph if a cycle is formed
F 4 2 4 0 then precedence function is not
G 5 1 3 0 possible for the problem….
BOTTOM UP PARSING
(SR parser)
• LR Parser
The LR parser is a non-recursive, shift-reduce, bottom-up parser. It uses a wide
class of context-free grammar which makes it the most efficient syntax analysis
technique. LR parsers are also known as LR(k) parsers, where L stands for left-to-
right scanning of the input stream; R stands for the construction of right-most
derivation in reverse, and k denotes the number of lookahead symbols to make
decisions.
There are three widely used algorithms available for constructing an LR parser:
SLR – Simple LR Parser:
– Works on smallest class of grammar
– Few number of states, hence very small table
– Simple and fast construction
LR(1) – LR Parser (CLR):
– Works on complete set of LR(1) Grammar
– Generates large table and large number of states
– Slow construction
LALR(1) – Look-Ahead LR Parser:
– Works on intermediate size of grammar
– Number of states are same as in SLR(1)
BOTTOM UP PARSER
LR(0)
Basic things:
1. Closure() and Goto()
2. Add one more production to the grammar to make Augmented
grammar.
3. LR(0) items: Any production with a (.) in RHS is called LR(0) items.
1. S.AA In RHS we have not seen anything
2. S A.A In RHS we have seen ‘A’
3. S AA. In RHS we have seen everything in this production.
Closure
Augmented
Form
Grammar

S’S S’.S
SAB
Aa SAB S.AB
Bb Aa A.a
Bb B.b
BOTTOM UP PARSER
LR(0)
Find whether the grammar is LR(0) or not?
EE+T
ET
TT*F
TF
Fid
BOTTOM UP PARSER
LR(0)
Sol:
STEP1:
Augmented grammar
E’E STEP2: Closure
EE+T E’.E
ET E.E+T
TT*F E.T
TF
T.T*F I0
Fid
T.F
F.id
BOTTOM UP PARSER
LR(0)
Sol: GOTO(I0,F)
GOTO(I0,E)
E’E.
TF. I3
EE.+T I1
GOTO(I0,id)
GOTO(I0,T) Fid. I4
ET.
TT.*F
I2
BOTTOM UP PARSER
LR(0)
Sol:
GOTO(I5,T)
GOTO(I1,+)
EE+.T
EE+T.
T.T*F TT.*F I7
T.F I5
F.id GOTO(I5,F)
TF. Same as I3
GOTO(I2,*)
TT*.F GOTO(I5,id)
F.id I6 Fid. Same as I4
BOTTOM UP PARSER
LR(0)
Sol:
GOTO(I6,F)
TT*F. I8
GOTO(I7,*)
GOTO(I6,id) TT*.F
Same as I6
Fid. Same as I F.id
4
BOTTOM UP PARSER
LR(0)
PARSING TABLE FOR LR(0)
Because of SR conflict the Grammar
is Not LR(0)
ACTION GOTO
STATES
+ * id $ E T F
I0 S4 1 2 3
I1 S5 Accept
I2 R2 S6 /R2 R2 R2
I3 R4 R4 R4 R4
I4 R5 R5 R5 R5
I5 S4 7 3

I6 S4 8

I7 R1 S6 /R1 R1 R1
I8 R3 R3 R3 R3
BOTTOM UP PARSER
SLR
• For SLR we have to follow the same process and Find
First and Follow for the Non-terminal.

NON TERMINAL
FIRST FOLLOW
E {id} {$,+}
T {id} {$,+,*}
F {id} {$,+,*}
BOTTOM UP PARSER
SLR
PARSING TABLE FOR SLR There is no multiple entries in the
Table so the grammar is SLR
ACTION GOTO
STATES
+ * id $ E T F
I0 S4 1 2 3
I1 S5 Accept
I2 R2 S6 R2
I3 R4 R4 R4
I4 R5 R5 R5
I5 S4 7 3

I6 S4 8

I7 R1 S6 R1
I8 R3 R3 R3
BOTTOM UP PARSER

Find whether the grammar is LR(0) or SLR?


SL=R
SR
L*R
Lid
RL
BOTTOM UP PARSER
LR(0)
Sol:
STEP1:
Augmented grammar STEP2: Closure Form
S’S
SL=R
S’.S
SR S.L=R
S.R
I0
L*R
Lid L.*R
RL L.id
R.L
BOTTOM UP PARSER
LR(0)
Sol: GOTO(I0,R)
GOTO(I0,S) SR. I3
S’S. I1 GOTO(I0,*)
L*.R
R.L
L.*R
I4
GOTO(I0,L)
L.id
SL.=R
RL.
I2 GOTO(I0,id)
Lid. I5
BOTTOM UP PARSER
LR(0)
Sol: GOTO(I4,*)
GOTO(I2,=) L*.R
SL=.R R.L Same as I4
R.L L.*R
L.*R I6 L.id
L.id
GOTO(I4,id)
GOTO(I4,R) Lid. Same as I5
L*R. I7 GOTO(I6,R)
GOTO(I4,L) SL=R. I9
RL. I8
BOTTOM UP PARSER
LR(0)
Sol:
GOTO(I6,L)
RL. Same as I8

GOTO(I6,*) GOTO(I6,id)
L*.R
R.L Same as I5
L.*R I
Same as 4
Lid.
L.id
BOTTOM UP PARSER
LR(0)
PARSING TABLE FOR LR(0)
Because of SR conflict the Grammar
is Not LR(0)
ACTION GOTO
STATES
= * id $ S L R
I0 S4 S5 1 2 3

I1 Accept
I2 S6 /R5 R5 R5 R5
I3 R2 R2 R2 R2
I4 S4 S5 8 7
I5 R4 R4 R4 R4
I6 S4 S5 8 9
I7 R3 R3 R3 R3
I8 R5 R5 R5 R5

I9 R1 R1 R1 R1
BOTTOM UP PARSER
SLR
• For SLR we have to follow the same process and Find
First and Follow for the Non-terminal.

NON TERMINAL
FIRST FOLLOW
S {*,id} {$}
L {*,id} {=,$}
R {*,id} {=,$}
BOTTOM UP PARSER

PARSING TABLE FOR SLR


Because of SR conflict the Grammar
is Not SLR
ACTION GOTO
STATES
= * id $ S L R
I0 S4 S5 1 2 3

I1 Accept
I2 S6 /R5 R5
I3 R2
I4 S4 S5 8 7
I5 R4 R4
I6 S4 S5 8 9
I7 R3 R3
I8 R5 R5

I9 R1
BOTTOM UP PARSER
CLR
Find whether the grammar is CLR or not?
SAA
AaA
Ab
BOTTOM UP PARSER
CLR
Sol:
STEP1: Augmented grammar
S’S
SAA
AaA
Ab
STEP2: Closure
S’.S , $
S.AA , $
A.aA , a/b I0
A.b , a/b
BOTTOM UP PARSER
CLR
Sol:
GOTO(I0,S)
GOTO(I0,a)
S’S. ,$ I1 Aa.A , a/b
A.aA , a/b I3
A.b , a/b
GOTO(I0,A)
SA.A ,$ GOTO(I0,b)
A.aA ,$ I2
A.b ,$ Ab. a/b I4
,
BOTTOM UP PARSER
CLR
Sol:
GOTO(I2,b)
GOTO(I2,A)
Ab. , $
I7
SAA. ,$ I5
GOTO(I3,A)
GOTO(I2,a) AaA. , a/b I8
Aa.A ,$
A.aA ,$ I6 GOTO(I3,a)
Aa.A , a/b
A.b ,$ A.aA , a/b Same as I3
A.b , a/b
BOTTOM UP PARSER
CLR
Sol:
GOTO(I3,b)
Ab. , a/b Same as I4 GOTO(I6,a)
Aa.A ,$
A.aA ,$ Same as I6
A.b ,$
GOTO(I6,A)
AaA. ,$ I9 GOTO(I6,b)
Ab. ,$ Same as I7
BOTTOM UP PARSER
CLR
There is no multiple entries in the
PARSING TABLE FOR CLR Table so the grammar is CLR
ACTION GOTO
STATES
a b $ S A
I0 S3 S4 1 2
I1 ACCEPT
I2 S6 S7 5
I3 S3 S4 8
I4 R3 R3
I5 R1
I6 S6 S7 9
I7 R3
I8 R2 R2
I9 R2
BOTTOM UP PARSER
LALR
There is no multiple entries in the
PARSING TABLE FOR LALR Table so the grammar is LALR
ACTION GOTO
STATES
a b $ S A
I0 S36 S47 1 2
I1 ACCEPT
I2 S36 S47 5
I36 S36 S47 89
I47 R3 R3 R3
I5 R1

I89 R2 R2 R2
BOTTOM UP PARSER
CLR/LALR
Find whether the grammar is CLR or not?
SAaAb
SBbBa
A Ꜫ
B Ꜫ
BOTTOM UP PARSER
CLR

Sol:
STEP1:Augmented STEP2: Closure
grammar S’.S , $
S’S S.AaAb , $
SAaAb S.BbBa , $ I0
SBbBa A. , a
AꜪ B. , b
B Ꜫ
BOTTOM UP PARSER
CLR
Sol: GOTO(I0,B)
GOTO(I0,S) SB.bBa , $
I3
S’S. ,$ I1
GOTO(I2,a)
SAa.Ab , $
A. ,
I4
b
GOTO(I0,A)
SA.aAb , $
I2 GOTO(I3,b)
SBb.Ba , $
B. , a
I5
BOTTOM UP PARSER
CLR
Sol: GOTO(I6,b)
GOTO(I4,A) $
SAaAb. , I8
SAaA.b , $ I6
GOTO(I7,a)
SBbBa. , $ I9
GOTO(I5,B)
SBbB.a , $
I7
BOTTOM UP PARSER
CLR
There is no multiple entries in the
PARSING TABLE FOR CLR Table so the grammar is CLR
ACTION GOTO
STATES
a b $ S A B
I0 R3 R4 1 2 3
I1 ACCEPT
I2 S4
I3 S5
I4 R3 6
I5 R4 7
I6 S8
I7 S9
I8 R1
I9 R2
LL vs LR
LL LR
Does a leftmost derivation. Does a rightmost derivation in reverse.
Starts with the root non terminal on the Ends with the root non terminal on the
stack. stack.
Ends when the stack is empty. Starts with an empty stack.
Uses the stack for designating what is still Uses the stack for designating what is
to be expected. already seen.
Builds the parse tree top-down. Builds the parse tree bottom-up.
Continuously pops a non terminal off the Tries to recognize a right hand side on the
stack, and pushes the corresponding right stack, pops it, and pushes the
hand side. corresponding non terminal.
Expands the non-terminals. Reduces the non-terminals.
Reads the terminals when it pops one off Reads the terminals while it pushes them
the stack. on the stack.
Pre-order traversal of the parse tree. Post-order traversal of the parse tree.
Parser Conflicts
How to handle Ambiguous grammar in LR parser:
An LR parser may encounter two types of conflicts :
• Shift-Reduce Conflicts
• Reduce-Reduce Conflicts
It can be resolved by using following methods:
• The SR conflict in the parsing table is resolved by favouring the shift
action over reduced action.
• The RR conflict in the parsing table is resolved by favouring first
reduced over second reduced action.
NOTE:
• The parser generator tool YACC also resolves the conflict in the
above manner.
• If the grammar is expression grammar then the conflicts SR and RR
are resolved based on the precedence's of the operation

You might also like