Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

fuzion.ebnf


grammar Fuzion;

LF          : ( '\r'? '\n'
                | '\r'
                | '\f'
              )
            ;
COMMA       : ','
            ;
LPAREN      : '('
            ;
RPAREN      : ')'
            ;
BRACEL      : '{'
            ;
BRACER      : '}'
            ;
LBRACKET    : '['
            ;
RBRACKET    : ']'
            ;
SEMI        : ';'
            ;
NUM_LITERAL : [0-9]+
            ;
LITERAL     : DIGITS_W_DOT EXPONENT
            ;
EXPONENT    : 'E' PLUSMINUS DIGITS
            | 'P' PLUSMINUS DIGITS
            |
            ;
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
            ;
UNDERSCORE  : '_'
            |
            ;
BIN_DIGIT   : '0' | '1'
            ;
BIN_DIGIT_  : UNDERSCORE BIN_DIGIT
            ;
BIN_DIGITS_ : BIN_DIGIT_ BIN_DIGITS_
            |
            ;
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
            ;
OCT_DIGITS_ : OCT_DIGIT_ OCT_DIGITS_
            |
            ;
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
            ;
DEC_DIGITS_ : DEC_DIGIT_ DEC_DIGITS_
            |
            ;
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
            ;
HEX_DIGITS_ : HEX_DIGIT_ HEX_DIGITS_
            |
            ;
HEX_DIGITS  : HEX_DIGIT HEX_DIGITS
            |
            ;
HEX_TAIL    : '.' HEX_DIGITS
            ;
unit        : feature semi EOF
            ;
stmntsEof   : stmnts EOF
            ;
semiOrFlatLF: semi
            | LF
            ;
semi        : SEMI semi
            |
            ;
feature     : routine
            | field
            ;
routine     : visibility
              modifiers
              featNames
              formGens
              formArgs
              returnType
              inherits
              contract
              implRout
            ;
field       : visibility
              modifiers
              featNames
              returnType
              contract
              implFldOrRout
            ;
visibility  : visiFlag
            |
            ;
visiFlag    : 'export' visiList
            | 'private'
            | 'protected'
            | 'public'
            ;
visiList    : e=visi ( COMMA visiList
                     |
                     )
            ;
visi        : COLON qual
            | qual
            ;
qual        : name ( 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: l=genericList ( '...'
                            |
                            )
            |
            ;
genericList : e=generic  ( COMMA genericList
                         |
                         )
            ;
generic     : IDENT
              ( COLON type
              |
              )
            ;
formArgs    : LPAREN argLst RPAREN
            |
            ;
argLst      : argList
            |
            ;
argList     : argument ( COMMA argList
                       |
                       )
            ;
argument    : visibility
              modifiers
              argNames
              type
              contract
            ;
argNames    : name ( COMMA argNames
                   |
                   )
            ;
returnType  : type
            | 'value'
            | 'ref'
            |
            ;
inherits    : inherit
            |
            ;
inherit     : COLON callList
            ;
callList    : call ( COMMA callList
                   |
                   )
            ;
call        : name ( actualGens actualArgs callTail
                   | dot ( NUM_LITERAL callTail
                         | call
                         )
                   )
            ;
indexCall   : ( LBRACKET exprList RBRACKET
                ( ':=' exprInLine
                |
                )
              )
            ;
callTail    : ( indexCall
              |
              )
              ( 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
            | exprUntilSp actualsLstC
            |
            ;
actualsLst  : exprUntilSp actualsLst
            |
            ;
actualsLstC : COMMA expr actualsLstC
            |
            ;
bracketTerm : block
            | 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 expr (COMMA expr)+ RBRACKET
            | LBRACKET expr (SEMI  expr)+ RBRACKET
            ;
term        : simpleterm ( indexCall
                         |
                         )           ( dot call
                                     |
                                     )
            ;
simpleterm  : bracketTerm
            | fun
            | stringTerm
            | NUM_LITERAL
            | 'old' term
            | match
            | loop
            | ifstmnt
            | callOrFeatOrThis
            ;
stringTerm  : STRING
            // NYI string interpolation
            // | STRING$ ident stringTerm
            // | STRING{ block stringTerm
            ;
op          : OPERATOR
            ;
fun         : 'fun' function
            | 'fun' c=call
            ;
function    : formArgs
              typeOpt
              inherits
              contract
              ( block
              | 'is' block
              | ARROW e=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       : BRACEL stmnts BRACER
            ;
stmnts      :
            | s=stmnt semiOrFlatLF l=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
                  | plainLambda
                  | call
                  ;
anonymous   : returnType
              inherit
              contract
              block
            ;
qualThis    : name ( dot name )* dot 'this'
            ;
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' block
            | ARROW e=block
            ;
implFldOrRout   : implRout
                | implFldInit
                | implFldUndef
                |
                ;
implFldInit : ':=' exprAtMinIndent
            ;
implFldUndef: ':=' '?'
            ;
type        : onetype ( PIPE onetype ) *
            ;
onetype     : 'ref' simpletype
            | 'fun' funArgsOpt typeOpt
            | simpletype '->' simpletype
            | funArgs '->' simpletype
            | t=simpletype
            ;
funArgs     : LPAREN a=typeList RPAREN
            ;
funArgsOpt  : funArgs
            |
            ;
typeOpt     : type
            |
            ;
simpletype  : name actualGens
              ( dot simpletype
              |
              )
            ;
comma       : COMMA
            ;
colon       : ':'
            ;
dot         : '.'
            ;