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

Compiler Unit 2 ...5

Uploaded by

siyadogra98
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

Compiler Unit 2 ...5

Uploaded by

siyadogra98
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 71

Learn Compiler Design From B K Sharma

Unit II: Basic Parsing


Techniques :

Ambiguity in CFG and Removal


Learn Compiler Design From B K Sharma

Unit II: Syllabus


• Syntax Analysis and Syntax Directed
Translation
• Syntax Analysis:
– CFGs
– Top Down Parsing
– Brute Force Approach
– Recursive Descent Parsing
– Transformation on the grammars
Learn Compiler Design From B K Sharma

Unit II: Syllabus


– Predictive Parsing
– Bottom Up Parsing
– Operator Precedence Parsing
– LR Parsers
• SLR,
• LALR
• LR
• Parser Generator
Learn Compiler Design From B K Sharma

Unit II: Syllabus

• Syntax Directed Definitions


– Construction of syntax trees
– Bottom Up Evaluation of S-attributed
definition
– L-attribute Definition
– Top Town translation
– Bottom Up Evaluation of inherited attributes
– Recursive Evaluation
– Analysis of Syntax Directed Definition
Learn Compiler Design: From B. K. Sharma
Summary of Lesson 14: Syntax Analysis and CFG
1: Basis of Parsing is context-free grammar (CFG) which
describes context free languages.
2: Context free grammar G can be defined by four tuples
as: G=(V,T,S,P)
3: Two types of derivations are left-most derivations and
right-most derivations.
4: Every parse tree corresponds to:
A single, unique leftmost derivation
A single, unique right most derivation
6:However, one input string may have several parse tree!!!!
Learn Compiler Design: From B. K. Sharma

Mapping of Lesson with Course Outcome


(CO)
Lesson CO3
Lesson 13: Parsing or Understand LL, LR,
Syntax Analysis and SLR parsing
techniques.
Learn Compiler Design From B K Sharma

Ambiguous Grammars
अनिनितता
A grammar is ambiguous if there exists a
string w that can be derived by at least two
different parse trees.

Ambiguity implies multiple parse trees for


same string w.

Equivalently, there is more than one


rightmost or leftmost derivation for same
string.
Learn Compiler Design From B K Sharma

Ambiguous Grammars
E ® E + E | E * E | (E) | a
a + a*a
E E Þ E + E Þ a+ E Þ a+ E*E
Þ a + a* E Þ a + a*a
E + E
leftmost derivation

a E * E

a a
Learn Compiler Design From B K Sharma

Ambiguous Grammars

E ® E + E | E * E | (E) | a
a + a*a
E Þ E*E Þ E + E*E Þ a+ E*E E
Þ a + a*E Þ a + a*a
E * E
leftmost derivation

E + E a

a a
Learn Compiler Design From B K Sharma

Ambiguous Grammars

The grammar E ® E + E | E * E | (E) | a


is ambiguous:
string a + a*a has two leftmost derivations

E Þ E + E Þ a+ E Þ a+ E*E
Þ a + a* E Þ a + a*a
E Þ E*E Þ E + E*E Þ a+ E*E
Þ a + a*E Þ a + a*a
Learn Compiler Design From B K Sharma

Ambiguous Grammars

The grammar E ® E + E | E * E | (E) | a


is ambiguous:
string a + a*a has two derivation trees
E E

E + E E * E

a E * E E + E a

a a a a
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


One- Minute Paper
Consider the following expression and two
parse tree:
a + a*a
take a = 2

And evaluate the expression using two parse trees


and find which parse tree give correct answer?
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?


a + a*a
take a = 2
E E

E + E E * E

a E * E E + E a

a a a a
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?

2 + 2*2
E E

E + E E * E

2 E * E E + E 2

2 2 2 2
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?


2 + 2*2 = 6 2 + 2*2 = 8
6 8
E E
2 4 4 2
E + E E * E
2 2 2 2
2 E * E E + E 2

2 2 2 2
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?


Correct result: 2 + 2*2 = 6
6
E
2 4
E + E
2 2
2 E * E

2 2
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?

Ambiguous grammars should be avoided:

Do not guarantee unique parsing and


translation
Expression evaluation is not clearly defined
in this grammar
Different parse trees can have different
semantic meanings, yield different execution
results.
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?

Ambiguity is bad for programming languages ,


where we want agreement between the
programmer and compiler over what happens.

Can make parsing more difficult.

Can impact the semantics of the language.

Leaves meaning of some programs ill-


defined.
Learn Compiler Design From B K Sharma

Why do we care about ambiguity?

Ambiguity is common in programming


languages due to problem in context
free grammar:
Ambiguity in Arithmetic Expression
Ambiguity in IF-THEN-ELSE
Learn Compiler Design From B K Sharma

How to fix the ambiguous grammar?


Dealing with Ambiguity
The most direct method to deal with
ambiguity is to rewrite the grammar
unambiguously.
The new grammar should accept the
same language.
There is no general algorithm to rewrite
ambiguous grammars.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle ambiguity in expressions:
The precedence and associativity of operators
specify order of evaluation.
Higher precedence operators are evaluated
first.
Equal precedence operators are evaluated
according to associativity.
Left-to-right or Right-to-left.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle ambiguity in expressions:
+, -, *, / are left associative and ^
has right associative
5- 3 - 2 is equivalent to ((5-3)-2)
Not to (5- (3-2))
2^3^2 is evaluated to (2^(3^2))
Not to ((2^3)^2)
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?

To handle associativity of operators:

We design grammar rules to be either


left or right recursive.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Consider the expression: 2 + 2*2
* has more priority than +
The correct answer is : (2+(2*2))=6
G1 E → E + E
| E * E
| id
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
G1 E → E + E is ambiguous.
| E * E
| id

The “+” having the least priority has to be


at the upper level and has to wait for the
result produced by the “*” operator which is
at the lower level.

So, the first parse tree is the correct one


and gives the same result as expected.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
G1 E → E + E
| E * E
| id

The unambiguous grammar will contain


the productions having the highest
priority operator (“*” in the
example) at the lower level and vice
versa.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Ambiguous Unambiguous grammar:
G1 E → E + E G1’ E → E + P
E → P
| E * E
P → P * Q
| id
P → Q
Re-Write G1 Q → id
+ is at higher level and left associative
* is at lower level and left associative
E is used for doing addition operations and P is used to perform
multiplication operations.
They are independent and will maintain the precedence order in the
parse tree.
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Parse the id + id * id using the following
grammar and draw the Parse Tree:
Unambiguous grammar:
G1’ E → E + P
E → P
P → P * Q
P → Q
Q → id
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Parse the id + id * id + id using the
following grammar and draw the Parse Tree:
Unambiguous grammar:
G1’ E → E + P
E → P
P → P * Q
P → Q
Q → id
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Rewrite the following Ambiguous grammar
Ambiguous grammar
G2 E →E-E
| E * E
| E ^E
| id
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
ANSWER
Unambiguous grammar:
Ambiguous grammar
G2’ E → E – P
| P
G2 E →E-E P → P * Q
| E * E | Q
| E ^E Re-Write G2 Q → R ^ Q
| id | R
R → id
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Parse the id - id * id - id using the
following grammar and draw the Parse Tree:
Unambiguous grammar:

G2’ E → E – P
| P
P → P * Q
| Q
Q → R ^ Q
| R
R → id
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
ANSWER: id - id * id - id
E
E P
E P
-
-
Q
P P Q
*
Q R
Q R
id
R R id
id id
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Let us consider the following grammar:
Ambiguous grammar Parsing of the string:
G3 expr  expr op expr
id + id * id
| (expr)
| id
| num We get two Parse Trees:
op  + | - | * | /
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Let us consider the following grammar:
Ambiguous grammar Unambiguous grammar:
G3 expr  expr op expr expr  expr addminus term
| (expr) | term
| id term term multdiv factor
| num term  factor
op  + | - | * | / factor  (expr)
| id
| num
addminus  + | -
multdiv  *| /
G 3’
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle precedence of operators:

We divide operators into groups of


equal precedence.
For each precedence level, we
introduce a non-terminal and grammar
rules.
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Let us consider the following Unambiguous
grammar:
Unambiguous grammar: Parsing of
the string:

G3’ id + id * id
And see the
difference between
G3 and G3’?
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
ANSWER
Parsing of the string:
id + id * id

addminus

multdiv
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
Let us consider the following Unambiguous
grammar:
Unambiguous grammar: Parsing of
the string:

G3’ id - id + id
And see the
difference between
G3 and G3’?
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


Minute Paper
ANSWER
Parsing of the string:
id - id + id

addminus

addminus
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
We design grammar rules to be either
left or right recursive.
Let us consider a grammar:

G4 E → E-E Parsing of the string:


| id
id-id-id.
We get two parse trees as follows inn the next Slide:
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
G4 E → E-E Parsing of the string:
| id
id-id-id.

Which one is correct?

Parse Tree 1 Parse Tree 2


Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
id-id-id. Let’s consider a single value of id=3
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Point to Note down:

For the same priority operators, we need to


consider associativity which is left to right.

The parse tree which grows on the left side


of the root will be the correct parse tree in
order to make the grammar unambiguous.
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
To convert ambiguous grammar to
unambiguous grammar, we will apply the
following rules:
1: If the left associative operators (+, -, *, /)
are used in the production rule, then apply
left recursion in the production rule.
For example:
X → Xα
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
To convert ambiguous grammar to
unambiguous grammar, we will apply the
following rules:
2: If the right associative operates(^) is used
in the production rule then apply right
recursion in the production rule.
For example:
X → αX
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
Left and Right Recursion
Left recursion means that the leftmost
symbol on the right side is the same as the
non-terminal on the left side.(X → X α )
Right recursion means that the rightmost
symbol on the left side is the same as the
non-terminal on the right side. (X → αX )
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
Ambiguous Grammar Unambiguous grammar:
E → E-E E → E – P
G4 | id E → P
Re-Write G4 G’4 P → id
So, to make the above grammar unambiguous,
simply make the grammar Left Recursive by
replacing the right most non-terminal E in the
right side of the production with another random
variable, say P.
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


One- Minute Paper
Let us consider the following Unambiguous
grammar:
Unambiguous grammar: Parse the string:

E → E – P
id -id - id
G4’ E → P take id=3
P → id

And see the


difference between
G4 and G4’?
Learn Compiler Design: From B. K. Sharma

Active Learning Activity


One- Minute Paper
ANSWER
Parsing of the string:
id - id – id taking id=3
Learn Compiler Design From B K Sharma

How to deal with ambiguity in


Arithmetic expressions?
To handle associativity of operators:
Let us consider the grammar:

G5 E→ E^E | id

If we derive string 2^3^2, there will be


two parse trees:
Ambiguous Grammar Unambiguous grammar:
G5 E→ E^E | id E → P ^ E | P
P → id
Re-Write G5
Learn Compiler Design From B K Sharma

How to rewrite the grammar to


deal with Ambiguity of Else in If
statement
?

AKA

Dangling Else Problem


Learn Compiler Design From B K Sharma

Dangling Else Problem


Consider the following grammar for if
statements:
stmt  if-stmt | while-stmt | … Ambiguous Grammar
if-stmt  if expr then stmt else stmt
| if expr then stmt

Dangling means hanging.

Dangling Else means hanging else.


This means which if the else should be
associated.
Learn Compiler Design From B K Sharma

What is Dangling Else Problem?

When there is multiple if and a single else,


then else part does not get a clear view to
go with which if, this problem is called
dangling else problem.
if expr then s [No Problem]

if expr then s1 else s2 [No Problem]

if expr1 then if expr2 then s1 else s2 [Problem]


Learn Compiler Design From B K Sharma

What is Dangling Else Problem?


Parse: if E1 then if E2 then S1 else S2

Case I: E1=True and E2= True

if E1 then if E2 then S1 else S2

True True Executed


Case II: E1=False and E2= True
if E1 then if E2 then S1 else S2

False True Which stmt executed?


Learn Compiler Design From B K Sharma

What is Dangling Else Problem?


Parse: if E1 then if E2 then S1 else S2
Case II: E1=False and E2= True

if E1 then if E2 then S1 else S2

False True Which stmt executed?

if E1 then if E2 then S1 else S2

Executed
One may associate else with first if.
Learn Compiler Design From B K Sharma

What is Dangling Else Problem?


Parse: if E1 then if E2 then S1 else S2
Case III: E1=True and E2= False
if E1 then if E2 then S1 else S2

True False Which stmt executed?

if E1 then if E2 then S1 else S2

Executed

One may associate else with second if.


Learn Compiler Design From B K Sharma

What is Dangling Else Problem?

In this example, S1 is unambiguously


executed when E1 is true and E2 is
true.
But one may interpret S2 as being
executed when E1 is false (thus
attaching the else to the first if) or
when E1 is true and E2 is false (thus
attaching the else to the second if).
Learn Compiler Design From B K Sharma

What is Dangling Else Problem?


stmt  if-stmt | while-stmt | …
if-stmt  if expr then stmt else stmt
| if expr then stmt

Parse: if E1 then if E2 then S1 else S2


Thus one may interpret the above statements in
either of the two ways:

if E1 then [if E2 then S1] else S2

if E1 then [if E2 then S1 else S2]


Learn Compiler Design From B K Sharma

What is Dangling Else Problem?


stmt  if-stmt | while-stmt | …
if-stmt  if expr then stmt else stmt
| if expr then stmt
Parse: if E1 then if E2 then S1 else S2
Two Parse Trees
if-stmt if-stmt

if expr then stmt else stmt if expr then stmt

E1 if-stmt S2 E1 if-stmt

if expr then stmt if expr then stmt else stmt

E2 S1 E2 S1 S2
Learn Compiler Design From B K Sharma

What is Dangling Else Problem?

The two parse trees translate differently


the else part
The else part can be attached to inner if
(should be the case) or to outer if.

Desired semantics

Match the else with the closest if.


Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
How to rewrite the if-stmt grammar to eliminate
ambiguity?

By defining different if statements


matched-stmt and unmatched-stmt
stmt  if-stmt | while-stmt | …
Original Grammar
if-stmt  if expr then stmt else stmt
| if expr then stmt
Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
stmt  if-stmt | while-stmt | …
Ambiguous Grammar
if-stmt  if expr then stmt else stmt
| if expr then stmt
Unambiguous Grammar
if-stmt  matched-stmt
| unmatched-stmt
matched-stmt  if expr then matched-stmt else matched-stmt

unmatched-stmt if expr then matched-stmt else unmatched-stmt

unmatched-stmt if expr then if-stmt(both)


Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
if-stmt  matched-stmt
| unmatched-stmt
The if-stmt of type:
if E1 then S1 else S2
is called matched-stmt.
matched-stmt: does not have dangling if.
The if-stmt of type:
if E1 then if E2 then S1 else S2
is called unmatched-stmt.
unmatched-stmt: does have dangling if.
Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
if-stmt  matched-stmt
| unmatched-stmt
The if-stmt of type:
if E1 then if E2 then S1 else S2
is called unmatched-stmt.
unmatched-stmt: does have dangling if.

if E1 then if E2 then S1 else S2

Dangling if if can be paired with following else


Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
if-stmt  matched-stmt
| unmatched-stmt

if E1 then if E2 then S1 else S2 else if E3 then S3 else S4

matched-stmt matched-stmt

matched-stmt  if expr then matched-stmt else matched-stmt


Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
if E1 then if E2 then S1 else S2 else if E3 then if E4 then S3 else S4

unmatched-stmt
matched-stmt
unmatched-stmt
if E1 then matched-stmt
else unmatched-stmt
unmatched-stmt
unmatched-stmt if expr then matched-stmt else unmatched-stmt

if-stmt
unmatched-stmt if expr then if-stmt(both)
Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
stmt  if-stmt | while-stmt | …
Ambiguous Grammar
if-stmt  if expr then stmt else stmt
| if expr then stmt
Unambiguous Grammar
if-stmt  matched-stmt
| unmatched-stmt
matched-stmt  if expr then matched-stmt else matched-stmt

unmatched-stmt if expr then matched-stmt else unmatched-stmt

unmatched-stmt if expr then if-stmt(both)


Learn Compiler Design From B K Sharma

Eliminating Ambiguity of Else in If


Statements
Parse: if E1 then if E2 then S1 else S2
One Parse Tree
if-stmt

umatched-stmt

if-stmt
expr then
if
E1

if expr else unmatched-stmt


then matched-stmt
E2 S1 S2
Learn Compiler Design: From B. K. Sharma
Summary of Lesson 15: Ambiguity in CFG and
Removal
1: A grammar is ambiguous if there exists a string w that can be
derived by at least two different parse trees.
2: The most direct method to deal with ambiguity is to rewrite the
grammar unambiguously.
3: To handle ambiguity in expressions: the precedence and
associativity of operators specify order of evaluation:
4: Higher precedence operators are evaluated first.
Equal precedence operators are evaluated according to associativity:
Left-to-right or Right-to-left.
6: To handle associativity of operators: We design grammar rules
to be either left or right recursive.
7.: When there is multiple if and a single else, then else part does
not get a clear view to go with which if, this problem is called
dangling else problem.
Learn Compiler Design From B K Sharma

Read PPT named Top-down Parsing New

You might also like