fuzion.ebnf
grammar Fuzion;
unit : exprs EOF
;
semiOrFlatLF: semi
| LF
;
semi : SEMI semi
|
;
feature : modAndNames routOrField
;
modAndNames : visibility
modifiers
featNames
;
routOrField : routine
| field
;
routine : formArgsOpt
returnType
effects
inherits
contract
implRout
;
field : returnType
contract
implFldOrRout
;
visibility : visiFlag
|
;
visiFlag : 'private' colon 'module'
| 'private' colon 'public'
| 'private'
| 'module' colon 'public'
| 'module'
| 'public'
;
visi : COLON qual
| qual
;
qual : name
| name dot qual
| type dot qual
;
name : IDENT // all parts of name must be in same line
| opName
| 'ternary' QUESTION COLON
| 'index' LBRACKET '..' RBRACKET
| 'index' LBRACKET RBRACKET
| 'set' LBRACKET RBRACKET
| 'set' IDENT
;
opName : 'infix' op
| 'prefix' op
| 'postfix' op
;
modifiers : modifier modifiers
|
;
modifier : 'redef'
| 'fixed'
;
featNames : qual (COMMA featNames
|
)
;
formArgsOpt : formArgs
|
;
formArgs : LPAREN argLst RPAREN
;
argLst : argList
|
;
argList : argument ( COMMA argList
|
)
;
argument : visibility
modifiers
argNames
argType
contract
;
argType : type
| typeType
| typeType COLON type
|
;
typeType : 'type'
| 'type' '...'
;
argNames : name ( COMMA argNames
|
)
;
returnType : boundType
| 'value'
| 'ref'
|
;
effects : EXCLAMATION typeList
|
;
EXCLAMATION : '!'
;
inherits : inherit
|
;
inherit : COLON callList
;
callList : call ( COMMA callList
|
)
;
call : name actuals callTail
;
actuals : actualArgs
| dot NUM_LITERAL
;
indexCall : LBRACKET actualList RBRACKET indexTail
;
indexTail : ':=' exprInLine
|
;
callTail : indexCallOpt dotCallOpt
;
indexCallOpt: indexCall
|
;
dotCallOpt : dot call
|
;
typeList : type ( COMMA typeList
|
)
;
actualArgs : actualsList
| LPAREN actualList RPAREN
;
actualList : actualSome
|
;
actualSome : actual actualMore
;
actualMore : COMMA actualSome
|
;
actualsList : actualSp actualsList
|
;
bracketTerm : brblock
| klammer
| inlineArray
;
actualSp : actual // no white space except enclosed in { }, [ ], or ( ).
;
actual : expr | type
;
exprInLine : exprWithResult // within one line
| bracketTerm // stretching over one or several lines
;
exprWithResult: opExpr
( QUESTION expr COLON expr
| QUESTION casesBars
|
)
;
opExpr : ( op
)*
opTail
;
opTail : term
( ( op )+
( opTail
|
)
|
)
;
klammer : klammerExpr
| tuple
| klammerLambd
;
klammerExpr : LPAREN expr RPAREN
;
tuple : LPAREN RPAREN
| LPAREN expr (COMMA expr)+ RPAREN
;
klammerLambd: LPAREN argNamesOpt RPAREN lambda
;
argNamesOpt : argNames
|
;
lambda : contract '->' block
;
plainLambda : argNames lambda
;
inlineArray : LBRACKET RBRACKET
| LBRACKET cmaSepElmts RBRACKET
| LBRACKET semiSepElmts RBRACKET
;
cmaSepElmts : expr addCmaElmts
;
addCmaElmts : COMMA cmaSepElmts
| COMMA
|
;
semiSepElmts: expr addSemiElmts
;
addSemiElmts: SEMI semiSepElmts
| SEMI
|
;
term : simpleterm ( indexCall
|
) ( dot call
|
)
;
simpleterm : bracketTerm
| stringTerm
| NUM_LITERAL
| match
| loop
| ifexpr
| dotEnv
| dotType
| callOrFeatOrThis
;
stringTerm : '"any chars"'
| '" any chars $' IDENT stringTermD
| '" any chars{' block stringTermB
;
stringTermD : 'any chars"'
| 'any chars$' IDENT stringTermD
| 'any chars{' block stringTermB
;
stringTermB : '}any chars"'
| '}any chars$' IDENT stringTermD
| '}any chars{' block stringTermB
;
op : OPERATOR
;
match : 'match' exprInLine BRACEL cases BRACER
;
cases : '|' casesBars
| casesNoBars
;
casesNoBars : caze semiOrFlatLF casesNoBars
|
;
casesBars : caze ( '|' casesBars
|
)
;
caze : ( caseFldDcl
| caseTypes
| caseStar
)
;
caseFldDcl : IDENT type caseBlock
;
caseTypes : typeList caseBlock
;
caseStar : STAR caseBlock
;
caseBlock : ARROW // if followed by '|'
| ARROW block // if block does not start with '|'
;
block : exprs
| brblock
;
brblock : BRACEL exprs BRACER
;
exprs : exprWithResult semiOrFlatLF exprs (semiOrFlatLF | )
|
;
expr : feature
| assign
| destructure
| exprInLine
| checkexpr
;
loop : loopProlog loopBody loopEpilog
| loopBody loopEpilog
| loopProlog loopBody
| loopBody
| loopProlog loopEpilog
;
loopProlog : indexVars 'variant' exprInLine
| indexVars
| 'variant' exprInLine
;
loopBody : 'while' exprInLine block
| 'while' exprInLine 'do' block
| 'do' block
;
loopEpilog : 'until' exprInLine thenPart elseBlock
| 'else' block
;
indexVars : 'for' indexVar (semi indexVars)
;
indexVar : visibility
modifiers
name
( type contract implFldInit nextValue
| contract implFldInit nextValue
| type contract implFldIter
| contract implFldIter
)
;
implFldIter : 'in' exprInLine
;
nextValue : COMMA exprInLine
|
;
cond : exprInLine
;
ifexpr : 'if' exprInLine thenPart elseBlock
;
thenPart : 'then' block
| block
;
elseBlock : 'else' block
|
;
checkexpr : 'check' cond
;
assign : 'set' name ':=' exprInLine
;
destructure : destructr
| destructrDcl
| destructrSet
;
destructr : '(' argNames ')' ':=' exprInLine
;
destructrDcl: formArgs ':=' exprInLine
;
destructrSet: 'set' '(' argNames ')' ':=' exprInLine
;
callOrFeatOrThis : anonymous
| qualThisType
| plainLambda
| call
| universeCall
;
qualThisType: qualThis
| qualThis dotTypeSuffx
;
universeCall : 'universe' dot 'this' dot call
;
anonymous : 'ref'
inherit
contract
block
;
qualThis : name ( dot name )* dot 'this'
;
dotEnv : simpletype dot 'env'
| LPAREN type RPAREN dot 'env'
;
dotType : simpletype dotTypeSuffx
| LPAREN type RPAREN dotTypeSuffx
;
dotTypeSuffx: dot 'type'
;
contract : require
ensure
;
require : 'pre' condList
|
;
ensure : 'post' condList
|
;
invariant : 'inv' condList
|
;
condList : cond ( COMMA condList
|
)
semi
;
implRout : block
| 'is' 'abstract'
| 'is' 'intrinsic'
| 'is' 'intrinsic_constructor'
| 'is' 'native'
| 'is' block
| ARROW block
| 'of' block
| fullStop
;
implFldOrRout : implRout
| implFldInit
|
;
implFldInit : ':=' exprInLine
;
type : boundType
| freeType
;
freeType : name ':' type
;
boundType : qualThis
| onetype ( PIPE onetype ) *
;
onetype : simpletype '->' simpletype // if used as function return type, no line break allowed after `->`
| pTypeList '->' simpletype // if used as function return type, no line break allowed after `->`
| pTypeList
| LPAREN type RPAREN typeTail
| simpletype
;
pTypeList : LPAREN typeList RPAREN
;
pTypeListOpt: pTypeList
|
;
typeOpt : type
|
;
simpletype : name typePars typeTail
;
typeTail : dot simpletype
|
;
typePars : typeInParens typePars
| '(' typeList ')'
|
;
typeInParens: '(' typeInParens ')'
| type // no white space except enclosed in { }, [ ], or ( ).
;
comma : COMMA
;
colon : ':'
;
dot : '.' // either preceded by white space or not followed by white space
;
fullStop : '.' // not following white space but followed by white space
;
OPERATOR : ( '!'
| '$'
| '%'
| '&'
| '*'
| '+'
| '-'
| '.'
| ':'
| '<'
| '='
| '>'
| '?'
| '^'
| '|'
| '~'
)+
;
LF : ( '\r'? '\n'
| '\r'
| '\f'
)
;
COMMA : ','
;
LPAREN : '('
;
RPAREN : ')'
;
BRACEL : '{'
;
BRACER : '}'
;
LBRACKET : '['
;
RBRACKET : ']'
;
SEMI : ';'
;
NUM_LITERAL : [0-9]+
;
IDENT : ( 'a'..'z'
| 'A'..'Z'
)
( 'a'..'z'
| 'A'..'Z'
| '0'..'9'
| '_'
)*
;
LITERAL : DIGITS_W_DOT EXPONENT
;
fragment
EXPONENT : 'E' PLUSMINUS DIGITS
| 'P' PLUSMINUS DIGITS
|
;
fragment
PLUSMINUS : '+'
| '-'
|
;
DIGITS : DEC_DIGIT_ DEC_DIGITS_
| '0' 'b' BIN_DIGIT_ BIN_DIGITS_
| '0' 'o' OCT_DIGIT_ OCT_DIGITS_
| '0' 'd' DEC_DIGIT_ DEC_DIGITS_
| '0' 'x' HEX_DIGIT_ HEX_DIGITS_
;
DIGITS_W_DOT: DIGITS
| DEC_DIGIT_ DEC_DIGITS_ DEC_TAIL
| '0' 'b' BIN_DIGIT_ BIN_DIGITS_ BIN_TAIL
| '0' 'o' OCT_DIGIT_ OCT_DIGITS_ OCT_TAIL
| '0' 'd' DEC_DIGIT_ DEC_DIGITS_ DEC_TAIL
| '0' 'x' HEX_DIGIT_ HEX_DIGITS_ HEX_TAIL
;
fragment
UNDERSCORE : '_'
|
;
BIN_DIGIT : '0' | '1'
;
BIN_DIGIT_ : UNDERSCORE BIN_DIGIT
;
fragment
BIN_DIGITS_ : BIN_DIGIT_ BIN_DIGITS_
|
;
fragment
BIN_DIGITS : BIN_DIGIT BIN_DIGITS
|
;
BIN_TAIL : '.' BIN_DIGITS
;
OCT_DIGIT : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'
;
OCT_DIGIT_ : UNDERSCORE OCT_DIGIT
;
fragment
OCT_DIGITS_ : OCT_DIGIT_ OCT_DIGITS_
|
;
fragment
OCT_DIGITS : OCT_DIGIT OCT_DIGITS
|
;
OCT_TAIL : '.' OCT_DIGITS
;
DEC_DIGIT : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
;
DEC_DIGIT_ : UNDERSCORE DEC_DIGIT
;
fragment
DEC_DIGITS_ : DEC_DIGIT_ DEC_DIGITS_
|
;
fragment
DEC_DIGITS : DEC_DIGIT DEC_DIGITS
|
;
DEC_TAIL : '.' DEC_DIGITS
;
HEX_DIGIT : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
| 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
;
HEX_DIGIT_ : UNDERSCORE HEX_DIGIT
;
fragment
HEX_DIGITS_ : HEX_DIGIT_ HEX_DIGITS_
|
;
fragment
HEX_DIGITS : HEX_DIGIT HEX_DIGITS
|
;
HEX_TAIL : '.' HEX_DIGITS
;
COLON : ':'
;
ARROW : '=>'
;
PIPE : '|'
;
STAR : '*'
;
QUESTION : '?'
;