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 * having higher precedence then +,
    and with both '+' 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).