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

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