<
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