Appendix A
The Full Grammar
This appendix collects the complete context-free grammar of Nex in one place,
with the expression grammar given in its layered form so that operator
precedence and associativity (Section 2.6) are expressed directly by the
productions rather than assumed.
A.1 Programs, Modules, and Declarations
program ::= topitem *
topitem ::= import | intern | classdec | fundec | funsig | tydec | stmt
import ::= import id (. id )* ⟨from string ⟩
intern ::= intern id (/ id )* ⟨as id ⟩
tydec ::= declare type id = ty
fundec ::= function id ⟨gen ⟩ ( ⟨params ⟩ ) ⟨: ty ⟩ ⟨note ⟩ ⟨require ⟩ do block ⟨ensure ⟩ ⟨rescue ⟩ end
funsig ::= declare function id ⟨gen ⟩ ( ⟨params ⟩ ) ⟨: ty ⟩ ⟨note ⟩
A.2 Classes
classdec ::= ⟨sealed ⟩ ⟨deferred ⟩ class id ⟨gen ⟩ ⟨note ⟩ ⟨inherit ⟩ classbody ⟨invariant ⟩ end
inherit ::= inherit parent (, parent )*
parent ::= id ⟨tyargs ⟩
classbody ::= (featuresec | createsec )*
featuresec ::= ⟨private ⟩ feature member +
createsec ::= create constructor +
member ::= field | method
field ::= ⟨once ⟩ id : ty ⟨:= exp ⟩ ⟨note ⟩ | id := exp ⟨note ⟩
method ::= id ⟨( ⟨params ⟩ ) ⟩ ⟨: ty ⟩ ⟨note ⟩ ⟨require ⟩ do block ⟨ensure ⟩ ⟨rescue ⟩ end
| id ( ⟨params ⟩ ) ⟨: ty ⟩ ⟨note ⟩ ⟨deferred ⟩
constructor ::= id ⟨( ⟨params ⟩ ) ⟩ ⟨require ⟩ do block ⟨ensure ⟩ ⟨rescue ⟩ end
invariant ::= invariant assertion +
params ::= param (, param )*
param ::= id (, id )* ⟨: ty ⟩
require ::= require assertion +
ensure ::= ensure assertion +
rescue ::= rescue block
assertion ::= id : exp
note ::= note string
A.3 Types and Generics
gen ::= [ genparam (, genparam )* ]
genparam ::= ⟨? ⟩ id ⟨-> id ⟩
tyargs ::= [ ty (, ty )* ]
ty ::= Integer | Integer64 | Real | Decimal | Char | Boolean | String
| ? ty | funty | id ⟨tyargs ⟩
funty ::= Function ⟨( ⟨funtyparams ⟩ ) ⟨: ty ⟩⟩
funtyparams ::= funtyparam (, funtyparam )*
funtyparam ::= id : ty | ty
A.4 Statements
block ::= stmt *
stmt ::= id := exp | exp . id := exp
| let id ⟨: ty ⟩ := exp
| if exp then block (elseif exp then block )* ⟨else block ⟩ end
| from block ⟨invariant ⟩ ⟨variant ⟩ until exp do block end
| repeat exp do block end
| across exp as id do block end
| case exp of caseclause + ⟨else stmt ⟩ end
| match exp of matchclause + ⟨else block ⟩ end
| select selectclause + ⟨timeout ⟩ ⟨else block ⟩ end
| do block ⟨rescue ⟩ end | with string do block end
| raise exp | retry | exp
caseclause ::= scon (, scon )* then stmt
matchclause ::= when id ⟨tyargs ⟩ as id then block
selectclause ::= when exp ⟨as id ⟩ then block
timeout ::= timeout exp then block
invariant ::= invariant assertion +
variant ::= variant exp
A.5 Expressions (Layered)
The following layering expresses the precedence and associativity of
Section 2.6: each level refers to the next more tightly binding one, with the
binary operators of a level left-associative except ^.
exp ::= orexp
orexp ::= andexp (or andexp )*
andexp ::= eqexp (and eqexp )*
eqexp ::= relexp ((= | /= | == | != ) relexp )*
relexp ::= addexp ((< | <= | > | >= ) addexp )*
addexp ::= mulexp ((+ | - ) mulexp )*
mulexp ::= unexp ((* | / | % | ^ ) unexp )*
unexp ::= - unexp | not unexp | postexp
postexp ::= primary postfix *
postfix ::= ⟨? ⟩ . id ⟨( ⟨args ⟩ ) ⟩ | ( ⟨args ⟩ )
primary ::= scon | id | this | result | ( exp )
| createexp | whenexp | fnexp | spawnexp | convexp
| old primary | arraylit | maplit | setlit
createexp ::= create id ⟨tyargs ⟩ ⟨. id ⟨( ⟨args ⟩ ) ⟩⟩
whenexp ::= when exp then exp else exp end
fnexp ::= fn ⟨gen ⟩ ( ⟨params ⟩ ) ⟨: ty ⟩ do block end
spawnexp ::= spawn do block end
convexp ::= convert exp to id : ty
args ::= exp (, exp )*
arraylit ::= [ ⟨exp (, exp )* ⟩ ]
maplit ::= { } | { exp : exp (, exp : exp )* }
setlit ::= #{ ⟨exp (, exp )* ⟩ }
A.6 Lexical Grammar
id ::= (letter | _ ) (letter | _ | digit )*
scon ::= int | real | char | string | true | false | nil
int ::= digit + | 0b bit + | 0o odigit + | 0x hdigit +
real ::= ⟨digit + ⟩ . digit + ⟨exp ⟩
char ::= # (char≠digit,ws | named | digit + )
named ::= nul | space | newline | tab | return
string ::= " … " | ' … '
comment ::= -- … end-of-line
A digit separator _ may occur between two digits of any numeric
literal. The reserved words of Section 2.1 are excluded from
id by the longest-match rule of Section 2.5.