-- Expressions
texp  -> exp typesignature
exp   -> bexp  | munchers
bexp  -> bterm | bterm || annot bexp           (infixr 2)
bterm -> bfact | bfact && annot bterm          (infixr 3)
bfact -> nexp  | nexp rop annot nexp           (infix  4)
nexp  -> nterm | nexp nop annot nterm          (infixl 6)
nterm -> nfact | nterm * annot nfact           (infixl 7)
nfact -> fexp  | nfact ^ annot fexp            (infixl 8)
fexp  -> prim  | fexp @ annot prim             (function application) 
prim  -> aexp
       | fix annot aexp                        (fixpoint operator)
       | poly aexp                             (polyvariant expression)
       | spec aexp                             (specialisation)
       | lift aexp                             (lift)
       | proj annot aexp                       (tuple projection)
aexp  -> varid                                 (variable) 
       | () annot                              (general constructor) 
       | ( texp )                              (parenthesized expression) 
       | ( texp1 , ... , texpk ) annot         (tuple, k>=2) 
       | liter
munchers -> \ annot varid typesig -> exp       (lambda abstraction)
          | let annot decls in exp             (let expression)
          | if annot exp then exp else exp     (conditional)

-- Types
typesig  -> :: typeexp
          |                                    (no type signature)
typeexp  -> typefact -> annot typeexp | typefact
typefact -> T_num 
          | Int annot 
          | Bool annot 
          | poly typefact 
          | () annot
          | (typeexp1,...,typeexpn) annot      (tuple, n>=2)
          | (typeexp)

-- Auxiliaries
annot -> ^D                                    (dynamic)
       | ^S                                    (static)
       |                                       (empty annotation)
rop   -> ==  | /=  | <  | <= | >= | >
nop   -> +   | -
proj  -> fst annot | snd annot | Proj_num_num annot

decls -> decl1 ; ... ; decln                   (n>=0) 
decl  -> var typesig = exp 
 
liter -> num annot | bool annot
num   -> dig  | dig num
bool  -> True | False

-- Lexical analizer
varid   -> (small {small | large | digit | ' })<reservedid> 

reservedid -> let  | in   | fix
            | if   | then | else
            | poly | spec 
            | Int  | lift
            | Bool | True | False
            | fst  | snd  
reservedop -> ::   | =    | \    | ->   | @    
            | ,    | ;    | {    | }    | (    | )
            | ^D   | ^S
            | ||   | &&   | +    | *    | -    | ^
            | ==   | /=   | <    | <=   | >=   | >
            | ()

