Ambiguous grammars
• Ambiguousgrammars are not LR(1):
oAny ambiguous grammar cannot be parsed using LR(1) techniques or any of
the parsing methods we discussed earlier
oThis is because LR parsers need a unique way to derive each sentence, and
ambiguity creates multiple possible parse trees
• Use them only when necessary and in a controlled manner
• If ambiguity is not well managed, the parser might not recognize the
correct language, leading to unpredictable behavior
4.
Why do weuse ambiguous grammars?
• Shorter and more natural specifications:
oFor certain language features like expressions, an ambiguous
grammar is simpler and easier to write than a complex unambiguous version
oExample: Operator precedence and associativity rules in arithmetic
expressions can be handled naturally with ambiguity
• Special case optimization:
oSometimes, it helps to separate frequently occurring syntax
patterns for performance improvements in parsing
oAmbiguous rules allow us to define such cases without making the grammar
overly complex
5.
How do wehandle ambiguity?
• Even if we use an ambiguous grammar, we must define rules to
remove ambiguity
• These rules ensure that each sentence has only one valid parse tree
oExample: Operator precedence and associativity rules in compilers (e.g., * has
higher precedence than +)
• If done properly, an LR parser can still be designed to follow the same
choices for resolving ambiguity
6.
Operator precedence parsing
•LR parsers sometimes face conflicts where the parser can either shift
or reduce
• This happens when a grammar allows multiple valid ways to derive a
sentence (e.g., a + b * c)
• Without extra rules, an LR parser cannot decide which action to take
• Operators are assigned precedence levels
7.
How do precedenceand associativity
resolve conflicts?
• When a shift-reduce conflict occurs, the parser uses operator
precedence to decide:
• If the current operator has higher precedence than the previous one, the
parser shifts (keeps reading more input)
• If the previous operator has higher precedence, the parser reduces (applies
a grammar rule)
• Associativity rules tell the parser which direction to group operators (left-to-
right or right-to-left)
• This helps in cases where two operators of the same precedence appear next to each other
8.
Implementation
• Instead ofrewriting the grammar to be unambiguous, we annotate the
operators with precedence and associativity
• Parser generators like YACC or Bison allow defining precedence and
associativity to resolve conflicts automatically
• Example (YACC/Bison):
• %left '+' '-'
• %left '*' '/'
• Parser generators resolve left associativity by reducing before shifting
• This tells the parser:
• * and / have higher precedence than + and -
• + and - are left-associative