Ten grammars for simple integer arithmetic expressions. NOTE: In all of the following languages, the "lexical" part of the language is defined by the following grammar. identifier -> letter | identifier letter | identifier digit number -> digit | number digit digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 letter -> a | b | ... | x | y | z Suppose that we change the production for identifier to identifier -> letter | identifier letter | identifier number How does that affect the parsing of the following identifiers? x3 x32 x3y x32y ----------------------------------------------------------------------------- 1.) A very simple, unambiguous, but not very expressive, BNF syntax. expr -> identifier '+' expr | identifier '*' expr | '(' expr ')' | identifier | number Show that the string "x + 3y" does not parse using this grammar. Show that the string "(x + y) * z" does not parse using this grammar. Show that the string "z * (x + y)" does parse. Parse the strings "x + y * z" and "x * y + z". What can you say about the precedence of operators for this grammar? Parse the string "x + y + z". What can you say about the associativity of '+' for this grammar? Suppose that we change the production for expr to expr -> identifier oper expr | '(' expr ')' | identifier | number oper -> '+' | '*' Notice that this makes oper a token class. How does that affect the parsing of the above strings? ----------------------------------------------------------------------------- 2.) An expressive, but ambiguous, BNF syntax. expr -> expr '+' expr | expr '*' expr | '(' expr ')' | identifier | number Show that the string "(x + y) * z" does parse using this grammar. Show that "x + y + z" has two different parses with this grammar but only one parse with the first grammar. Show that "x + y * z" has two different parses with this grammar but only one parse with the first grammar. Note: This grammar does not define any precedence or associativity for the operators. (Why not?) ----------------------------------------------------------------------------- 3.) An expressive, non-ambiguous BNF syntax, but with both operators having the same precedence, and with both operators being right associative. expr -> term '+' expr | term '*' expr | term term -> '(' expr ')' | identifier | number Parse the following expressions with this grammar. (x + y) * z z * (x + y) x + y + z x + y * z x * y + z x * y * z Notice that these expressions are right associative because the grammar is right recursive. The next example rewrites this grammar to be left recursive and then the operators will be left associative (the way they are usually defined). Here is an EBNF version of this grammar. expr -> term [ ('+' | '*') expr ] term -> '(' expr ')' | identifier | number ----------------------------------------------------------------------------- 4.) An expressive, non-ambiguous BNF syntax, but with both operators having the same precedence, and with both operators being left associative. expr -> expr '+' term | expr '*' term | term term -> '(' expr ')' | identifier | number Parse the following expressions with this grammar. (x + y) * z z * (x + y) x + y + z x + y * z x * y + z x * y * z Notice that these expressions are left associative because the grammar is left recursive. Here is an EBNF version of this grammar. Notice that this EBNF grammar "repeats" by using iteration (i.e., the Kleene star) but the previous EBNF grammar "repeats" by using recursion. expr -> term [ ('+' | '*') term ]* term -> '(' expr ')' | identifier | number ----------------------------------------------------------------------------- 5.) An ambiguous BNF syntax, with * having higher precedence then +, but neither operator has its associativity specified. expr -> expr '+' expr | term term -> term '*' term | factor factor -> '(' expr ')' | identifier | number Parse the following expressions with this grammar. (x + y) * z z * (x + y) x + y + z x + y * z x * y + z x * y * z Notice how, even though the grammar is ambiguous, it does manage to define a precedence for the operators (but not associativity). What happens if your try to use the token class oper from the first example? ----------------------------------------------------------------------------- 6.) A non-ambiguous BNF syntax with '+' and '*' being left associative. expr -> expr '+' term | term term -> term '*' factor | factor factor -> '(' expr ')' | identifier | number Parse the following expressions with this grammar. (x + y) * z z * (x + y) x + y + z x + y * z x * y + z x * y * z ----------------------------------------------------------------------------- 7.) An "equivalent" EBNF syntax. expr -> term [ '+' term ]* term -> factor [ '*' factor ]* factor -> '(' expr ')' | identifier | number Notes: (1) But now we are back to being ambiguous. This does not specify if '+' and '*' are left or right associative. (2) Syntax diagrams for this language would be derived from this EBNF syntax, not from the BNF syntax. ----------------------------------------------------------------------------- 8.) A BNF syntax that includes subtraction and division. expr -> expr '+' term | expr '-' term | term term -> term '*' factor | term '/' factor | factor factor -> '(' expr ')' | identifier | number ----------------------------------------------------------------------------- 9.) A EBNF syntax that includes subtraction and division. expr -> term [ ('+' | '-') term ]* term -> factor [ ('*' | '/') factor ]* factor -> '(' expr ')' | identifier | number ----------------------------------------------------------------------------- 10.) A EBNF syntax with addition, subtraction, multiplication, division, and exponentiation. expr -> term [ ('+' | '-') term ]* term -> factor [ ('*' | '/') factor ]* factor -> base [ '^' exponent ]* base -> '(' expr ')' | identifier | number exponent -> '(' expr ')' | identifier | number Rewrite this using BNF so that exponentiation is right associative (and the other operators are left associative).