Six example syntaxes for simple integer arithmetic expressions. 1.) A very simple, unambiguous, but not very expressive, BNF syntax. expr -> identifier + expr | identifier * expr | ( expr ) | number | identifier number -> digit | number digit digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter | identifier letter | identifier digit letter -> a | b | ... |x | y | z 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? Note: The productions for number, digit, identifier, and letter define (most of) the tokens for this grammar (and all of the following grammars). 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 Suppose that we change the production for expr to expr -> identifier oper expr | identifier oper expr | ( expr ) | number | identifier oper -> + | * Notice that this makes oper a token class. How does that affect the parsing of the above strings? ----------------------------------------------------------------- 2.) A more expressive, but ambiguous, BNF syntax. expr -> expr + expr | expr * expr | ( expr ) | number | identifier number -> digit | number digit digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter | identifier letter | identifier digit letter -> a | b | ... |x | y | z Note: This is ambiguous. It does not specify the precedence of operations between + and * and it does not specify if + and * are left or right associative. 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. ----------------------------------------------------------------- 3.) A better BNF syntax. expr -> expr + term | term term -> term * factor | factor factor -> ( expr ) | number | identifier number -> digit | number digit digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter | identifier letter | identifier digit letter -> a | b | ... |x | y | z Parse the following expressions with this grammar. (x + y) * z z * (x + y) x + y + z x + y * z x * y + z What happens if your try to use a token class like oper from the first example? ----------------------------------------------------------------- 4.) An equivalent EBNF syntax. expr -> term { + term }* term -> factor { '*' factor }* factor -> ( expr ) | number | identifier number -> digit { digit }* digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter {letter | digit}* letter -> a | b | ... |x | y | z Notes: (1) This is still a bit ambiguous. It 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. ----------------------------------------------------------------- 5.) A BNF syntax with subtraction and division. expr -> expr + term | expr - term | term term -> term * factor | term / factor | factor factor -> ( expr ) | number | identifier number -> digit | number digit digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter | identifier letter | identifier digit letter -> a | b | ... |x | y | z ----------------------------------------------------------------- 6.) A EBNF syntax with subtraction and division. expr -> term { [+ | -] term }* term -> factor { ['*' | /] factor }* factor -> ( expr ) | number | identifier number -> digit { digit }* digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 identifier -> letter {letter | digit}* letter -> a | b | ... |x | y | z