--- layout: doc-page title: "Scala Syntax Summary" --- The following descriptions of Scala tokens uses literal characters `‘c’` when referring to the ASCII fragment `\u0000` – `\u007F`. _Unicode escapes_ are used to represent the Unicode character with the given hexadecimal code: ```ebnf UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ ``` Informal descriptions are typeset as `“some comment”`. ### Lexical Syntax The lexical syntax of Scala is given by the following grammar in EBNF form. ```ebnf whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’ upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ “… and Unicode category Lu” lower ::= ‘a’ | … | ‘z’ “… and Unicode category Ll” letter ::= upper | lower “… and Unicode categories Lo, Lt, Nl” digit ::= ‘0’ | … | ‘9’ paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ opchar ::= “printableChar not matched by (whiteSpace | upper | lower | letter | digit | paren | delim | opchar | Unicode_Sm | Unicode_So)” printableChar ::= “all characters in [\u0020, \u007F] inclusive” charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’) op ::= opchar {opchar} varid ::= lower idrest alphaid ::= upper idrest | varid plainid ::= alphaid | op id ::= plainid | ‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’ | INT // interpolation id, only for quasi-quotes idrest ::= {letter | digit} [‘_’ op] integerLiteral ::= (decimalNumeral | hexNumeral) [‘L’ | ‘l’] decimalNumeral ::= ‘0’ | nonZeroDigit {digit} hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit {hexDigit} digit ::= ‘0’ | nonZeroDigit nonZeroDigit ::= ‘1’ | … | ‘9’ floatingPointLiteral ::= digit {digit} ‘.’ {digit} [exponentPart] [floatType] | ‘.’ digit {digit} [exponentPart] [floatType] | digit {digit} exponentPart [floatType] | digit {digit} [exponentPart] floatType exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit} floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ booleanLiteral ::= ‘true’ | ‘false’ characterLiteral ::= ‘'’ (printableChar | charEscapeSeq) ‘'’ stringLiteral ::= ‘"’ {stringElement} ‘"’ | ‘"""’ multiLineChars ‘"""’ stringElement ::= printableChar \ (‘"’ | ‘\’) | UnicodeEscape | charEscapeSeq multiLineChars ::= {[‘"’] [‘"’] char \ ‘"’} {‘"’} processedStringLiteral ::= alphaid ‘"’ {printableChar \ (‘"’ | ‘$’) | escape} ‘"’ | alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’ escape ::= ‘$$’ | ‘$’ letter { letter | digit } | ‘{’ Block [‘;’ whiteSpace stringFormat whiteSpace] ‘}’ stringFormat ::= {printableChar \ (‘"’ | ‘}’ | ‘ ’ | ‘\t’ | ‘\n’)} symbolLiteral ::= ‘'’ plainid comment ::= ‘/*’ “any sequence of characters; nested comments are allowed” ‘*/’ | ‘//’ “any sequence of characters up to end of line” nl ::= “new line character” semi ::= ‘;’ | nl {nl} ``` ## Context-free Syntax The context-free syntax of Scala is given by the following EBNF grammar: ### Literals and Paths ```ebnf SimpleLiteral ::= [‘-’] integerLiteral | [‘-’] floatingPointLiteral | booleanLiteral | characterLiteral | stringLiteral Literal ::= SimpleLiteral | processedStringLiteral | symbolLiteral | ‘null’ QualId ::= id {‘.’ id} ids ::= id {‘,’ id} Path ::= StableId | [id ‘.’] ‘this’ StableId ::= id | Path ‘.’ id | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id ClassQualifier ::= ‘[’ id ‘]’ ``` ### Types ```ebnf Type ::= [‘implicit’] FunArgTypes ‘=>’ Type Function(ts, t) | HkTypeParamClause ‘=>’ Type TypeLambda(ps, t) | InfixType FunArgTypes ::= InfixType | ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’ InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2) RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds) WithType ::= AnnotType {‘with’ AnnotType} (deprecated) AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleType TypeArgs AppliedTypeTree(t, args) | SimpleType ‘#’ id Select(t, name) | StableId | Path ‘.’ ‘type’ SingletonTypeTree(p) | ‘(’ ArgTypes ‘)’ Tuple(ts) | ‘_’ TypeBounds | Refinement RefinedTypeTree(EmptyTree, refinement) | SimpleLiteral SingletonTypeTree(l) ArgTypes ::= Type {‘,’ Type} | NamedTypeArg {‘,’ NamedTypeArg} FunArgType ::= Type | ‘=>’ Type PrefixOp(=>, t) ParamType ::= [‘=>’] ParamValueType ParamValueType ::= Type [‘*’] PostfixOp(t, "*") TypeArgs ::= ‘[’ ArgTypes ‘]’ ts NamedTypeArg ::= id ‘=’ Type NamedArg(id, t) NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts Refinement ::= ‘{’ [Dcl] {semi [Dcl]} ‘}’ ds TypeBounds ::= [‘>:’ Type] [‘<:’ Type] | INT TypeBoundsTree(lo, hi) TypeParamBounds ::= TypeBounds {‘<%’ Type} {‘:’ Type} ContextBounds(typeBounds, tps) ``` ### Expressions ```ebnf Expr ::= [‘implicit’] FunParams ‘=>’ Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) | Expr1 BlockResult ::= [‘implicit’] FunParams ‘=>’ Block | Expr1 FunParams ::= Bindings | id | ‘_’ Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] If(Parens(cond), thenp, elsep?) | ‘if’ Expr ‘then’ Expr [[semi] ‘else’ Expr] If(cond, thenp, elsep?) | ‘while’ ‘(’ Expr ‘)’ {nl} Expr WhileDo(Parens(cond), body) | ‘while’ Expr ‘do’ Expr WhileDo(cond, body) | ‘do’ Expr [semi] ‘while’ Expr DoWhile(expr, cond) | ‘try’ Expr Catches [‘finally’ Expr] Try(expr, catches, expr?) | ‘try’ Expr [‘finally’ Expr] Try(expr, Nil, expr?) | ‘throw’ Expr Throw(expr) | ‘return’ [Expr] Return(expr?) | ForExpr | [SimpleExpr ‘.’] id ‘=’ Expr Assign(expr, expr) | SimpleExpr1 ArgumentExprs ‘=’ Expr Assign(expr, expr) | PostfixExpr [Ascription] | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ Match(expr, cases) -- point on match Ascription ::= ‘:’ InfixType Typed(expr, tp) | ‘:’ Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*) Catches ::= ‘catch’ Expr PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op) InfixExpr ::= PrefixExpr | InfixExpr id [nl] InfixExpr InfixOp(expr, op, expr) PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr PrefixOp(expr, op) SimpleExpr ::= ‘new’ Template New(templ) | BlockExpr | SimpleExpr1 [‘_’] PostfixOp(expr, _) SimpleExpr1 ::= Literal | Path | ‘_’ | ‘(’ ExprsInParens ‘)’ Parens(exprs) | SimpleExpr ‘.’ id Select(expr, id) | SimpleExpr (TypeArgs | NamedTypeArgs) TypeApply(expr, args) | SimpleExpr1 ArgumentExprs Apply(expr, args) | XmlExpr ExprsInParens ::= ExprInParens {‘,’ ExprInParens} ExprInParens ::= PostfixExpr ‘:’ Type | Expr ParArgumentExprs ::= ‘(’ ExprsInParens ‘)’ exprs | ‘(’ [ExprsInParens] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ exprs :+ Typed(expr, Ident(wildcardStar)) ArgumentExprs ::= ParArgumentExprs | [nl] BlockExpr BlockExpr ::= ‘{’ CaseClauses ‘}’ Match(EmptyTree, cases) | ‘{’ Block ‘}’ block // starts at { Block ::= {BlockStat semi} [BlockResult] Block(stats, expr?) BlockStat ::= Import | {Annotation} [‘implicit’ | ‘lazy’] Def | {Annotation} {LocalModifier} TmplDef | Expr1 ForExpr ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) ForYield(enums, expr) {nl} [‘yield’] Expr | ‘for’ Enumerators (‘do’ Expr | ‘yield’ Expr) ForDo(enums, expr) Enumerators ::= Generator {semi Enumerator | Guard} Enumerator ::= Generator | Guard | Pattern1 ‘=’ Expr GenAlias(pat, expr) Generator ::= Pattern1 ‘<-’ Expr GenFrom(pat, expr) Guard ::= ‘if’ PostfixExpr CaseClauses ::= CaseClause { CaseClause } CaseDef(pat, guard?, block) // block starts at => CaseClause ::= ‘case’ (Pattern [Guard] ‘=>’ Block | INT) Pattern ::= Pattern1 { ‘|’ Pattern1 } Alternative(pats) Pattern1 ::= PatVar ‘:’ RefinedType Bind(name, Typed(Ident(wildcard), tpe)) | Pattern2 Pattern2 ::= [varid ‘@’] InfixPattern Bind(name, pat) InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat) SimplePattern ::= PatVar Ident(wildcard) | Literal Bind(name, Ident(wildcard)) | ‘(’ [Patterns] ‘)’ Parens(pats) Tuple(pats) | XmlPattern | SimplePattern1 [TypeArgs] [ArgumentPatterns] SimplePattern1 ::= Path | ‘{’ Block ‘}’ | SimplePattern1 ‘.’ id PatVar ::= varid | ‘_’ Patterns ::= Pattern {‘,’ Pattern} ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ Apply(fn, pats) | ‘(’ [Patterns ‘,’] Pattern2 ‘:’ ‘_’ ‘*’ ‘)’ ``` ### Type and Value Parameters ```ebnf ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’ ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeDef(Modifiers, name, tparams, bounds) id [HkTypeParamClause] TypeParamBounds Bound(below, above, context) DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (Id[HkTypeParamClause] | ‘_’) TypeBounds ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ ‘implicit’ ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ [ClsParams] ‘)’ ClsParams ::= ClsParam {‘,’ ClsParam} ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param Param ::= id ‘:’ ParamType [‘=’ Expr] | INT DefParamClauses ::= {DefParamClause} [[nl] ‘(’ ‘implicit’ DefParams ‘)’] DefParamClause ::= [nl] ‘(’ [DefParams] ‘)’ DefParams ::= DefParam {‘,’ DefParam} DefParam ::= {Annotation} [‘inline’] Param ValDef(mods, id, tpe, expr) -- point of mods at id. ``` ### Bindings and Imports ```ebnf Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’ Binding ::= (id | ‘_’) [‘:’ Type] ValDef(_, id, tpe, EmptyTree) Modifier ::= LocalModifier | AccessModifier | ‘override’ LocalModifier ::= ‘abstract’ | ‘final’ | ‘sealed’ | ‘implicit’ | ‘lazy’ AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’ Annotation ::= ‘@’ SimpleType {ParArgumentExprs} Apply(tpe, args) TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ (self, stats) TemplateStat ::= Import | {Annotation [nl]} {Modifier} Def | {Annotation [nl]} {Modifier} Dcl | EnumCaseStat | Expr1 | SelfType ::= id [‘:’ InfixType] ‘=>’ ValDef(_, name, tpt, _) | ‘this’ ‘:’ InfixType ‘=>’ Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) Import(expr, sels) ImportSelectors ::= ‘{’ {ImportSelector ‘,’} (ImportSelector | ‘_’) ‘}’ ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] Ident(name), Pair(id, id) ``` ### Declarations and Definitions ```ebnf Dcl ::= ‘val’ ValDcl | ‘var’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl | INT ValDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree) VarDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree) DefDcl ::= DefSig [‘:’ Type] DefDef(_, name, tparams, vparamss, tpe, EmptyTree) DefSig ::= id [DefTypeParamClause] DefParamClauses TypeDcl ::= id [TypTypeParamClause] [‘=’ Type] TypeDefTree(_, name, tparams, tpt) | id [HkTypeParamClause] TypeBounds TypeDefTree(_, name, tparams, bounds) Def ::= ‘val’ PatDef | ‘var’ VarDef | ‘def’ DefDef | ‘type’ {nl} TypeDcl | TmplDef | INT PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr PatDef(_, pats, tpe?, expr) VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ DefDef ::= DefSig [‘:’ Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) | DefSig [nl] ‘{’ Block ‘}’ DefDef(_, name, tparams, vparamss, tpe, Block) | ‘this’ DefParamClause DefParamClauses DefDef(_, , Nil, vparamss, EmptyTree, expr | Block) (‘=’ ConstrExpr | [nl] ConstrBlock) TmplDef ::= ([‘case’ | `enum'] ‘class’ | trait’) ClassDef | [‘case’] ‘object’ ObjectDef | `enum' EnumDef ClassDef ::= id ClassConstr TemplateOpt ClassDef(mods, name, tparams, templ) ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses with DefDef(_, , Nil, vparamss, EmptyTree, EmptyTree) as first stat ConstrMods ::= AccessModifier | Annotation {Annotation} (AccessModifier | ‘this’) ObjectDef ::= id TemplateOpt ModuleDef(mods, name, template) // no constructor EnumDef ::= id ClassConstr [`extends' [ConstrApps]] EnumDef(mods, name, tparams, template) [nl] ‘{’ EnumCaseStat {semi EnumCaseStat} ‘}’ EnumCaseStat ::= {Annotation [nl]} {Modifier} EnumCase EnumCase ::= `case' (EnumClassDef | ObjectDef | ids) EnumClassDef ::= id [ClsTpeParamClause | ClsParamClause] ClassDef(mods, name, tparams, templ) ClsParamClauses TemplateOpt TemplateOpt ::= [‘extends’ Template | [nl] TemplateBody] Template ::= ConstrApps [TemplateBody] | TemplateBody Template(constr, parents, self, stats) ConstrApps ::= ConstrApp {‘with’ ConstrApp} ConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args) ConstrExpr ::= SelfInvocation | ConstrBlock SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} ConstrBlock ::= ‘{’ SelfInvocation {semi BlockStat} ‘}’ TopStatSeq ::= TopStat {semi TopStat} TopStat ::= {Annotation [nl]} {Modifier} TmplDef | Import | Packaging | PackageObject Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ Package(qid, stats) PackageObject ::= ‘package’ ‘object’ ObjectDef object with package in mods. CompilationUnit ::= {‘package’ QualId semi} TopStatSeq Package(qid, stats) ```