fuzion.ebnf
grammar Fuzion;
unit : stmnts EOF
;
semiOrFlatLF: semi
| LF
;
semi : SEMI semi
|
;
feature : routine
| field
;
routine : visibility
modifiers
featNames
formGens
formArgsOpt
returnType
inherits
contract
implRout
;
field : visibility
modifiers
featNames
returnType
contract
implFldOrRout
;
visibility : visiFlag
|
;
visiFlag : 'export' visiList
| 'private'
| 'protected'
| 'public'
;
visiList : visi ( COMMA visiList
|
)
;
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
| RBRACKET
)
| 'set' ( LBRACKET RBRACKET
| IDENT
)
;
opName : 'infix' op
| 'prefix' op
| 'postfix' op
;
modifiers : modifier modifiers
|
;
modifier : 'lazy'
| 'synchronized'
| 'redef'
| 'redefine'
| 'const'
| 'leaf'
;
featNames : qual (COMMA featNames
|
)
;
formGens : '<' formGensBody '>'
| '<' '>'
|
;
formGensBody: genericList ( '...'
|
)
|
;
genericList : generic ( COMMA genericList
|
)
;
generic : IDENT
( COLON type
|
)
;
formArgsOpt : formArgs
|
;
formArgs : LPAREN argLst RPAREN
;
argLst : argList
|
;
argList : argument ( COMMA argList
|
)
;
argument : visibility
modifiers
argNames
argType
contract
;
argType : typeType
| type
| type dot typeType
;
typeType : 'type'
| 'type' '...'
;
argNames : name ( COMMA argNames
|
)
;
returnType : type
| 'value'
| 'ref'
|
;
inherits : inherit
|
;
inherit : COLON callList
;
callList : call ( COMMA callList
|
)
;
call : nameOrType actuals callTail
;
nameOrType : name
| 'type'
;
actuals : actualGens actualArgs
| dot NUM_LITERAL
;
indexCall : ( LBRACKET exprList RBRACKET
( ':=' exprInLine
|
)
)
;
callTail : indexCallOpt dotCallOpt
;
indexCallOpt: indexCall
|
;
dotCallOpt : dot call
|
;
actualGens : '<' typeList '>'
| '<' '>'
|
;
typeList : type ( COMMA typeList
|
)
;
actualArgs : actualsList // must be in same line as name of called feature
| LPAREN exprList RPAREN
| LPAREN RPAREN
;
exprList : expr ( COMMA exprList
|
)
;
actualsList : exprUntilSp actualsLst
|
;
actualsLst : exprUntilSp actualsLst
|
;
bracketTerm : brblock
| klammer
| inlineArray
;
exprUntilSp : expr // no white space except enclosed in { }, [ ], or ( ).
;
exprInLine : expr // within one line
| bracketTerm // stretching over one or several lines
;
exprAtMinIndent : block
| exprInLine
;
expr : opExpr
( QUESTION expr COLON expr
| QUESTION cases
|
)
;
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
| fun
| stringTerm
| NUM_LITERAL
| 'old' term
| match
| loop
| ifstmnt
| 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
;
fun : 'fun' function
| 'fun' call
;
function : formArgsOpt
typeOpt
inherits
contract
( block
| 'is' block
| ARROW block
)
;
match : 'match' exprInLine BRACEL cases BRACER
;
cases : caze maybecomma ( '|' casesBars // NYI: grammar not correct yet.
| casesNoBars
)
;
casesBars : caze maybecomma ( '|' casesBars
|
)
;
caseNoBars : caze maybecomma ( casesNoBars
|
)
;
casesNoBars : caseNoBars caseNoBars
| caseNoBars
;
maybecomma : comma
|
;
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 : stmnts
| brblock
;
brblock : BRACEL stmnts BRACER
;
stmnts :
| stmnt semiOrFlatLF stmnts (semiOrFlatLF | )
;
stmnt : feature
| assign
| destructure
| exprInLine
| checkstmt
;
loop : loopProlog loopBody loopEpilog
| loopBody loopEpilog
| loopProlog loopBody
| loopBody
| loopProlog loopEpilog
;
loopProlog : indexVars 'variant' exprInLine
| indexVars
| 'variant' exprInLine
;
loopBody : 'while' exprAtMinIndent block
| 'while' exprAtMinIndent 'do' block
| 'do' block
;
loopEpilog : 'until' exprAtMinIndent thenPart elseBlockOpt
| elseBlock
;
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 exprAtMinIndent
|
;
cond : exprInLine
;
ifstmnt : 'if' exprInLine thenPart elseBlockOpt
;
thenPart : 'then' block
| block
;
elseBlockOpt: elseBlock
|
;
elseBlock : 'else' ( ifstmnt
| block
)
;
checkstmt : 'check' cond
;
assign : 'set' name ':=' exprInLine
;
destructure : destructr
| destructrDcl
| destructrSet
;
destructr : '(' argNames ')' ':=' exprInLine
;
destructrDcl: formArgs ':=' exprInLine
;
destructrSet: 'set' '(' argNames ')' ':=' exprInLine
;
callOrFeatOrThis : anonymous
| qualThis
| env
| plainLambda
| call
;
anonymous : returnType
inherit
contract
block
;
qualThis : name ( dot name )* dot 'this'
;
env : simpletype dot 'env'
;
contract : require
ensure
invariant
;
require : 'pre' condList
|
;
ensure : 'post' condList
|
;
invariant : 'inv' condList
|
;
condList : cond ( COMMA condList
|
)
semi
;
implRout : block
| 'is' 'abstract'
| 'is' 'intrinsic'
| 'is' 'intrinsic_constructor'
| 'is' block
| ARROW block
| 'of' block
| fullStop
;
implFldOrRout : implRout
| implFldInit
| implFldUndef
|
;
implFldInit : ':=' exprAtMinIndent
;
implFldUndef: ':=' '?'
;
type : onetype ( PIPE onetype ) *
;
onetype : 'ref' simpletype
| 'fun' funArgsOpt typeOpt
| simpletype '->' simpletype
| funArgs '->' simpletype
| simpletype
;
funArgs : LPAREN typeList RPAREN
;
funArgsOpt : funArgs
|
;
typeOpt : type
|
;
simpletype : name actualGens typeTail
| 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 : '?'
;