Grammar for source expression terms.  The grammar is from Peyton Jones
and Lester (1992, pages 7 and 30), but modified to have left
associative infix operators, and with some changes suggested by Klaus
Elmquist Nielsen: "case" has a matching "end", there is a modulo
operator "%", and the syntax of pack is pack{tag, arg1, ..., argn}.

  expr     =  "let" defns "in" expr
           |  "letrec" defns "in" expr
           |  "case" expr "of" alts "end"
           |  "if" expr "then" expr "else" expr
           |  "\" name "." expr
           |  expr1
  expr1    =  expr1 "|" expr2
           |  expr2 
  expr2    =  expr2 "&" expr3
           |  expr3
  expr3    =  expr4 "=" expr4
           |  expr4 "~=" expr4
           |  expr4 "<" expr4
           |  expr4 ">" expr4
           |  expr4 "<=" expr4
           |  expr4 ">=" expr4
           |  expr4
  expr4    =  expr4 "+" expr5
           |  expr4 "-" expr5
           |  expr5
  expr5    =  expr5 "*" expr6
           |  expr5 "/" expr6
           |  expr5 "%" expr6
           |  expr6 
  expr6    =  expr6 aexpr
           |  aexpr
  aexpr    =  name 
           |  int 
           |  "pack{" int exprs "}"
  defns    =  defn  |  defn ";" defns
  defn     =  Name "=" expr
  alts     =  alt   |  alt ";" alts
  alt      =  "<" int ">" vars "->" expr
  exprs    =  "," expr exprs  |  <empty>

  Transforming expr1-6 to eliminate left-recursion, and left-factoring
  defn and alts, we get:

  expr     =  "let" defns "in" expr
           |  "letrec" defns "in" expr
           |  "case" expr "of" alts "end"
           |  "if" expr "then" expr "else" expr
           |  "\" name "." expr
           |  expr1
  expr1    =  expr2 e1opt
  e1opt    =  "|" expr2 e1opt | <empty>
  expr2    =  expr3 e2opt
  e2opt    =  "&" expr3 e2opt | <empty>
  expr3    =  expr4 e3opt
  e3opt    =  "=" expr4 | <empty>
  expr4    =  expr5 e4opt 
  e4opt    =  "+" expr5 e4opt
           |  "-" expr5 e4opt
           |  <empty>
  expr5    =  expr6 e5opt
  e5opt    =  "*" expr6 e5opt
           |  "/" expr6 e5opt
           |  "%" expr6 e5opt
           |  <empty>
  expr6    =  aexpr e6opt
  e6opt    =  aexpr e6opt | <empty>
  aexpr    =  name 
           |  int 
           |  "pack{" int exprs "}"
           |  "(" expr ")"
  defns    =  name "=" expr defnopt
  defnopt  =  <empty>  |  ";" defns
  alts     =  alt altsopt
  altsopt  =  <empty>  | ";" alts
  alt      =  "<" int ">" vars "->" expr
  vars     =  name vars | <empty>
  exprs    =  "," expr exprs  |  <empty>

Checking grammar requirements:
   The rule for expr is of form 1 and OK, because:

   First(expr1) = First(expr2) = First(expr3) = First(expr4) 
   = First(expr5) = First(expr6) = First(aexpr) = { name, int, "pack", "(" },
   so the first-sets of all alternatives are disjoint.

   The rules for expr1-6, defns, alts, and alt are of form 0 and therefore OK.

   The rule for vars (form 2) is OK because Follow(vars) = { "->" }.
   The rule for altsop (form 2) is OK because 
        Follow(altsopt) = Follow(alts) = { "end" }
   The rule for defnopt (form 2) is OK because 
        Follow(defnopt) = Follow(defns) = { "in" }.

   It remains to check the rules e1opt to e6opt, all of form 2, where:

   Follow(e1opt) = Follow(expr) = { of, then, else, ;, in, ), ;, ",", "}" }
   Follow(e2opt) = { | } U Follow(expr)
   Follow(e3opt) = { &, | } U Follow(expr)
   Follow(e4opt) = { =, &, | } U Follow(expr)
   Follow(e5opt) = { +, -, =, &, | } U Follow(expr)
   Follow(e6opt) = { %, *, /, +, -, =, &, | } U Follow(expr)
   Follow(aexpr) = { name, int, "pack", (, *, %, /, +, -, =, &, | } 
                     U Follow(expr)

   These rules are all OK, as a brief inspection will show.
