fuzion.ebnf
grammar Fuzion;
unit : block 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'
;
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
;
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 pureCallList
;
pureCallList : pureCall ( COMMA pureCallList
|
)
;
callList : call ( COMMA callList
|
)
;
pureCall : name actuals pureCallTail
;
call : name actuals callTail
;
actuals : actualArgs
| dot NUM_LITERAL
;
indexCall : LBRACKET actualCommas RBRACKET indexTail
;
indexTail : ':=' exprInLine
|
;
pureCallTail: indexCall pureCallTail
| dot call pureCallTail
|
;
callTail : indexCall callTail
| dot call callTail
| dot 'env' callTail
| dot 'type' callTail
| dot 'this' callTail
|
;
typeList : type ( COMMA typeList
|
)
;
actualArgs : actualSpaces
| LPAREN actualCommas RPAREN
;
actualCommas: actualSome
|
;
actualSome : operatorExpr actualMore
;
actualMore : COMMA actualSome
|
;
actualSpaces: actualSpace actualSpaces
|
;
bracketTerm : brblock
| klammer
| inlineArray
;
actualSpace : operatorExpr // no white space or semicolon except enclosed in { }, [ ], or ( ).
;
exprInLine : operatorExpr // within one line
;
operatorExpr : opExpr
( QUESTION expr COLON expr
| QUESTION casesBars
|
)
;
opExpr : opTail
| ops opTail
| op
| dot call
;
ops : dotCallOrOp ops
| dotCallOrOp
;
opTail : term
| term ops
| term ops opTail
;
klammer : klammerExpr
| tuple
| klammerLambd
;
klammerExpr : LPAREN expr RPAREN
;
tuple : LPAREN RPAREN
| LPAREN operatorExpr (COMMA operatorExpr)+ RPAREN
;
klammerLambd: tuple lambda
;
lambda : '->' block
;
plainLambda : argNames lambda
;
inlineArray : LBRACKET RBRACKET
| LBRACKET cmaSepElmts RBRACKET
| LBRACKET semiSepElmts RBRACKET
;
cmaSepElmts : operatorExpr addCmaElmts
;
addCmaElmts : COMMA cmaSepElmts
| COMMA
|
;
semiSepElmts: operatorExpr addSemiElmts
;
addSemiElmts: SEMI semiSepElmts
| SEMI
|
;
term : simpleterm callTail
;
simpleterm : bracketTerm
| stringTerm
| NUM_LITERAL
| match
| loop
| ifexpr
| 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
;
dotCallOrOp : dot call
| OPERATOR
;
match : 'match' exprInLine cases
| '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 : expr semiOrFlatLF exprs (semiOrFlatLF | )
|
;
expr : checkexpr
| assign
| destructure
| feature
| operatorExpr
;
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 loopElseBlock
| 'else' block
;
indexVars : 'for' indexVar (semi indexVars)
;
indexVar : visibility
modifiers
name
( type implFldInit nextValue
| implFldInit nextValue
| type implFldIter
| implFldIter
)
;
implFldIter : 'in' exprInLine
;
nextValue : COMMA exprInLine
|
;
ifexpr : 'if' exprInLine thenPart elseBlock
;
thenPart : 'then' block
| block
;
elseBlock : 'else' block
|
;
loopElseBlock : 'else' block
|
;
checkexpr : 'check' block
;
assign : 'set' name ':=' exprInLine
;
destructure : destructr
| destructrDcl
;
destructr : '(' argNames ')' ':=' exprInLine
;
destructrDcl: formArgs ':=' exprInLine
;
callOrFeatOrThis : anonymous
| plainLambda
| universeCall
| call
;
universe : 'universe'
;
universeCall : universe dot call
;
anonymous : 'ref'
inherit
block
;
contract : require ensure
;
require : 'pre' block // may start at min indent
| 'pre' 'else' block // may start at min indent
|
;
ensure : 'post' block // may start at min indent
| 'post' 'then' block // may start at min indent
|
;
invariant : 'inv' block
|
;
implRout : 'is' 'abstract'
| ARROW 'abstract'
| 'is' 'intrinsic'
| ARROW 'intrinsic'
| 'is' 'native'
| ARROW 'native'
| 'is' block
| ARROW block
| 'of' block
| fullStop
;
implFldOrRout : implRout // may start at min indent
| implFldInit // may start at min indent
|
;
implFldInit : ':=' operatorExpr // may start at min indent
;
type : boundType
| freeType
;
freeType : name ':' type
;
boundType : 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
| dot 'this'
|
;
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 : ';'
;
IDENT : ( 'a'..'z'
| 'A'..'Z'
)
( 'a'..'z'
| 'A'..'Z'
| '0'..'9'
| '_'
)*
;
NUM_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 : '?'
;
last changed: 2024-11-14