<program> ::= <decl>*
<decl> ::= <import_decl> | <export_decl> | <let_decl> | <type_decl>
<import_decl> ::= (<import_all> | <import_part>) "from" <identifier>
<import_all> ::= "import as" <identifier>
<import_part> ::= "import {" <identifier> ("," <identifier>)* "}"
<export_decl> ::= "export" (<let_decl> | <type_decl> | "abstract" <type_decl>)
<let_decl> ::= "let" <identifier> (":" ("<" <identifier> ("," <identifier>)* ">")? <expr>)? "=" <expr> | <match_case>
<type_decl> ::= "type" <identifier> (":" <expr>)? "=" ("<" <identifier> ("," <identifier>)* ">")? <type_variants>
<type_variants> ::= <type_variant> ("|" <type_variant>)*
<type_variant> ::= <identifier> | <identifier> ("(" <expr> ("," <expr>)* ")")
| <identifier> "{" <identifier> ":" <expr> ("," <identifier> ":" <expr>)* "}"
<expr> ::= <lambda_expr>
| <if_expr>
| <match_expr>
| <let_in_expr>
| <prefix_expr>
| <infix_expr>
| <call_expr>
| <block_expr>
| <literal>
| <identifier>
| "(" <expr> ")"
<lambda_expr> ::= <param_list> "=>" <expr>
<param_list> ::= <identifier>
| "(" (<identifier> (":" <expr>)? ("," <identifier> (":" <expr>)? )*)? ")"
<if_expr> ::= "if" <expr> "then" <expr> "else" <expr>
<match_expr> ::= "match" <expr> "then" <match_case>+
<match_case> ::= "|" <pattern> "=>" <expr>
<pattern> ::= <identifier>
| <identifier> "(" (<pattern> ("," <pattern>)*)? ")"
| <literal>
<let_in_expr> ::= <let_decl> "in" <expr>
<infix_expr> ::= <expr> <infix_op> <expr>
<infix_op> ::= "+" | "-" | "*" | "/" | "%" | "=="
| "!=" | ">" | ">=" | "<" | "<=" | "&&" | "||" | "->"
<prefix_expr> ::= <prefix_op> <expr>
<prefix_op> ::= "-" | "!"
<call_expr> ::= <expr> ("<" <identifier> ("," <identifier>*) ">")? "(" (<expr> ("," <expr>)*)? ")"
<block_expr> ::= "{" <block_content> ("\n" <block_content>)* "}"
<block_content> ::= <let_decl> | <type_decl> | <expr>
<literal> ::= <integer>
| <float>
| <string>
| <char>
<identifier> ::= ([a-z] | [A-Z] | "_") (<identifier> | [0-9])*
<integer> ::= [0-9]+
<float> ::= [0-9]+ "." [0-9]+
<string> ::= "\"" "\""
<char> ::= "'" "'"