0% found this document useful (0 votes)
30 views51 pages

16 Ambiguity

The document discusses ambiguity in context-free grammars. It provides an example grammar that generates an ambiguous string with two possible parse trees. To resolve this ambiguity, the grammar can be rewritten by stratifying the productions into two classes - one for addition and one for multiplication - with a separate non-terminal for each operator. This ensures there is only one parse tree for each string generated by the grammar. The document also discusses how to handle ambiguity in if-then-else expressions by associating else with the closest unmatched then branch.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views51 pages

16 Ambiguity

The document discusses ambiguity in context-free grammars. It provides an example grammar that generates an ambiguous string with two possible parse trees. To resolve this ambiguity, the grammar can be rewritten by stratifying the productions into two classes - one for addition and one for multiplication - with a separate non-terminal for each operator. This ensures there is only one parse tree for each string generated by the grammar. The document also discusses how to handle ambiguity in if-then-else expressions by associating else with the closest unmatched then branch.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 51

Ambiguity

Arles Rodríguez
[email protected]

Facultad de Ciencias
Departamento de Matemáticas
Universidad Nacional de Colombia
Motivation
• Given the following grammar:

• And the string:

• How many parse trees we can generate?


Motivation
• How many parse trees we can generate?

𝐸
𝐸 +¿ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑
𝑖𝑑 𝑖𝑑
Motivation
• How many parse trees we can generate?

𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑 𝑖𝑑 𝐸 +¿ 𝐸
𝑖𝑑 𝑖𝑑 𝑖𝑑 𝑖𝑑
Motivation
• The string has two parse trees.

𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑 𝑖𝑑 𝐸 +¿ 𝐸
𝑖𝑑 𝑖𝑑 𝑖𝑑 𝑖𝑑
Motivation
• The string has two parse trees.

𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑 𝑖𝑑 𝐸 +¿ 𝐸
𝑖𝑑 𝑖𝑑 𝑖𝑑 𝑖𝑑
• Here we have two derivations that yields completely
different parse trees.
Ambiguous grammar
• A grammar is ambiguous if it has more than
one parse tree for some string.
– Equivalently, there is more than one right-most or
left most derivation for some string.
• Ambiguity is BAD:
– multiple parse trees for some program left the
compiler to pick which of those to possible
interpretations of the program.
– To generate code like this is not a good idea.
Exercise
Handling ambiguity
Handling Ambiguity
• There are several ways to handle ambiguity:
– Given:
– Most direct:
• Rewrite grammar unambiguously

• Generates the same language as old grammar but only


has a single parse tree for each string.
Handling Ambiguity: Rewrite grammar
unambiguously

𝐸

• Now E controls the generation of 𝐸 +𝐸
plus and controls the generation of
′ ′
multiplications 𝑖𝑑 ∗ 𝐸 𝐸
𝑖𝑑∗ 𝑖𝑑+𝑖𝑑 𝑖𝑑 𝑖𝑑
• This is known as stratify the grammar
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate: +
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

+
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate: +
There are summed together.
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
Stratify the grammar
• Consist of dividing the production in two
classes.
– One that handles plus
– One that handles times
• There is one non-terminal for each operator.

Can generate:
• Handles id multiplication
Stratify the grammar
• There is one non-terminal for each operator.

• Handles parenthesizes expressions.


Stratify the grammar
• By stratifying the grammar all the pluses must
be generated before any of the times.
• Times are going to be nested more deeply
inside the parse tree than the pluses.
Stratify the grammar
• There is one non-terminal for each operator.

– Last part show the explicit association that


indicates that we can have pluses inside of times
by using parentheses.
– Times binds more tightly than plus.
Ambiguity
• The string had two parse trees for grammar:

𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑 𝑖𝑑 𝐸 +¿ 𝐸
𝑖𝑑 𝑖𝑑 𝑖𝑑 𝑖𝑑
Ambiguity
• The string had only one parse tree for
grammar:

𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑑 𝑖𝑑 𝐸 +¿ 𝐸
𝑖𝑑 𝑖𝑑 𝑖𝑑 𝑖𝑑
Ambiguity
• The string had only one parse tree for
grammar:
Ambiguity
• The string had only one parse tree for
grammar:

𝐸
𝐸 ′
+¿ 𝐸
𝑖𝑑 ∗ 𝐸 𝐸 ′ ′

𝑖𝑑 𝑖𝑑
Another example
• Consider the grammar:

• The expression:

How many parse trees it has?


Another example: How many parse trees it
has?

• Consider the grammar:

• The expression:

Which one do we want in a programming language?


Another example: How many parse trees it
has?

• Consider the grammar: 𝐸


𝑖𝑓 𝐸 1 𝑡h𝑒𝑛 𝐸
𝑖𝑓 𝐸2 𝑡h𝑒𝑛 𝐸 3 𝑒𝑙𝑠𝑒 𝐸4

• The expression:

Which one do we want in a programming language?


Another example: How many parse trees it
has?

• Consider the grammar: 𝐸


𝑖𝑓 𝐸 1 𝑡h𝑒𝑛 𝐸
𝑖𝑓 𝐸2 𝑡h𝑒𝑛 𝐸 3 𝑒𝑙𝑠𝑒 𝐸4

• The expression: 𝐸
𝑖𝑓 𝐸 1 𝑡
𝑒𝑙𝑠𝑒
h𝑒𝑛 𝐸 𝐸
Which one do we want in a programming language?
𝑖𝑓 𝐸 2 𝑡h𝑒𝑛 𝐸 3
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest matching if 𝐸
• Consider the grammar:𝑖𝑓 𝐸 1 𝑡h𝑒𝑛 𝐸
𝑖𝑓 𝐸2 𝑡h𝑒𝑛 𝐸 3 𝑒𝑙𝑠𝑒 𝐸4
𝐸
𝑖𝑓 𝐸 1 𝑡
• We want the expression: 𝑒𝑙𝑠𝑒
h𝑒𝑛 𝐸 𝐸
𝑖𝑓 𝐸 2 𝑡h𝑒𝑛 𝐸 3
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest matching if
• Consider the grammar:
𝐸
𝑖𝑓 𝐸 1 𝑡h𝑒𝑛 𝐸
𝑖𝑓 𝐸2 𝑡h𝑒𝑛 𝐸 3 𝑒𝑙𝑠𝑒 𝐸4
• We want the expression:
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest unmatched then

• We can define
/*all then are matched */
/*some then is unmatched*/
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest unmatched then

• We can define
/*all then are matched */
/*some then is unmatched*/
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest unmatched then

• We can define
/*all then are matched */
/*some then is unmatched*/
Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest unmatched then

• We can define
/*all then are matched */
/*some then is unmatched*/

¿𝑖𝑓 𝐸 𝑡h𝑒𝑛𝑀𝐼𝐹 𝑒𝑙𝑠𝑒𝑈𝐼𝐹


Another example: How many parse trees it
has?
Which one do we want in a programming language?
• We want else associated to the closest unmatched then

• We can define
/*all then are matched */
Unmatched if
/*some then is unmatched*/
must be in the
else part.
Then branch
must be a
matched if
¿ 𝑖𝑓 𝐸 𝑡h𝑒𝑛𝑀𝐼𝐹 𝑒𝑙𝑠𝑒𝑈𝐼𝐹
Another example: How many parse trees it
has?
Given this grammar:
/*all then are matched */
/*some then is unmatched*/

¿𝑖𝑓 𝐸 𝑡h𝑒𝑛 𝑀𝐼𝐹 𝑒𝑙𝑠𝑒𝑈𝐼𝐹


The expression:

How many parse trees it has?


Another example: How many parse trees it
has?
Given this grammar:
𝑈𝐼𝐹
/*all then are matched */
/*some then is unmatched*/
𝑖𝑓 𝐸1 𝑡h𝑒𝑛 𝐸

𝑖𝑓 𝐸2 𝑡h𝑒𝑛 𝑀𝐼𝐹 𝑒𝑙𝑠𝑒 𝑀


¿ 𝑖𝑓 𝐸 𝑡h𝑒𝑛 𝑀𝐼𝐹 𝑒𝑙𝑠𝑒 𝑈𝐼𝐹
E3 E4
The expression:

How many parse trees it has?


Exercise
Considerations
• Is impossible to convert automatically an
ambiguous grammar to an unambiguous one.
• Used with care, ambiguity can simplify the
grammar
– Allows more natural definitions
– We need disambiguation mechanisms
• Some way to tell which parse tree we want when more
than once parse tree is possible.
Considerations
• In practice, most practical tools:
– Use the more natural (ambiguous) grammar.
– Along disambiguation declarations.
• Some way to tell which parse tree we want when more
than once parse tree is possible.
• Most popular form of disambiguation are:
– Precedence and associativity declarations.
Ambiguity: Example 1
• Consider the grammar:

• This grammar is ambiguous because has two


possible parse trees
𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 + 𝐸
𝐸 +¿ 𝐸 ∫¿ 𝑖𝑛𝑡 𝐸 +¿ 𝐸
∫¿ ∫¿ 𝑖𝑛𝑡 𝑖𝑛𝑡
Ambiguity
• is ambiguous because has two possible parse
trees.
𝐸 𝐸
𝐸 +¿ 𝐸 𝐸 + 𝐸
𝐸 +¿ 𝐸 ∫¿ 𝑖𝑛𝑡 𝐸 +¿ 𝐸
∫¿ ∫¿ 𝑖𝑛𝑡 𝑖𝑛𝑡
• We can get ambiguity because grammar does not tell us
whether plus is left associative or right associative.
Ambiguity

• Simple solution: to 𝐸
have associativity
declarations.
𝐸 +¿ 𝐸
• We can declare plus to 𝐸 +¿ 𝐸 ∫¿
be left associative. In ∫¿ ∫¿
bison: %left +
Ambiguity: Example 2
• Consider the grammar:

• And the string:

𝐸 𝐸
𝐸 𝐸+¿ 𝐸 ∗ 𝐸
𝐸 ∗ 𝐸 𝑖𝑛𝑡 𝑖𝑛𝑡 𝐸 +¿ 𝐸
𝑖𝑛𝑡 𝑖𝑛𝑡 𝑖𝑛𝑡 𝑖𝑛𝑡
Ambiguity: Example 2
• Consider the grammar:

• And the string:

• Grammar is ambiguous because it does not say


precedence of times with respect to plus.
• We can have multiple associative declarations:
• + can be left associative %left +
Precedence
• * can be left associative %left *
is given by
• In bison * after + means higher priority
the order
Caution
• Declarations are called associativity and
precedence declarations.
• This is not going on inside the parser.
• The parser does not really understand about
associativity and precedence.
• Declarations tell it to make certain kind of moves
in certain situations.
• Is important to check the behavior of your
grammar after you add this declarations.
¡Thank you!
References
• Aho et al. Compilers: principles, techniques, and
tools. Torczon et al. (2014) (Section 4.2)
• Slides are based on the design of Aiken Alex. CS 143.
https://web.stanford.edu/class/cs143/

You might also like