\begin{syntax}
  expr ::= integer                                ; integer constant
       | real 			                  ; real constant
       | lqualid 		                  ; symbol
       | prefix-op expr 	                  ;
       | expr infix-op expr 	                  ;
       | expr "[" expr "]"                        ; brackets
       | expr "[" expr "]" "<-" expr              ; brackets assignment
       | expr "[" expr infix-op-1 expr "]" 	  ; ternary brackets
       | expr expr+ 		                  ; function application
       | "fun" binder+ spec* "->" spec* expr ; lambda abstraction
       | "let" "rec" rec-defn "in" expr ; recursive functions
       | "let" fun-defn "in" expr                 ; local function
       | "if" expr "then" expr ("else" expr)?     ; conditional
       | expr ";" expr                            ; sequence
       | "loop" invariant* variant? expr "end"    ; infinite loop
       | "while" expr                             ; while loop
         "do" invariant* variant? expr "done"     ;
       | "for" lident "=" expr to-downto expr     ; for loop
         "do" invariant* expr "done"                ;
       | assertion                                ; assertion
       | "raise" uqualid                          ; exception raising
       | "raise" "(" uqualid expr ")"             ;
       | "try" expr "with" ("|" handler)+ "end"   ; exception catching
       | "any" type spec*                         ;
       | "abstract" expr spec*                    ; blackbox
       | "let" pattern "=" expr "in" expr         ; local binding
       | "match" expr ("," expr)* "with"          ; pattern matching
         "|"? expr-case ("|" expr-case)* "end"    ;
       | "(" expr ("," expr)+ ")"                 ; tuple
       | "{" expr-field+ "}"                     ; record
       | expr "." lqualid                         ; field access
       | expr "." lqualid "<-" expr               ; field assignment
       | "{" expr "with" expr-field+ "}"         ; field update
       | expr ":" type 	                          ; cast
       | "ghost" expr 	                          ; ghost expression
       | label expr 	                          ; label
       | "'" uident ":" expr                      ; code mark
       | "(" expr ")" 	      	                  ; parentheses
  \
  expr-case ::= pattern "->" expr                 ;
  \
  expr-field ::= lqualid "=" expr ";"            ;
  \
  handler ::= uqualid pattern? "->" expr
  \
  to-downto ::= "to" | "downto"
\end{syntax}
