Edit Page
Grammar

Notation

This section informally explains the grammar notation used below.

Symbols and naming

Terminal symbol names start with an uppercase letter, e.g. SimpleName.
Nonterminal symbol names start with lowercase letter, e.g. kotlinFile.
Each production starts with a colon (:).
Symbol definitions may have many productions and are terminated by a semicolon (;).
Symbol definitions may be prepended with attributes, e.g. start attribute denotes a start symbol.

EBNF expressions

Operator | denotes alternative.
Operator * denotes iteration (zero or more).
Operator + denotes iteration (one or more).
Operator ? denotes option (zero or one).
alpha{beta} denotes a nonempty beta-separated list of alpha’s.
Operator ``++’’ means that no space or comment allowed between operands.

Semicolons

Kotlin provides “semicolon inference”: syntactically, subsentences (e.g., statements, declarations etc) are separated by the pseudo-token SEMI, which stands for “semicolon or newline”. In most cases, there’s no need for semicolons in Kotlin code.

Syntax

Relevant pages: Packages

start
kotlinFile
  : preamble toplevelObject*
  ;
start
script
  : preamble expression*
  ;
preamble
(used by script, kotlinFile)
fileAnnotations
(used by preamble)
  : fileAnnotation*
  ;
fileAnnotation
(used by fileAnnotations)
  : "@" "file" ":" ("[" annotationEntry+ "]" | annotationEntry)
  ;
packageHeader
(used by preamble)
  : modifiers "package" SimpleName{"."} SEMI?
  ;
import
(used by preamble, package)
  : "import" SimpleName{"."} ("." "*" | "as" SimpleName)? SEMI?
  ;

See Imports

toplevelObject
(used by package, kotlinFile)
  : package
  : class
  : object
  : function
  : property
  ;
package
(used by toplevelObject)
  : "package" SimpleName{"."} "{"
       import*
       toplevelObject*
    "}"
  ;

See Packages

  : modifiers ("class" | "interface") SimpleName
      typeParameters?
      primaryConstructor?
      (":" annotations delegationSpecifier{","})?
      typeConstraints
      (classBody? | enumClassBody)
  ;
primaryConstructor
(used by class, object)
  : (modifiers "constructor")? ("(" functionParameter{","} ")")
  ;
classBody
  : ("{" members "}")?
  ;
members
  : memberDeclaration*
  ;
delegationSpecifier
(used by objectLiteral, class, object)
explicitDelegation
  : userType "by" expression 
  ;
typeParameters
(used by class, property, function)
  : "<" typeParameter{","} ">"
  ;
typeParameter
(used by typeParameters)
  : modifiers SimpleName (":" userType)?
  ;
typeConstraints
(used by class, property, function)
  : ("where" typeConstraint{","})?
  ;
typeConstraint
(used by typeConstraints)
  : annotations SimpleName ":" type
  ;

Class members

memberDeclaration
(used by members)
  : companionObject
  : object
  : function
  : property
  : class
  : typeAlias
  : anonymousInitializer
  : secondaryConstructor
  ;
anonymousInitializer
(used by memberDeclaration)
  : "init" block
  ;
companionObject
(used by memberDeclaration)
  : modifiers "companion" "object"
  ;
valueParameters
  : "(" functionParameter{","}? ")" 
  ;
functionParameter
  : modifiers ("val" | "var")? parameter ("=" expression)?
  ;
initializer
(used by enumEntry)
  : modifiers "fun" typeParameters?
      (type "." | annotations)?
      SimpleName
      typeParameters? valueParameters (":" type)?
      typeConstraints
      functionBody?
  ;
functionBody
(used by getter, setter, function)
  : block
  : "=" expression
  ;
variableDeclarationEntry
  : SimpleName (":" type)?
  ;
multipleVariableDeclarations
(used by for, property)
  : "(" variableDeclarationEntry{","} ")"
  ;
  : modifiers ("val" | "var")
      typeParameters? (type "." | annotations)?
      (multipleVariableDeclarations | variableDeclarationEntry)
      typeConstraints
      ("by" | "=" expression SEMI?)?
      (getter? setter? | setter? getter?) SEMI?
  ;
getter
(used by property)
  : modifiers "get"
  : modifiers "get" "(" ")" (":" type)? functionBody
  ;
setter
(used by property)
  : modifiers "set"
  : modifiers "set" "(" modifiers (SimpleName | parameter) ")" functionBody
  ;
parameter
  : SimpleName ":" type
  ;
secondaryConstructor
(used by memberDeclaration)
  : modifiers "constructor" valueParameters (":" constructorDelegationCall)? block
  ;
constructorDelegationCall
  : "this" valueArguments
  : "super" valueArguments
  ;

Enum classes

See Enum classes

enumClassBody
(used by class)
  : "{" enumEntries (";" members)? "}"
  ;
enumEntries
(used by enumClassBody)
  : enumEntry*
  ;
enumEntries
(used by enumClassBody)
  : (enumEntry ","? )?
  ;
enumEntry
(used by enumEntries)
  : modifiers SimpleName ((":" initializer) | ("(" arguments ")"))? classBody?
  ;

Types

See Types

typeDescriptor
  : "(" typeDescriptor ")"
  : functionType
  : userType
  : nullableType
  : "dynamic"
  ;
nullableType
(used by typeDescriptor)
  : typeDescriptor "?"
simpleUserType
(used by userType)
  : SimpleName ("<" (optionalProjection type | "*"){","} ">")?
  ;
optionalProjection
(used by simpleUserType)
  : varianceAnnotation
  ;
functionType
(used by typeDescriptor)
  : (type ".")? "(" (parameter | modifiers  type){","} ")" "->" type?
  ;

Control structures

See Control structures

if
(used by atomicExpression)
  : "if" "(" expression ")" expression SEMI? ("else" expression)?
  ;
try
(used by atomicExpression)
  : "try" block catchBlock* finallyBlock?
  ;
catchBlock
(used by try)
  : "catch" "(" annotations SimpleName ":" userType ")" block
  ;
finallyBlock
(used by try)
  : "finally" block
  ;
loop
(used by atomicExpression)
  : for
  : while
  : doWhile
  ;
for
(used by loop)
while
(used by loop)
  : "while" "(" expression ")" expression
  ;
doWhile
(used by loop)
  : "do" expression "while" "(" expression ")"
  ;

Expressions

Precedence

Precedence Title Symbols
Highest Postfix ++, --, ., ?., ?
  Prefix -, +, ++, --, !, labelDefinition@@
  Type RHS :, as, as?
  Multiplicative *, /, %
  Additive +, -
  Range ..
  Infix function SimpleName
  Elvis ?:
  Named checks in, !in, is, !is
  Comparison <, >, <=, >=
  Equality ==, \!==
  Conjunction &&
  Disjunction ||
Lowest Assignment =, +=, -=, *=, /=, %=

Rules

disjunction
(used by expression)
  : conjunction ("||" conjunction)*
  ;
conjunction
(used by disjunction)
  : equalityComparison ("&&" equalityComparison)*
  ;
equalityComparison
(used by conjunction)
comparison
(used by equalityComparison)
namedInfix
(used by comparison)
elvisExpression
(used by namedInfix)
  : infixFunctionCall ("?:" infixFunctionCall)*
  ;
infixFunctionCall
(used by elvisExpression)
rangeExpression
(used by infixFunctionCall)
  : additiveExpression (".." additiveExpression)*
  ;
multiplicativeExpression
(used by additiveExpression)
prefixUnaryExpression
(used by typeRHS)
callableReference
  : (userType "?"*)? "::" SimpleName typeArguments?
  ;
atomicExpression
  : "(" expression ")"
  : literalConstant
  : functionLiteral
  : "this" labelReference?
  : "super" ("<" type ">")? labelReference?
  : if
  : when
  : try
  : objectLiteral
  : jump
  : loop
  : SimpleName
  : FieldName
  : "package" 
  ;
labelReference
(used by atomicExpression, jump)
  : "@" ++ LabelName
  ;
labelDefinition
  : LabelName ++ "@"
  ;
literalConstant
(used by atomicExpression)
  : "true" | "false"
  : stringTemplate
  : NoEscapeString
  : IntegerLiteral
  : HexadecimalLiteral
  : CharacterLiteral
  : FloatLiteral
  : "null"
  ;
stringTemplate
(used by literalConstant)
  : "\"" stringTemplateElement* "\""
  ;
stringTemplateElement
(used by stringTemplate)
longTemplate
  : "${" expression "}"
  ;
isRHS
  : type
  ;
declaration
(used by statement)
  : function
  : property
  : class
  : object
  ;
statement
(used by statements)
  : declaration
  : expression
  ;
multiplicativeOperation
  : "*" : "/" : "%"
  ;
additiveOperation
(used by additiveExpression)
  : "+" : "-"
  ;
inOperation
(used by namedInfix)
  : "in" : "!in"
  ;
typeOperation
(used by typeRHS)
  : "as" : "as?" : ":"
  ;
isOperation
(used by namedInfix)
  : "is" : "!is"
  ;
comparisonOperation
(used by comparison)
  : "<" : ">" : ">=" : "<="
  ;
equalityOperation
(used by equalityComparison)
  : "!=" : "=="
  ;
assignmentOperator
(used by expression)
  : "="
  : "+=" : "-=" : "*=" : "/=" : "%="
  ;
prefixUnaryOperation
  : "-" : "+"
  : "++" : "--"
  : "!"  
  : annotations 
  : labelDefinition
  ;
postfixUnaryOperation
  : "++" : "--" : "!!"
  : callSuffix
  : arrayAccess
  : memberAccessOperation postfixUnaryExpression 
  ;
annotatedLambda
(used by callSuffix)
memberAccessOperation
  : "." : "?." : "?"
  ;
  : "<" type{","} ">"
  ;
  : "(" (SimpleName "=")? "*"? expression{","} ")"
  ;
jump
(used by atomicExpression)
  : "throw" expression
  : "return" ++ labelReference? expression?
  : "continue" ++ labelReference?
  : "break" ++ labelReference?
  ;
functionLiteral
  : "{" statements "}"
  : "{" (modifiers SimpleName){","} "->" statements "}"
  ;
statements
(used by block, functionLiteral)
  : SEMI* statement{SEMI+} SEMI*
  ;
constructorInvocation
  : userType callSuffix
  ;
arrayAccess
  : "[" expression{","} "]"
  ;
objectLiteral
(used by atomicExpression)
  : "object" (":" delegationSpecifier{","})? classBody 
  ;

Pattern matching

See When-expression

when
(used by atomicExpression)
  : "when" ("(" expression ")")? "{"
        whenEntry*
    "}"
  ;
whenEntry
(used by when)
  : whenCondition{","} "->" expression SEMI
  : "else" "->" expression SEMI
  ;
whenCondition
(used by whenEntry)
  : expression
  : ("in" | "!in") expression
  : ("is" | "!is") isRHS
  ;

Modifiers

modifier
(used by modifiers)
  : modifierKeyword
  ;
modifierKeyword
(used by modifier)
classModifier
(used by modifierKeyword)
  : "abstract"
  : "final"
  : "enum"
  : "open"
  : "annotation"
  ;
memberModifier
(used by modifierKeyword)
  : "override"
  : "open"
  : "final"
  : "abstract"
  ;
accessModifier
(used by modifierKeyword)
  : "private"
  : "protected"
  : "public"
  : "internal"
  ;
varianceAnnotation
  : "in"
  : "out"
  ;

Annotations

annotation
(used by annotations)
  : "@" (annotationUseSiteTarget ":")? unescapedAnnotation
  ;
annotationList
(used by annotations)
  : "@" (annotationUseSiteTarget ":")? "[" unescapedAnnotation+ "]"
  ;
annotationUseSiteTarget
  : "file"
  : "field"
  : "property"
  : "get"
  : "set"
  : "param"
  : "sparam"
  ;
unescapedAnnotation
  : SimpleName{"."} typeArguments? valueArguments?
  ;

Lexical structure

helper
Digit
  : ["0".."9"];
IntegerLiteral
(used by literalConstant)
  : Digit+?
FloatLiteral
(used by literalConstant)
  : <Java double literal>;
helper
  : Digit | ["A".."F", "a".."f"];
HexadecimalLiteral
(used by literalConstant)
  : "0x" HexDigit+;
CharacterLiteral
(used by literalConstant)
  : <character as in Java>;
NoEscapeString
(used by literalConstant)
  : <"""-quoted string>;
RegularStringPart
  : <any character other than backslash, quote, $ or newline>
ShortTemplateEntryStart:
  : "$"
EscapeSequence:
  : UnicodeEscapeSequence | RegularEscapeSequence
UnicodeEscapeSequence:
  : "\u" HexDigit{4}
RegularEscapeSequence:
  : "\" <any character other than newline>
  : <semicolon or newline>;
FieldName
(used by atomicExpression)
  : "$" SimpleName;
LabelName
  : "@" SimpleName;