FunAlg - syntax
<literal> ::=
| ( )
| [ - ] { 0 - 9 }+
| [ - ] { 0 - 9 }+ / { 0 - 9 }+
| ' _ '
| " { _ }* "
<ident> ::=
| { a - z | A - Z } { a - z | A - Z | 0 - 9 | _ }*
<infix_op> ::=
| { = | <> | > | < | >= | <= | + | - | * | / | % | ^ | || | && | $$ | ; }
<type_cons> ::=
| <ident> [ <poly_appl> ]
| <type_cons> { * <type_cons> }*
| <type_cons> => <type_cons>
<poly_appl> ::=
| [ ]
| [ <type_cons> { , <type_cons> }* ]
<poly_args> ::=
| [ ]
| [ <ident> { , <ident> }* ]
<denote> ::=
| _
| ( )
| <ident>
| ( <denote> { , <denote> }* )
<expr> ::=
| <literal>
| <ident> [ <poly_appl> ]
| ( <expr> { , <expr> }* )
| <expr> <expr>
| <expr> <infix_op> <expr>
| if <expr> then <expr> else <expr>
| let <denote> = <expr> in <expr>
| fun <denote> : <type_cons> -> <expr>
| match <expr> with { | <ident> <denote> -> <expr> }+
<def> ::=
| type <ident> [ <poly_args> ] = { <type_cons> | { | <ident> : <type_cons> }+ }
| let <ident> [ <poly_args> ] [ : <type_cons> ] = <expr>
| let rec <ident> [ <poly_args> ] : <type_cons> = <expr>
<file> ::=
| { <def> ;; }*