Let us take our simple language with two operators
    L = { a, a+a, a*a, a+a+a, a+a*a, a*a+a, a*a*a, ... }
and add balanced parentheses to it.

-----------------------------------------------------------------------------


1.) Here is an ambiguous BNF grammar for this language.


BNF:    expr -> expr '+' expr | expr '*' expr | '(' expr ')' | a

-----------------------------------------------------------------------------


2.) Here is an unambiguous, right associative, BNF grammar
(and an EBNF grammar derived from it).


BNF:    expr -> a '+' expr
              | a '*' expr
              | '(' expr ')' '+' expr
              | '(' expr ')' '*' expr
              | '(' expr ')'
              | a


EBNF:   expr -> a [ ('+'|'*') expr ]
        expr -> '(' expr ')' [ ('+'|'*') expr ]


Here is a simplified grammar.

BNF:   expr -> term '+' expr | term '*' expr | term
       term -> a | '(' expr ')'

EBNF:   expr -> term [ ('+'|'*') expr ]
        expr -> a | '(' expr ')'


Explain what is wrong with the following grammar.
BNF:    expr -> a '+' expr
              | a '*' expr
              | expr '+' '(' expr ')'
              | expr '*' '(' expr ')'
              | '(' expr ')'
              | a

-----------------------------------------------------------------------------


3.) Here is an unambiguous, left associative, BNF grammar
(and an EBNF grammar derived from it).


BNF:    expr ->  expr '+' a
               | expr '*' a
               | expr '+' '(' expr ')'
               | expr '*' '(' expr ')'
               | '(' expr ')'
               | a


EBNF:   expr -> [ expr ('+'|'*') ] a
        expr -> [ expr ('+'|'*') ] '(' expr ')'


Here is a simplified grammar.

BNF:   expr -> expr '+' term | expr '*' term | term
       term -> a | '(' expr ')'

EBNF:   expr -> term [ ('+'|'*') expr ]
        expr -> a | '(' expr ')'

-----------------------------------------------------------------------------


4.) Here is an ambiguous BNF grammar that gives '*' higher precedence than
'+' but does not specify the associativity for either operator.


BNF:   expr -> expr '+' expr | term
       term -> term '*' term | a | '(' expr ')'

-----------------------------------------------------------------------------


5.) Here is an ambiguous BNF grammar that gives '*' higher precedence than
'+', makes '+' right associative, and does not specify the associativity of '*'.


BNF:   expr -> term '+' expr | term
       term -> term '*' term | a | '(' expr ')'


EBNF:  expr -> term [ '+' expr ]
       term -> term '*' term | a | '(' expr ')'

-----------------------------------------------------------------------------


6.) Here is an ambiguous BNF grammar that gives '*' higher precedence than
'+', makes '+' left associative, and does not specify the associativity of '*'.


BNF:   expr -> expr '+' term | term
       term -> term '*' term | a | '(' expr ')'


EBNF:  expr -> term ( '+' term )*
       term -> term '*' term | a | '(' expr ')'

-----------------------------------------------------------------------------


7.) Here is an ambiguous BNF grammar that gives '*' higher precedence than
'+', makes '*' left associative, and does not specify the associativity of '+'.


BNF:   expr -> expr '+' expr | term
       term -> term '*' factor
     factor -> a | '(' expr ')'


EBNF:  expr -> expr '+' expr | term
       term -> factor ( '*' factor )*
     factor -> a | '(' expr ')'

Notice: This is our first example that needs three levels of non-terminals.

-----------------------------------------------------------------------------


8.) Here is an unambiguous BNF grammar that gives '*' higher precedence than
'+', makes '+' left associative and makes '*' right associative.


BNF:   expr -> expr '+' term | term
       term -> factor '*' term | factor
     factor -> a | '(' expr ')'


EBNF:  expr -> term ( '+' term )*
       term -> factor [ '*' term ]
     factor -> a | '(' expr ')'

-----------------------------------------------------------------------------


9.) Here is an unambiguous BNF grammar that gives '*' higher precedence than
'+', and makes both '+' and '*' left associative.


BNF:   expr -> expr '+' term | term
       term -> term '*' factor | factor
     factor -> a | '(' expr ')'


EBNF:  expr -> term ( '+' term )*
       term -> factor ( '*' factor )*
     factor -> a | '(' expr ')'

-----------------------------------------------------------------------------