0% found this document useful (0 votes)
657 views9 pages

Ambiguity: E E+E - E E - (E) - Id

1. Ambiguity in programming language grammars occurs when a string has more than one possible parse tree or derivation, leaving the meaning unclear. 2. There are two main ways to address ambiguity: rewriting the grammar or using parser generator declarations. 3. Rewriting the grammar involves splitting expressions into nonterminals by precedence level. Declarations allow specifying precedence and associativity to disambiguate an ambiguous grammar. 4. Other sources of ambiguity include the dangling else problem, which can be addressed by distinguishing between matched and unmatched if statements.

Uploaded by

Aravindh C
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)
657 views9 pages

Ambiguity: E E+E - E E - (E) - Id

1. Ambiguity in programming language grammars occurs when a string has more than one possible parse tree or derivation, leaving the meaning unclear. 2. There are two main ways to address ambiguity: rewriting the grammar or using parser generator declarations. 3. Rewriting the grammar involves splitting expressions into nonterminals by precedence level. Declarations allow specifying precedence and associativity to disambiguate an ambiguous grammar. 4. Other sources of ambiguity include the dangling else problem, which can be addressed by distinguishing between matched and unmatched if statements.

Uploaded by

Aravindh C
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/ 9

Ambiguity

„ Defining
„ Rewriting:
„ Expression Grammars
„ precedence
„ associativity
„ IF-THEN-ELSE
„ the Dangling-ELSE problem
„ Declarations
„ Expression Grammars
„ precedence
„ Associativity
„ Readings: Sections 4.2, 4.3

Ambiguity = program
structure not uniquely defined
E → E+E | E*E | (E) | id

String id * id + id has two parse trees:


E E

E + E E * E

E * E id id E + E

id id id id

1
Ambiguity
„ A grammar is ambiguous if, for any string
„ it has more than one parse tree, or
„ there is more than one right-most derivation, or

„ there is more than one left-most derivation

(the three conditions are equivalent)

„ Ambiguity is BAD
„ Leaves meaning of some programs ill-defined

Dealing with Ambiguity


„ There are several ways to handle
ambiguity
„ We will discuss two of them:
„ rewriting the grammar
„ parser-generator declarations

2
Expression Grammars
(precedence)
„ Rewrite the grammar
„ use a different nonterminal for each precedence
level
„ start with the lowest precedence (MINUS)

E Æ E - E | E / E | ( E ) | id

rewrite to

E Æ E-E | T
T Æ T/T | F
F Æ id | ( E )

Example
parse tree for id – id / id E

E Æ E-E | T E - E
T Æ T/T | F T
F Æ id | ( E ) T
T / T
F
F F
id
id id

3
Example: Preventing
Ambiguity
„ Question: can we construct parse tree
for id-id/id that shows the wrong
precedence?

Associativity
„ The grammar captures operator precedence,
but it is still ambiguous!
„ fails to express that both subtraction and division
are left associative;
„ e.g., 5-3-2 is equivalent to: ((5-3)-2) and not to: (5-(3-
2))

„ Example: two parse trees for the expression


5-3-2 using the grammar given above; one
that correctly groups 5-3, and one that
incorrectly groups 3-2

4
Recursion
„ Grammar is recursive in nonterminal X if:
„ X Æ+ … X …
„ Æ+ means “in one or more steps, X derives a sequence
of symbols that includes an X”
„ Grammar is left recursive in X if:
„ X Æ+ X …
„ in one or more steps, X derives a sequence of symbols
that starts with an X
„ A grammar is right recursive in X if:
„ X Æ+ … X
„ in one or more steps, X derives a sequence of symbols
that ends with an X

How to fix associativity


„ The grammar given above is both left and
right recursive in nonterminals exp and term
„ try this: write the derivation steps that show this
„ To correctly expresses operator associativity:
„ For left associativity, use left recursion
„ For right associativity, use right recursion
„ Here's the correct grammar:
E Æ E–T | T
T Æ T/F | F
F Æ id | ( E )

5
Ambiguity: The Dangling Else
„ Consider the grammar
E → if E then E
| if E then E else E
| print

„ This grammar is also ambiguous

The Dangling Else: Example


„ The expression
if E1 then if E2 then E3 else E4
has two parse trees
if if

E1 if E4 E1 if

E2 E3 E2 E3 E4

• Typically we want the second form

6
The Dangling Else: A Fix
„ else matches the closest unmatched then
„ We can describe this in the grammar
E → MIF /* all then are matched */
| UIF /* some then are unmatched */
MIF → if E then MIF else MIF
| print
UIF → if E then E
| if E then MIF else UIF
„ Describes the same set of strings

The Dangling Else: Example


Revisited
„ The expression if E1 then if E2 then E3 else E4
if if

E1 if E1 if E4

E2 E3 E4 E2 E3

• A valid parse tree • Not valid because the


(for a UIF) then expression is not
a MIF

7
Precedence and Associativity
Declarations
„ Instead of rewriting the grammar
„ Use the more natural (ambiguous) grammar
„ Along with disambiguating declarations

„ Most parser generators allow precedence and


associativity declarations to disambiguate
grammars

„ Examples …

Associativity Declarations
„ Consider the grammar E → E - E | int
„ Ambiguous: two parse trees of int - int - int
E E

E - E E - E

E - E int int E - E

int int int int

• Left associativity declaration: %left +

8
Precedence Declarations
„ Consider grammar E → E + E | E * E | int
„ And the string int + int * int
E E

E * E E + E

E + E int int E * E

int int int int


• Precedence declarations: %left +
%left *

You might also like