expression -> | sequence | apply | unary | binary | let | control | primary grouping -> "(" expression ")" ; unary -> ( "-" | "!" ) expression ; binary -> expression operator expression ; operator -> | "==" | "!=" | "<" | "<=" | ">" | ">=" | "+" | "-" | "*" | "/" | "++" ; pattern -> "_" | record_pattern | variant_pattern ; record_pattern -> "{" ( identifier ( "=" pattern )? ( "," identifier ( "=" pattern )? )* ) ( "|" identifier ) "}" variant_pattern -> "`" identifier ( "(" ( "_" | compound_pattern | identifier ) ")" )? ; parameters -> "(" ( identifier ( "," identifier )* )?")" let -> "let" ( identifier parameters? | pattern ) "=" expression ( "and" ( identifier parameters? | pattern ) "=" expression )* "in" expression ; control -> | if | when if -> "if" expression "then" expression "else" expression ; when -> "when" expression "is" ( ( identifier | pattern ) "=>" expression )+ ; variant -> "`" identifier ( "(" expression ")" )? ; base_record -> expression ( "with" identifier "=" expression ( "," identifier "=" expression )* ","? )? record -> "{" ( identifier ("=" expression)? ( "," identifier ("=" expression)? )* )? ( "|" base_record )? "}" ; list -> "[" ( expression ( "," expression )* ","? )? "]" ; identifier -> IDENTIFIER | "@" STRING ; operand -> ( NUMBER | STRING | identifier | "(" expression ")" | record | variant | list) ; selector -> "." identifier ; index -> "[" expression "]" ; call -> "(" ( ( "_" | expression ) ( "," ( "_" | expression ) )* ","? )? ")" ; primary -> operand ( selector | index | call ) ;