4 6 ambiguity of grammars
play

4.6: Ambiguity of Grammars In this section, we say what it means for - PowerPoint PPT Presentation

4.6: Ambiguity of Grammars In this section, we say what it means for a grammar to be ambiguous. We also give a straightforward method for disambiguating grammars for languages with operators of various precedences and associativities, and


  1. 4.6: Ambiguity of Grammars In this section, we say what it means for a grammar to be ambiguous. We also give a straightforward method for disambiguating grammars for languages with operators of various precedences and associativities, and consider an efficient parsing algorithm for such disambiguated grammars. 1 / 16

  2. Motivating Example Suppose G is our grammar of arithmetic expressions: E → E � plus � E | E � times � E | � openPar � E � closPar � | � id � . Question: are there multiple ways of parsing the string � id �� times �� id �� plus �� id � according to this grammar? Answer: 2 / 16

  3. Motivating Example Suppose G is our grammar of arithmetic expressions: E → E � plus � E | E � times � E | � openPar � E � closPar � | � id � . Question: are there multiple ways of parsing the string � id �� times �� id �� plus �� id � according to this grammar? Answer: Yes: E E E � plus � E E � times � E E � times � E � id � � id � E � plus � E � id � � id � � id � � id � ( pt 1 ) ( pt 2 ) 2 / 16

  4. Definition In pt 1 , multiplication has higher precedence than addition; in pt 2 , the situation is reversed. Because there are multiple ways of parsing this string, we say that our grammar is “ambiguous”. A grammar G is ambiguous iff there is a w ∈ ( alphabet G ) ∗ such that w is the yield of multiple valid parse trees for G whose root labels are s G ; otherwise, G is unambiguous . 3 / 16

  5. Examples The grammar A → % | 0A1A | 1A0A is a grammar generating all elements of { 0 , 1 } ∗ with a diff of 0, for the diff function such that diff 0 = − 1 and diff 1 = 1. It is 4 / 16

  6. Examples The grammar A → % | 0A1A | 1A0A is a grammar generating all elements of { 0 , 1 } ∗ with a diff of 0, for the diff function such that diff 0 = − 1 and diff 1 = 1. It is ambiguous as, e.g., 0101 can be parsed as 0%1(01) or 0(10)1%. 4 / 16

  7. Examples The grammar A → % | 0A1A | 1A0A is a grammar generating all elements of { 0 , 1 } ∗ with a diff of 0, for the diff function such that diff 0 = − 1 and diff 1 = 1. It is ambiguous as, e.g., 0101 can be parsed as 0%1(01) or 0(10)1%. In Section 4.5, we saw another grammar for this language: A → % | 0BA | 1CA , B → 1 | 0BB , C → 0 | 1CC , which turns out to be 4 / 16

  8. Examples The grammar A → % | 0A1A | 1A0A is a grammar generating all elements of { 0 , 1 } ∗ with a diff of 0, for the diff function such that diff 0 = − 1 and diff 1 = 1. It is ambiguous as, e.g., 0101 can be parsed as 0%1(01) or 0(10)1%. In Section 4.5, we saw another grammar for this language: A → % | 0BA | 1CA , B → 1 | 0BB , C → 0 | 1CC , which turns out to be unambiguous. The reason is that Π B is all elements of { 0 , 1 } ∗ with a diff of 1, but with no proper prefixes with positive diff ’s, and Π C has the corresponding property for 0/negative. 4 / 16

  9. Disambiguating Grammars of Operators Not every ambiguous grammar can be turned into an equivalent unambiguous one. However, we can use a simple technique to disambiguate our grammar of arithmetic expressions, and this technique works for many commonly occurring grammars involving operators of various precedences and associativities. Since there are two binary operators in our language of arithmetic expressions, we have to decide: 5 / 16

  10. Disambiguating Grammars of Operators Not every ambiguous grammar can be turned into an equivalent unambiguous one. However, we can use a simple technique to disambiguate our grammar of arithmetic expressions, and this technique works for many commonly occurring grammars involving operators of various precedences and associativities. Since there are two binary operators in our language of arithmetic expressions, we have to decide: • whether multiplication has higher or lower precedence than addition; and 5 / 16

  11. Disambiguating Grammars of Operators Not every ambiguous grammar can be turned into an equivalent unambiguous one. However, we can use a simple technique to disambiguate our grammar of arithmetic expressions, and this technique works for many commonly occurring grammars involving operators of various precedences and associativities. Since there are two binary operators in our language of arithmetic expressions, we have to decide: • whether multiplication has higher or lower precedence than addition; and • whether multiplication and addition are left or right associative. 5 / 16

  12. Disambiguating Grammars of Operators Not every ambiguous grammar can be turned into an equivalent unambiguous one. However, we can use a simple technique to disambiguate our grammar of arithmetic expressions, and this technique works for many commonly occurring grammars involving operators of various precedences and associativities. Since there are two binary operators in our language of arithmetic expressions, we have to decide: • whether multiplication has higher or lower precedence than addition; and • whether multiplication and addition are left or right associative. As usual, we’ll make multiplication have higher precedence than addition, and let addition and multiplication be left associative. 5 / 16

  13. Example Disambiguation As a first step towards disambiguating our grammar, we can form a new grammar with the three variables: E (expressions), T (terms) and F (factors), start variable E and productions: E → T | E � plus � E , T → F | T � times � T , F → � id � | � openPar � E � closPar � . The idea is that the lowest precedence operator “lives” at the highest level of the grammar, that the highest precedence operator lives at the middle level of the grammar, and that the basic expressions, including the parenthesized expressions, live at the lowest level of the grammar. 6 / 16

  14. Example Disambiguation Now, there is only one way to parse the string � id �� times �� id �� plus �� id � , since, if we begin by using the production E → T, our yield will only include a � plus � if this symbol occurs within parentheses. If we had more levels of precedence in our language, we would simply add more levels to our grammar. 7 / 16

  15. Example Disambiguation On the other hand, there are still two ways of parsing the string � id �� plus �� id �� plus �� id � : with left associativity or right associativity. To finish disambiguating our grammar, we must 8 / 16

  16. Example Disambiguation On the other hand, there are still two ways of parsing the string � id �� plus �� id �� plus �� id � : with left associativity or right associativity. To finish disambiguating our grammar, we must break the symmetry of the right-sides of the productions E → E � plus � E , T → T � times � T , turning one of the E’s into T, and one of the T’s into F. To make our operators be left associative, we must 8 / 16

  17. Example Disambiguation On the other hand, there are still two ways of parsing the string � id �� plus �� id �� plus �� id � : with left associativity or right associativity. To finish disambiguating our grammar, we must break the symmetry of the right-sides of the productions E → E � plus � E , T → T � times � T , turning one of the E’s into T, and one of the T’s into F. To make our operators be left associative, we must use left recursion , changing the second E to T, and the second T to F; right associativity would result from making the opposite choices, i.e., using right recursion . 8 / 16

  18. Example Disambiguation Thus, our unambiguous grammar of arithmetic expressions is E → T | E � plus � T , T → F | T � times � F , F → � id � | � openPar � E � closPar � . It can be proved that this grammar is indeed unambiguous, and that it is equivalent to the original grammar. 9 / 16

  19. Example Disambiguation Now, the only parse of � id �� times �� id �� plus �� id � is E E � plus � T T F T � times � F � id � F � id � � id � 10 / 16

  20. Example Disambiguation And, the only parse of � id �� plus �� id �� plus �� id � is E E � plus � T E � plus � T F T F � id � F � id � � id � 11 / 16

  21. Top-down Parsing for Grammars of Operators Top-down parsing is a simple and efficient parsing method for unambiguous grammars of operators like E → T | E � plus � T , T → F | T � times � F , F → � id � | � openPar � E � closPar � . 12 / 16

  22. Parsing Let E , T and F be all of the parse trees that are valid for our grammar, have yields containing no variables, and whose root labels are E, T and F, respectively. Because this grammar has three mutually recursive variables, we will need three mutually recursive parsing functions, parE ∈ Str → Option ( E × Str ) , parT ∈ Str → Option ( T × Str ) , parF ∈ Str → Option ( F × Str ) , which attempt to parse an element pt of E , T or F out of a string w , returning none to indicate failure, and some ( pt , y ), where y is the remainder of w , otherwise. 13 / 16

  23. Parsing Given a string w , parE operates as follows. Because all elements of E have yields beginning with the yield of an element of 14 / 16

Recommend


More recommend