Skip to main content

Flex Complete Syntax

Flex syntax is specified using a parser expression grammar (PEG).

Postfix operators

  • * Zero or more.
  • + One or more.
  • ? Zero or one.

Prefix operators

  • & Positive forward lookup (parse the following and consume no input).
  • ! Negative forward lookup (parse not the following and consume no input).

Infix operators

  • | Ordered choice.

Concatenation is indicated by placing two grammar expressions next to each other. Concatenation of two terms could or could not mean that whitespace is allowed to appear between them.

Identifiers and literals

(No whitespace between concatenated terms.)
IDENT : (LETTER | '_') (LETTER | DIGIT | '_')*
QIDENT : IDENT ('.' IDENT)*
CIDENT : '?' IDENT
LITERAL : STR_LIT | BIT_LIT | NUM_LIT
STR_LIT : '"' ((!('"' | '\\' | '\n' | '\r') ANY_CHAR) | ('\\' ANY_CHAR))* '"'
BIT_LIT : 'false' | 'true'
NUM_LIT : DEC_LIT
| HEX_LIT
| BIN_LIT
| NAT_LIT
| NEG_LIT
DEC_LIT : '-'? DIGIT+ ('.' DIGIT+)? ('e' | 'E') '-'? (DIGIT+ ('.' DIGIT+)?)
| '-'? DIGIT+ '.' DIGIT+
HEX_LIT : '0x' (DIGIT | 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F')+
BIN_LIT : '0b' ('0' | '1')+
NAT_LIT : DIGIT+
NEG_LIT : '-' DIGIT+

Modules and Declarations

(Whitespace is allowed between concatenated terms.)
----------------------------------- Modules ------------------------------------
MODULE : 'module' QIDENT IMPORT* DECL*
IMPORT : 'import' QIDENT '(' IDENT (',' IDENT)* ')'
| 'import' QIDENT 'as' IDENT
--------------------------------- Declarations ---------------------------------
DECL : DECL_FUNCTION
| DECL_TRANSFORM
| DECL_DERIVE_TRANSFORM
| DECL_ANNOTATION
| ANNOTATION* ANNOTATED_DECL
| DECL_CONST
ANNOTATED_DECL : DECL_STRUCT
| DECL_NEWTYPE
| DECL_VARIANT
| DECL_ENUM
| DECL_TYPE_ALIAS
DECL_ANNOTATION : 'annotation' IDENT ('(' PARAMS ')')? ('|' ANNOTATION_SCOPE* '|')?
ANNOTATION_SCOPE : 'EnumValue'
| 'Enum'
| 'Struct'
| 'Field'
| 'VariantConstructor'
| 'Variant'
| 'Newtype'
| 'TypeAlias'
DECL_CONST : 'const' IDENT ':' TYPE '=' EXP ';'

Data Type Declarations

DECL_STRUCT : STRUCT_MODIFIERS 'struct' IDENT ('extends' QIDENT)? '{' FIELD* STRUCT_PROPERTY* '}'
STRUCT_MODIFIERS : ('abstract'? 'extensible')? 'message'?
FIELD : ANNOTATION* IDENT ':' TYPE ';'
STRUCT_PROPERTY : 'assert' EXP ';'
DECL_NEWTYPE : 'newtype' IDENT '{' FIELD STRUCT_PROPERTY* '}'
DECL_VARIANT : 'message'? 'variant' IDENT '{' VARIANT_CONSTRUCTOR+ '}'
VARIANT_CONSTRUCTOR : ANNOTATION* IDENT '(' (TYPE (',' TYPE)*)? ')' ';'
DECL_ENUM : 'enum' IDENT TYPE '{' ENUM_VALUE+ '}'
ENUM_VALUE : ANNOTATION* IDENT '=' LITERAL ';'
DECL_TYPE_ALIAS : 'type' IDENT '=' TYPE ';'
--------------------------------- Annotations ----------------------------------
ANNOTATION : '@' QIDENT '(' EXP (',' EXP)* ')'
| '@' QIDENT

Functions and Transforms

DECL_FUNCTION : 'function' IDENT '(' PARAMS ')' '->' TYPE BODY
DECL_TRANSFORM : 'transform' IDENT '(' PARAMS ')' '->' TYPE GIVEN_CLAUSE? BODY
DECL_DERIVE_TRANSFORM : 'derive' 'transform' IDENT '(' PARAMS ')' '->' TYPE GIVEN_CLAUSE? (';' | BODY)
PARAMS : (PARAM (',' PARAM)*)?
PARAM : IDENT ':' TYPE
GIVEN_CLAUSE : 'given' '(' CTX_PARAMS ')'
CTX_PARAMS : CTX_PARAM (',' CTX_PARAM)*
CTX_PARAM : CIDENT ':' TYPE
BODY : '=' EXP ';'
| '{' STMT* EXP ';' '}'

Expressions and Statements

EXP : 'if' EXP 'then' EXP 'else' EXP
| EXP1 (('^' | '||' | '&&') EXP1)*
EXP1 : EXP2 (('>' | '>=' | '<' | '<=' | '==' | '!=') EXP2)*
EXP2 : EXP3 ('++' EXP3)*
EXP3 : EXP4 (('+' | '-') EXP4)*
EXP4 : EXP5 (('*' | '/' | '%') EXP5)*
EXP5 : ('!' | '-')* EXP6
EXP6 : EXP7 (':' TYPE)?
EXP7 : EXP8 ('.' IDENT | '[' EXP ']' | '[' EXP '..' EXP ']')*
EXP8 : '(' EXP (',' EXP)* ')'
| '{' STMT* EXP ';' '}'
| 'match' '(' EXP ')' '{' (MATCH_PATTERN '=>' EXP ';')+ '}'
| 'value_cast' '<' TYPE '>' '(' EXP ')'
| 'value_cast?' '<' TYPE '>' '(' EXP ')'
| QIDENT '(' EXP (',' EXP)* ')' ('giving' '(' EXP (',' EXP)* ')')?
| QIDENT '{' EXP '}'
| QIDENT '{' STRUCT_BUILDER* '}'
| '[' (EXP (',' EXP)*)? ']'
| '[' EXP COMP_CHAIN ('zip' COMP_CHAIN)* ']'
| LITERAL
| QIDENT
| CIDENT
STMT : 'let' LET_PATTERN '=' EXP ';'
| 'assert' EXP ';'
LET_PATTERN : '(' LET_PATTERN (',' LET_PATTERN)+ ')' (':' TYPE)?
| IDENT (':' TYPE)?
MATCH_PATTERN : MATCH_PATTERN1 (':' TYPE | 'as' TYPE)?
MATCH_PATTERN1 : '(' MATCH_PATTERN (',' MATCH_PATTERN)+ ')'
| '[' (MATCH_PATTERN (',' MATCH_PATTERN)*)? ']'
| 'some' '(' MATCH_PATTERN ')'
| 'none'
| QIDENT '(' (MATCH_PATTERN (',' MATCH_PATTERN)*)? ')'
| LITERAL
| '_'
| QIDENT
COMP_CHAIN : COMP_CLAUSE+
COMP_CLAUSE : 'if' EXP
| 'for' LET_PATTERN 'in' EXP
| 'scan' LET_PATTERN '=' EXP 'in' EXP
| 'let' LET_PATTERN '=' EXP

Types

TYPE : TYPE1 ('[' ']')*
TYPE1 : '(' TYPE (',' TYPE)+ ')'
| 'Optional' '<' TYPE '>'
| INT_TYPE
| UINT_TYPE
| 'bit'
| 'float32'
| 'float64'
| 'string'
| QIDENT