Lec-18-19: Operator
precedence parser
Ambiguous grammars
• Ambiguous grammars 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
Why do we use 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
How do we handle 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
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
How do precedence and 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
Implementation
• Instead of rewriting 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
Precedence and associativity of C
operators
Images source: Programming in ANSI C book by E. Balagurusamy
Dangling else problem
Another example
Parsing a string

Operator_Precedence_Parser_Compiler.pptx

  • 1.
  • 2.
    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
  • 9.
  • 10.
    Images source: Programmingin ANSI C book by E. Balagurusamy
  • 11.
  • 12.
  • 13.