<
Model ::= Files Imports Block
<
Files ::= FileClause* FileClause ::= files FileItem*; FileItem ::= FileSpec | FileBinding FileSpec ::= [ Arc = ] DelimPath FileBinding ::= Arc = `[' FileSpec*, `]'
<
Imports ::= ImpClause* ImpClause ::= ImpIdReq | ImpIdOpt ImpIdReq ::= import ImpItemR*; ImpItemR ::= ImpSpecR | ImpListR ImpSpecR ::= Arc = DelimPath ImpListR ::= Arc = `[' ImpSpecR*, `]' ImpIdOpt ::= from DelimPath import ImpItemO*; ImpItemO ::= ImpSpecO | ImpListO ImpSpecO ::= [ Arc = ] Path [ Delim ] ImpListO ::= Arc = `[' ImpSpecO*, `]'
<
DelimPath ::= [ Delim ] Path [ Delim ]
Path ::= Arc { Delim Arc }*
Arc ::= Id | Integer | Text
<
Block ::= `{' Stmt*; Result; `}'
Stmt ::= Assign | Iterate | FuncDef | TypeDef
Result ::= { value | return } Expr
<
Assign ::= TypedId [ Op ] = Expr Op ::= AddOp | MulOp AddOp ::= + | ++ | - MulOp ::= *
<
Iterate ::= foreach Control in Expr do IterBody
Control ::= TypedId | `[' TypedId = TypedId `]'
IterBody ::= Stmt | `{' Stmt+; `}'
<
FuncDef ::= Id Formals+ [ TypeQual ] Block
Formals ::= ( FormalArgs )
FormalArgs ::= TypedId*,
| { TypedId = Expr }*,
| TypedId { , TypedId }* { , TypedId = Expr }+
<
Expr ::= if Expr then Expr else Expr | Expr1
Expr1 ::= Expr2 { => Expr2 }*
Expr2 ::= Expr3 { || Expr3 }*
Expr3 ::= Expr4 { && Expr4 }*
Expr4 ::= Expr5 [ { == | != | < | > | <= | >= } Expr5 ]
Expr5 ::= Expr6 { AddOp Expr6 }*
Expr6 ::= Expr7 { MulOp Expr7 }*
Expr7 ::= [ UnaryOp ] Expr8
UnaryOp ::= - | !
Expr8 ::= Primary [ TypeQual ]
Primary ::= ( Expr ) | Literal | Id | List
| Binding | Select | Block | FuncCall
Binary operators with equal precedence are left-associative.
<
Literal ::= ERR | TRUE | FALSE | Text | Integer
<
List ::= < Expr*, >
<
Binding ::= `[' BindElem*, `]'
BindElem ::= SelfNameB | NameBind
SelfNameB ::= Id
NameBind ::= GenPath = Expr
GenPath ::= GenArc { Delim GenArc }* [ Delim ]
GenArc ::= Arc | $ Id | $ ( Expr ) | % Expr %
<
Select ::= Primary Selector GenArc Selector ::= Delim | !
<
FuncCall ::= Primary Actuals Actuals ::= ( Expr*, )
<
TypeDef ::= type Id = Type
TypedId ::= Id [ TypeQual ]
TypeQual ::= : Type
Type ::= any | bool | int | text
| list [ ( Type ) ]
| binding ( TypeQual )
| binding [ ( TypedId*, ) ]
| function { ( TypedForm*, ) }* [ TypeQual ]
| Id
TypedForm ::= [ Id : ] Type