10.2. External Grammar of Core

In designing the external grammar, we have tried to strike a balance among a number of competing goals, including easy parseability by machines, easy readability by humans, and adequate structural simplicity to allow straightforward presentations of the semantics. Thus, we had to make some compromises. Specifically:

We use the following notational conventions for syntax:

[ pat ] optional
{ pat } zero or more repetitions
{ pat }+ one or more repetitions
pat1 ∣ pat2 choice
fibonacci terminal syntax in typewriter font
Module module %module mident { tdef ; }{ vdefg ; }  
Type defn. tdef %data qtycon { tbind } = { [ cdef {; cdef } ] } algebraic type
%newtype qtycon qtycon { tbind } = ty newtype
Constr. defn. cdef qdcon { @ tbind }{ aty }+  
Value defn. vdefg %rec { vdef { ; vdef } } recursive
vdef non-recursive
vdef qvar :: ty = exp  
Atomic expr. aexp qvar variable
qdcon data constructor
lit literal
( exp ) nested expr.
Expression exp aexp atomic expresion
aexp { arg }+ application
\ { binder }+ -> exp abstraction
%let vdefg %in exp local definition
%case ( aty ) exp %of vbind { alt { ; alt } } case expression
%cast exp aty type coercion
%note " { char } " exp expression note
%external ccall " { char } " aty external reference
%dynexternal ccall aty external reference (dynamic)
%label " { char } " external label
Argument arg @ aty type argument
aexp value argument
Case alt. alt qdcon { @ tbind }{ vbind } -> exp constructor alternative
lit -> exp literal alternative
%_ -> exp default alternative
Binder binder @ tbind type binder
vbind value binder
Type binder tbind tyvar implicitly of kind *
( tyvar :: kind ) explicitly kinded
Value binder vbind ( var :: ty )  
Literal lit ( [-] { digit }+ :: ty ) integer
( [-] { digit }+ % { digit }+ :: ty ) rational
( ' char ' :: ty ) character
( " { char } " :: ty ) string
Character char any ASCII character in range 0x20-0x7E except 0x22,0x27,0x5c
\x hex hex ASCII code escape sequence
hex 0∣…∣9 ∣a ∣…∣f  
Atomic type aty tyvar type variable
qtycon type constructor
( ty ) nested type
Basic type bty aty atomic type
bty aty type application
%trans aty aty transitive coercion
%sym aty symmetric coercion
%unsafe aty aty unsafe coercion
%left aty left coercion
%right aty right coercion
%inst aty aty instantiation coercion
Type ty bty basic type
%forall { tbind }+ . ty type abstraction
bty -> ty arrow type construction
Atomic kind akind * lifted kind
# unlifted kind
? open kind
bty :=: bty equality kind
( kind ) nested kind
Kind kind akind atomic kind
akind -> kind arrow kind
Identifier mident pname : uname module
tycon uname type constr.
qtycon mident . tycon qualified type constr.
tyvar lname type variable
dcon uname data constr.
qdcon mident . dcon qualified data constr.
var lname variable
qvar [ mident . ] var optionally qualified variable
Name lname lower { namechar }  
uname upper { namechar }  
pname { namechar }+  
namechar lower ∣ upper ∣ digit  
lower ab ∣ … ∣ z_  
upper AB ∣ … ∣ Z  
digit 01 ∣ … ∣ 9  
These choices are certainly debatable. In particular, keeping type applications on tuples and case arms considerably increases the size of Core files and makes them less human-readable, though it allows a Core parser to be simpler.