Grammar
The concrete syntax of Flex, in EBNF.
Root = ModuleDecl ImportDecl* Decl*
ModuleDecl = 'module' IDENT*
ImportDecl = 'import' IDENT* (ImportAlias | ImportElementList)
Decl =
AnnotationDecl
| ConstDecl
| EnumDecl
| FunctionDecl
| TransformDecl
| ContractDecl
| StructDecl
| NewtypeDecl
| VariantDecl
| TypeAliasDecl
| ComponentDecl
| ConnectionDecl
| GroupDecl
| SystemDecl
| GlobalProtocolDecl
| LocalProtocolDecl
ImportAlias = 'as' Name
ImportElementList = '(' ImportElement* ')'
Name = IDENT
ImportElement = IDENT ('=>' Name)?
AnnotationDecl = AnnotationUse* 'annotation' Name AnnotationParamList? AnnotationScopeList?
ConstDecl = AnnotationUse* 'const' Name ':' Type '=' Expr ';'
EnumDecl = AnnotationUse* 'enum' Name PrimitiveType EnumMember*
FunctionDecl = AnnotationUse* 'function' Name FunctionParam* '->' Type (Expr | BlockExpr)
TransformDecl = AnnotationUse* 'transform' Name TransformParam* '->' Type ContextParam* (Expr | BlockExpr)
ContractDecl = AnnotationUse* 'contract' Name ContractParam* ContractBody
StructDecl = AnnotationUse* 'abstract'? 'extensible'? 'message'? 'struct' Name ('extends' NamedType)? StructField* StructAssertion*
NewtypeDecl = AnnotationUse* 'newtype' Name NewtypeField StructAssertion*
VariantDecl = AnnotationUse* 'message'? 'variant' Name VariantConstructor*
TypeAliasDecl = AnnotationUse* 'type' Name '=' Type ';'
ComponentDecl = AnnotationUse* 'component' Name ';'
ConnectionDecl = AnnotationUse* 'connection' Name 'from' Path 'to' Path ';'
GroupDecl = AnnotationUse* 'group' Name '{' GroupMember* '}'
SystemDecl = AnnotationUse* 'system' Name SystemProtocolRef*
GlobalProtocolDecl = AnnotationUse* 'global' 'protocol' Name GlobalStmt*
LocalProtocolDecl = AnnotationUse* 'local' 'protocol' Name 'in' Path LocalStmt*
AnnotationUse = '@' AnnotationArgList?
AnnotationArgList = '(' AnnotationArg* ')'
AnnotationArg = AnnotationConstRef?
AnnotationConstRef = IDENT*
AnnotationParamList = '(' AnnotationParam* ')'
AnnotationScopeList = '|' Name* '|'
AnnotationParam = Name ':' Type
Type =
PrimitiveType
| TupleType
| OptionalType
| ArrayType
| NamedType
Expr =
BitLiteral
| StringLiteral
| IntegerLiteral
| FloatLiteral
| RefExpr
| ContextParamRefExpr
| ParenExpr
| BinaryExpr
| UnaryExpr
| TypeAscriptionExpr
| MemberAccessExpr
| ArrayAccessExpr
| CallExpr
| StructLitExpr
| IfExpr
| MatchExpr
| SomeExpr
| NoneExpr
| TryExpr
| ValueCastExpr
| FoldExpr
| MapExpr
| FilterExpr
| FlatmapExpr
| ArrayComprehensionExpr
| ArrayLitExpr
| BlockExpr
PrimitiveType = 'bit' | 'string' | 'float32' | 'float64' | INT_TYPE | UINT_TYPE
EnumMember = AnnotationUse* Name '=' ';'
FunctionParam = Name ':' Type
BlockExpr = '{' Stmt* Expr? '}'
TransformParam = Name ':' Type
ContextParam = '?' Name ':' Type
ContractParam = Name ':' Type
ContractBody = '{' Stmt* '}'
Stmt =
LetStatement
| AssertStatement
| IfStatement
NamedType = Path
StructField = AnnotationUse* Name ':' Type ';'
StructAssertion = 'assert' (Name '=')? Expr ';'
NewtypeField = Name ':' Type ';'
VariantConstructor = AnnotationUse* Name Type* ';'
Path = IDENT*
SystemProtocolRef = Path ';'
GroupMember = Path ';'
TupleType = '(' Type* ')'
OptionalType = 'Optional' '<' Type '>'
ArrayType = Type '[' ']'
BitLiteral = 'true' | 'false'
StringLiteral = STRING
IntegerLiteral = INTEGER
FloatLiteral = FLOAT
RefExpr = Path
ContextParamRefExpr = '?' IDENT
ParenExpr = '(' Expr TupleElement* ')'
BinaryExpr = Expr ('+' | '-' | '*' | '/' | '%' | '++' | '&&' | '&' | '||' | '|' | '^' | '==' | '!=' | '<' | '>' | '<=' | '>=' | '<<') Expr
UnaryExpr = ('!' | '~' | '-') Expr
TypeAscriptionExpr = Expr ':' Type
MemberAccessExpr = Expr '.' IDENT
ArrayAccessExpr = Expr '[' Expr ('..' Expr)? ']'
CallExpr = Expr CallArgList GivingArgList?
StructLitExpr = Expr StructFieldBinding* NewtypeLitValue? StructUpdateBody?
IfExpr = 'if' Expr 'then'? Expr 'else' Expr
MatchExpr = 'match' '(' Expr ')' MatchArm*
SomeExpr = 'some' '(' Expr ')'
NoneExpr = 'none'
TryExpr = 'try' '(' Expr ')'
ValueCastExpr = 'value_cast' '?'? '<' Type '>' '(' Expr ')'
FoldExpr = 'fold' FoldAccumulator LetPattern 'in' Expr BlockExpr
MapExpr = 'map' '(' LetPattern 'in' Expr ')' BlockExpr
FilterExpr = 'filter' '(' LetPattern 'in' Expr ')' BlockExpr
FlatmapExpr = 'flatmap' '(' LetPattern 'in' Expr ')' BlockExpr
ArrayComprehensionExpr = '[' Expr CompClause* ']'
ArrayLitExpr = '[' Expr* ']'
TupleElement = Expr
CallArgList = '(' Expr* ')'
GivingArgList = 'giving' '(' Expr* ')'
StructFieldBinding = IDENT '=' Expr ';'
NewtypeLitValue = Expr
StructUpdateBody = Expr 'with' StructFieldBinding*
MatchArm = MatchPattern '=>' Expr ';'?
MatchPattern =
DiscardPattern
| LiteralPattern
| SomePattern
| NonePattern
| QualifiedPattern
| TupleMatchPattern
| ArrayMatchPattern
| IdentPattern
| StructMatchPattern
| TypeMatchPattern
FoldAccumulator = LetPattern (':' Type)? '=' Expr
LetPattern =
IdentBinding
| DiscardBinding
| TuplePattern
| TypedBinding
CompClause =
ForClause
| FilterClause
| ScanClause
| LetClause
| ZipClause
ForClause = 'for' LetPattern 'in' Expr
FilterClause = 'if' Expr
ScanClause = 'scan' LetPattern (':' Type)? '=' Expr 'in' Expr
LetClause = 'let' LetPattern '=' Expr
ZipClause = 'zip' 'for' LetPattern 'in' Expr
LetStatement = 'let' LetPattern (':' Type)? '=' Expr ';'
AssertStatement = 'assert' Expr ';'
IfStatement = 'if' Expr 'then'? StmtList 'else' StmtList
StmtList =
'{' Stmt* '}'
| Stmt
IdentBinding = Name
DiscardBinding = _
TuplePattern = '(' LetPattern* ')'
TypedBinding = LetPattern ':' Type
DiscardPattern = _
LiteralPattern = INTEGER | FLOAT | STRING | 'true' | 'false'
SomePattern = 'some' '(' MatchPattern ')'
NonePattern = 'none'
QualifiedPattern = Path MatchPattern*
TupleMatchPattern = '(' MatchPattern* ')'
ArrayMatchPattern = '[' MatchPattern* ']'
IdentPattern = Name
StructMatchPattern = MatchPattern 'as' Type
TypeMatchPattern = MatchPattern ':' Type
LocalStmt =
ProtocolLetStatement
| VarStatement
| SetStatement
| SendStatement
| RecvStatement
| BranchBlock
| ListenBlock
| LoopBlock
| BreakStatement
| DoStatement
| StateAnnotationStatement
ProtocolLetStatement = 'let' IdentBinding (':' Type)? '=' Expr ';'
VarStatement = 'var' IdentBinding (':' Type)? '=' Expr ';'
SetStatement = 'set' Path '=' Expr ';'
SendStatement = 'send' SendWhat ConnectionClause AnnotationUse* ';'
RecvStatement = 'recv' RecvWhat ConnectionClause AnnotationUse* ';'
BranchBlock = 'branch' BranchArm* 'end'
ListenBlock = 'listen' ListenArm* 'end'
LoopBlock = 'loop' Name? ('invariant' Expr)? LocalStmt*
BreakStatement = 'break' Name? ';'
DoStatement = 'do' 'tail'? Path ';'
StateAnnotationStatement = AnnotationUse
SendWhat =
SendExpression
| SendAny
| SendAnyBind
| SendLet
ConnectionClause = 'from'? 'to'? 'on'? Path*
RecvWhat =
RecvVar
| RecvDiscard
| RecvAnyBind
| RecvLet
SendExpression = Expr
SendAny = 'any' Type
SendAnyBind = 'any' Name ':' Type 'where' Expr
SendLet = 'let' LetPattern ':' Type ('where' Expr)?
RecvVar = Path ('assuming' Expr)?
RecvDiscard = _ (':' Type)?
RecvAnyBind = 'any' Name ':' Type 'assuming' Expr
RecvLet = 'let' LetPattern ':' Type ('assuming' Expr)?
BranchArm = '|' ('else' | Expr) '=>' LocalStmt*
ListenArm = '|' 'recv' RecvWhat ConnectionClause AnnotationUse* '=>' LocalStmt*
GlobalStmt =
ExchStatement
| ChoiceBlock
| LoopBlock
| BreakStatement
| ParallelBlock
| InBlock
| DoStatement
| StateAnnotationStatement
ExchStatement = 'exch' SendWhat ('into' RecvWhat)? ConnectionClause AnnotationUse* ';'
ChoiceBlock = 'choice' 'in' ChoiceComponent* SyncWhereClause? ChoiceArm* 'end'
ParallelBlock = 'parallel' GlobalStmt* ParallelWithBranch*
InBlock = 'in' Path LocalStmt*
ChoiceComponent = Path
SyncWhereClause = 'where' SyncVarDef*
ChoiceArm = '|' ('else' | Expr) '=>' GlobalStmt*
SyncVarDef = Name '=' SyncExpr*
SyncExpr = 'in' Path '{' Expr '}'
ParallelWithBranch = 'with' GlobalStmt*