Scala 3 Syntax Summary
The following description of Scala tokens uses literal characters βcβ when referring to the ASCII fragment \u0000 β \u007F.
Informal descriptions are typeset as βsome commentβ.
Lexical Syntax
The lexical syntax of Scala is given by the following grammar in EBNF form:
whiteSpace ::= β\u0020β | β\u0009β | β\u000Dβ | β\u000Aβ
upper ::= βAβ | ... | βZβ | β$β and any character in Unicode categories Lu, Lt or Nl,
and any character in Unicode categories Lo and Lm that doesn't have
contributory property Other_Lowercase
lower ::= βaβ | ... | βzβ | β_β and any character in Unicode category Ll,
and any character in Unicode categories Lo or Lm that has contributory
property Other_Lowercase
letter ::= upper | lower
digit ::= β0β | ... | β9β
paren ::= β(β | β)β | β[β | β]β | β{β | β}β
delim ::= β`β | β'β | β"β | β.β | β;β | β,β
opchar ::= β!β | β#β | β%β | β&β | β*β | β+β | β-β | β/β | β:β |
β<β | β=β | β>β | β?β | β@β | β\β | β^β | β|β | β~β
and any character in Unicode categories Sm or So
printableChar ::= all characters in [\u0020, \u007E] inclusive
UnicodeEscape ::= β\β βuβ {βuβ} hexDigit hexDigit hexDigit hexDigit
hexDigit ::= β0β | ... | β9β | βAβ | ... | βFβ | βaβ | ... | βfβ
charEscapeSeq ::= β\β (βbβ | βtβ | βnβ | βfβ | βrβ | β"β | β'β | β\β)
escapeSeq ::= UnicodeEscape | charEscapeSeq
op ::= opchar {opchar}
varid ::= lower idrest
boundvarid ::= varid
| β`β varid β`β
plainid ::= alphaid
| op
id ::= plainid
| β`β { charNoBackQuoteOrNewline | escapeSeq } β`β
idrest ::= {letter | digit} [β_β op]
quoteId ::= β'β alphaid
spliceId ::= β$β alphaid ;
integerLiteral ::= (decimalNumeral | hexNumeral | binaryNumeral) [βLβ | βlβ]
decimalNumeral ::= β0β | digit [{digit | β_β} digit]
hexNumeral ::= β0β (βxβ | βXβ) hexDigit [{hexDigit | β_β} hexDigit]
binaryNumeral ::= β0β (βbβ | βBβ) binaryDigit [{binaryDigit | β_β} binaryDigit]
floatingPointLiteral
::= [decimalNumeral] β.β digit [{digit | β_β} digit] [exponentPart] [floatType]
| decimalNumeral exponentPart [floatType]
| decimalNumeral floatType
exponentPart ::= (βEβ | βeβ) [β+β | β-β] digit [{digit | β_β} digit]
floatType ::= βFβ | βfβ | βDβ | βdβ
booleanLiteral ::= βtrueβ | βfalseβ
characterLiteral ::= β'β (charNoQuoteOrNewline | escapeSeq) β'β
stringLiteral ::= β"β {stringElement} β"β
| β"""β multiLineChars β"""β
stringElement ::= charNoDoubleQuoteOrNewline
| escapeSeq
multiLineChars ::= {[β"β] [β"β] charNoDoubleQuote} {β"β}
interpolatedString
::= alphaid β"β {[β\β] interpolatedStringPart | β\\β | β\"β} β"β
| alphaid β"""β {[β"β] [β"β] char \ (β"β | β\$β) | escape} {β"β} β"""β
interpolatedStringPart
::= printableChar \ (β"β | β$β | β\β) | escape
escape ::= β\$\$β
| β\$"β
| β\$β alphaid
| β\$β BlockExpr
alphaid ::= upper idrest
| varid
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}
Optional Braces
The principle of optional braces is that any keyword that can be followed by { can also be followed by an indented block, without needing an intervening :. (Allowing an optional : would be counterproductive since it would introduce several ways to do the same thing.)
The lexical analyzer inserts indent and outdent tokens that represent regions of indented code at certain points.
In the context-free productions below we use the notation <<< ts >>> to indicate a token sequence ts that is either enclosed in a pair of braces { ts } or that constitutes an indented region indent ts outdent. Analogously, the notation :<<< ts >>> indicates a token sequence ts that is either enclosed in a pair of braces { ts } or that constitutes an indented region indent ts outdent that follows a colon token.
A colon token reads as the standard colon ":" but is generated instead of it where colon is legal according to the context free syntax, but only if the previous token is an alphanumeric identifier, a backticked identifier, or one of the tokens this, super, new, ")", and "]".
colon ::= ':' -- with side conditions explained above
<<< ts >>> ::= β{β ts β}β
| indent ts outdent
:<<< ts >>> ::= [nl] β{β ts β}β
| colon indent ts outdent
Keywords
Regular keywords
abstract case catch class def do else
enum export extends false final finally for
given if implicit import lazy match new
null object override package private protected return
sealed super then throw trait true try
type val var while with yield
: = <- => <: >: #
@ =>> ?=>
Soft keywords
as consume derives end erased extension infix initially inline
opaque open throws tracked transparent update using | * + -
See the separate section on soft keywords for additional details on where a soft keyword is recognized.
Context-free Syntax
The context-free syntax of Scala is given by the following EBNF grammar:
Literals and Paths
SimpleLiteral ::= [β-β] integerLiteral
| [β-β] floatingPointLiteral
| booleanLiteral
| characterLiteral
| stringLiteral
Literal ::= SimpleLiteral
| interpolatedStringLiteral
| symbolLiteral
| βnullβ
QualId ::= id {β.β id}
ids ::= id {β,β id}
SimpleRef ::= id
| [id β.β] βthisβ
| [id β.β] βsuperβ [ClassQualifier] β.β id
ClassQualifier ::= β[β id β]β
Types
Type ::= FunType
| TypTypeParamClause β=>>β Type LambdaTypeTree(ps, t)
| FunParamClause β=>>β Type TermLambdaTypeTree(ps, t)
| MatchType
| InfixType
FunType ::= FunTypeArgs (β=>β | β?=>β) Type Function(ts, t) | FunctionWithMods(ts, t, mods, erasedParams)
| FunTypeArgs (β->β | β?->β) [CaptureSet] Type -- under pureFunctions and captureChecking
| TypTypeParamClause β=>β Type PolyFunction(ps, t)
| TypTypeParamClause β->β [CaptureSet] Type -- under pureFunctions and captureChecking
FunTypeArgs ::= InfixType
| β(β [ FunArgTypes ] β)β
| FunParamClause
FunParamClause ::= β(β TypedFunParam {β,β TypedFunParam } β)β
TypedFunParam ::= [`erased`] id β:β Type
MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
| RefinedType β^β -- under captureChecking
RefinedType ::= AnnotType {[nl] Refinement} RefinedTypeTree(t, ds)
| AnnotType {[nl] Refinement} β^β CaptureSet -- under captureChecking
AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
AnnotType1 ::= SimpleType1 {Annotation} Annotated(t, annot)
SimpleType ::= SimpleLiteral SingletonTypeTree(l)
| β?β TypeBounds
| SimpleType1 {ParArgumentExprs}
SimpleType1 ::= id Ident(name)
| Singleton β.β id Select(t, name)
| Singleton β.β βtypeβ SingletonTypeTree(p)
| β(β [Types | NamesAndTypes] β)β Tuple(ts)
| Refinement RefinedTypeTree(EmptyTree, refinement)
| TypeSplice -- deprecated syntax
| SimpleType1 TypeArgs AppliedTypeTree(t, args)
| SimpleType1 β#β id Select(t, name)
Singleton ::= SimpleRef
| SimpleLiteral
| Singleton β.β id
FunArgType ::= Type
| β=>β Type PrefixOp(=>, t)
| β->β [CaptureSet] Type -- under captureChecking
FunArgTypes ::= FunArgType { β,β FunArgType }
ParamType ::= [β=>β] ParamValueType
| β->β [CaptureSet] ParamValueType -- under captureChecking
ParamValueType ::= Type [β*β] PostfixOp(t, "*")
TypeArgs ::= β[β TypeArg {β,β TypeArg} β]β ts
Refinement ::= :<<< [RefineDcl] {semi [RefineDcl]} >>> ds
TypeBounds ::= [β>:β TypeBound] [β<:β TypeBound] TypeBoundsTree(lo, hi)
TypeAndCtxBounds ::= TypeBounds [β:β ContextBounds] ContextBounds(typeBounds, tps)
ContextBounds ::= ContextBound
| ContextBound `:` ContextBounds -- to be deprecated
| '{' ContextBound {',' ContextBound} '}'
ContextBound ::= Type ['as' id]
Types ::= Type {β,β Type}
TypeArg ::= Type
| CaptureSet -- under captureChecking
TypeBound ::= Type
| CaptureSet -- under captureChecking
NamesAndTypes ::= NameAndType {β,β NameAndType}
NameAndType ::= id ':' Type
CaptureSet ::= '{' CaptureRef {',' CaptureRef} '}' -- under captureChecking
CaptureRef ::= { SimpleRef '.' } SimpleRef ['*'] [CapFilter] ['.' 'rd'] -- under captureChecking
CapFilter ::= '.' 'only' '[' QualId ']' -- under captureChecking
Expressions
Expr ::= FunParams (β=>β | β?=>β) Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
| TypTypeParamClause β=>β Expr PolyFunction(ts, expr)
| ExprCaseClause
| Expr1
BlockResult ::= FunParams (β=>β | β?=>β) Block
| TypTypeParamClause β=>β Block
| Expr1
FunParams ::= Bindings
| id
| β_β
Expr1 ::= [βinlineβ] βifβ β(β Expr β)β {nl} Expr [[semi] βelseβ Expr] If(Parens(cond), thenp, elsep?)
| [βinlineβ] β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)
| β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)
| PrefixOperator SimpleExpr β=β Expr Assign(expr, expr)
| InfixExpr id [nl] `=' Expr Assign(expr, expr) -- only if language.postfixOps is enabled
| SimpleExpr ArgumentExprs β=β Expr Assign(expr, expr)
| PostfixExpr [Ascription]
| βinlineβ InfixExpr MatchClause
Ascription ::= β:β InfixType Typed(expr, tp)
| β:β Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*)
Catches ::= βcatchβ (Expr | ExprCaseClause)
PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op) -- only if language.postfixOperators is enabled
InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr InfixOp(expr, op, expr)
| InfixExpr id ColonArgument
| InfixExpr MatchClause
MatchClause ::= βmatchβ <<< CaseClauses >>> Match(expr, cases)
PrefixExpr ::= [PrefixOperator] SimpleExpr PrefixOp(expr, op)
PrefixOperator ::= β-β | β+β | β~β | β!β -- unless backquoted
SimpleExpr ::= SimpleRef
| Literal
| β_β
| BlockExpr
| ExprSplice
| Quoted
| quoteId -- only inside splices
| βnewβ ConstrApp {βwithβ ConstrApp} [TemplateBody] New(constr | templ)
| βnewβ TemplateBody
| β(β ExprsInParens β)β Parens(exprs)
| SimpleExpr β.β id Select(expr, id)
| SimpleExpr β.β MatchClause
| SimpleExpr TypeArgs TypeApply(expr, args)
| SimpleExpr ArgumentExprs Apply(expr, args)
| SimpleExpr ColonArgument -- under language.experimental.fewerBraces
| SimpleExpr β_β PostfixOp(expr, _) (to be dropped)
| XmlExpr -- to be dropped
ColonArgument ::= colon {LambdaStart}
indent (CaseClauses | Block) outdent
| colon LambdaStart {LambdaStart} expr ENDlambda -- ENDlambda is inserted for each production at next EOL
-- does not apply if enclosed in parens
| colon ExprCaseClause
LambdaStart ::= FunParams (β=>β | β?=>β)
| TypTypeParamClause β=>β
Quoted ::= β'β β{β Block β}β
| β'β β[β TypeBlock β]β
ExprSplice ::= spliceId -- if inside quoted block
| β$β β{β Block β}β -- unless inside quoted pattern
| β$β β{β Pattern β}β -- when inside quoted pattern
TypeSplice ::= spliceId -- if inside quoted type -- deprecated syntax
| β$β β{β Block β}β -- unless inside quoted type pattern -- deprecated syntax
| β$β β{β Pattern β}β -- when inside quoted type pattern -- deprecated syntax
ExprsInParens ::= ExprInParens {β,β ExprInParens}
| NamedExprInParens {β,β NamedExprInParens}
ExprInParens ::= PostfixExpr β:β Type -- normal Expr allows only RefinedType here
| Expr
NamedExprInParens ::= id '=' ExprInParens
ParArgumentExprs ::= β(β [ExprsInParens] β)β exprs
| β(β βusingβ ExprsInParens β)β
| β(β [ExprsInParens β,β] PostfixExpr β*β β)β exprs :+ Typed(expr, Ident(wildcardStar))
ArgumentExprs ::= ParArgumentExprs
| BlockExpr
BlockExpr ::= <<< CaseClauses | Block >>>
Block ::= {BlockStat semi} [BlockResult] Block(stats, expr?)
BlockStat ::= Import
| {Annotation {nl}} {LocalModifier} Def
| Extension
| Expr1
| EndMarker
TypeBlock ::= {TypeBlockStat semi} Type
TypeBlockStat ::= βtypeβ {nl} TypeDef
ForExpr ::= βforβ β(β Enumerators0 β)β {nl} [βdoβ | βyieldβ] Expr ForYield(enums, expr) / ForDo(enums, expr)
| βforβ β{β Enumerators0 β}β {nl} [βdoβ | βyieldβ] Expr
| βforβ Enumerators0 (βdoβ | βyieldβ) Expr
Enumerators0 ::= {nl} Enumerators [semi]
Enumerators ::= Generator {semi Enumerator | Guard}
Enumerator ::= Generator
| Guard {Guard}
| Pattern1 β=β Expr GenAlias(pat, expr)
Generator ::= [βcaseβ] Pattern1 β<-β Expr GenFrom(pat, expr)
Guard ::= βifβ PostfixExpr
CaseClauses ::= CaseClause { CaseClause } Match(EmptyTree, cases)
CaseClause ::= βcaseβ Pattern [Guard] β=>β Block CaseDef(pat, guard?, block) // block starts at =>
ExprCaseClause ::= βcaseβ Pattern [Guard] β=>β Expr
TypeCaseClauses ::= TypeCaseClause { TypeCaseClause }
TypeCaseClause ::= βcaseβ (InfixType | β_β) β=>β Type [semi]
Pattern ::= Pattern1 { β|β Pattern1 } Alternative(pats)
Pattern1 ::= PatVar β:β RefinedType Bind(name, Typed(Ident(wildcard), tpe))
| [β-β] integerLiteral β:β RefinedType Typed(pat, tpe)
| [β-β] floatingPointLiteral β:β RefinedType Typed(pat, tpe)
| Pattern2
Pattern2 ::= [id β@β] 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)
| Quoted
| XmlPattern (to be dropped)
| SimplePattern1 [TypeArgs] [ArgumentPatterns]
| βgivenβ RefinedType
SimplePattern1 ::= SimpleRef
| SimplePattern1 β.β id
PatVar ::= varid
| β_β
Patterns ::= Pattern {β,β Pattern}
| NamedPattern {β,β NamedPattern}
NamedPattern ::= id '=' Pattern
ArgumentPatterns ::= β(β [Patterns] β)β Apply(fn, pats)
| β(β [Patterns β,β] PatVar β*β [β,β Patterns]β)β
Type and Value Parameters
ClsTypeParamClause::= β[β ClsTypeParam {β,β ClsTypeParam} β]β
ClsTypeParam ::= {Annotation} [β+β | β-β] TypeDef(Modifiers, name, tparams, bounds)
id [HkTypeParamClause] TypeAndCtxBounds Bound(below, above, context)
| {Annotation} [β+β | β-β] id `^` TypeAndCtxBounds -- under captureChecking
DefTypeParamClause::= [nl] β[β DefTypeParam {β,β DefTypeParam} β]β
DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeAndCtxBounds
| {Annotation} id `^` TypeAndCtxBounds -- under captureChecking
TypTypeParamClause::= β[β TypTypeParam {β,β TypTypeParam} β]β
TypTypeParam ::= {Annotation} (id | β_β) [HkTypeParamClause] TypeAndCtxBounds
| {Annotation} id `^` TypeAndCtxBounds -- under captureChecking
HkTypeParamClause ::= β[β HkTypeParam {β,β HkTypeParam} β]β
HkTypeParam ::= {Annotation} [β+β | β-β] (id | β_β) [HkTypeParamClause]
TypeBounds
| {Annotation} [β+β | β-β] id `^` TypeBounds -- under captureChecking
ClsParamClauses ::= {ClsParamClause} [[nl] β(β [βimplicitβ] ClsParams β)β]
ClsParamClause ::= [nl] β(β ClsParams β)β
| [nl] β(β βusingβ (ClsParams | FunArgTypes) β)β
ClsParams ::= ClsParam {β,β ClsParam}
ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var
[{Modifier} (βvalβ | βvarβ)] Param
DefParamClauses ::= DefParamClause { DefParamClause } -- and two DefTypeParamClause cannot be adjacent
DefParamClause ::= DefTypeParamClause
| DefTermParamClause
| UsingParamClause
ConstrParamClauses::= ConstrParamClause {ConstrParamClause}
ConstrParamClause ::= DefTermParamClause
| UsingParamClause
DefTermParamClause::= [nl] β(β [DefTermParams] β)β
UsingParamClause ::= [nl] β(β βusingβ (DefTermParams | FunArgTypes) β)β
DefImplicitClause ::= [nl] β(β βimplicitβ DefTermParams β)β
DefTermParams ::= DefTermParam {β,β DefTermParam}
DefTermParam ::= {Annotation} TermParamMods Param ValDef(mods, id, tpe, expr) -- point of mods at id.
TermParamMods ::= [βerasedβ] [βinlineβ] | [βconsumeβ]
Param ::= id β:β ParamType [β=β Expr]
Bindings and Imports
Bindings ::= β(β [Binding {β,β Binding}] β)β
Binding ::= [`erased`] (id | β_β) [β:β Type] ValDef(_, id, tpe, EmptyTree)
Modifier ::= LocalModifier
| AccessModifier
| βoverrideβ
| βopaqueβ
LocalModifier ::= βabstractβ
| βfinalβ
| βsealedβ
| βopenβ
| βimplicitβ
| βlazyβ
| βinlineβ
| βtransparentβ
| βinfixβ
| βerasedβ
| βtrackedβ
| βupdateβ -- under captureChecking
| βconsumeβ
AccessModifier ::= (βprivateβ | βprotectedβ) [AccessQualifier]
AccessQualifier ::= β[β id β]β
Annotation ::= β@β SimpleType1 {ParArgumentExprs} Apply(tpe, args)
Import ::= βimportβ ImportExpr {β,β ImportExpr}
Export ::= βexportβ ImportExpr {β,β ImportExpr}
ImportExpr ::= SimpleRef {β.β id} β.β ImportSpec Import(expr, sels)
| SimpleRef βasβ id Import(EmptyTree, ImportSelector(ref, id))
ImportSpec ::= NamedSelector
| WildCardSelector
| β{β ImportSelectors) β}β
NamedSelector ::= id [βasβ (id | β_β)]
WildCardSelector ::= β*β | βgivenβ [InfixType]
ImportSelectors ::= NamedSelector [β,β ImportSelectors]
| WildCardSelector {β,β WildCardSelector}
EndMarker ::= βendβ EndMarkerTag -- when followed by EOL
EndMarkerTag ::= id | βifβ | βwhileβ | βforβ | βmatchβ | βtryβ
| βnewβ | βthisβ | βgivenβ | βextensionβ | βvalβ
Definitions
RefineDcl ::= βvalβ ValDcl
| βvarβ ValDcl
| βdefβ DefDcl
| βtypeβ {nl} TypeDef
ValDcl ::= ids β:β Type
DefDcl ::= DefSig β:β Type
Def ::= βvalβ PatDef
| βvarβ PatDef
| βdefβ DefDef
| βtypeβ {nl} TypeDef
| TmplDef
PatDef ::= ids [β:β Type] [β=β Expr]
| Pattern2 [β:β Type] [β=β Expr] PatDef(_, pats, tpe?, expr)
DefDef ::= DefSig [β:β Type] [β=β Expr] DefDef(_, name, paramss, tpe, expr)
| βthisβ ConstrParamClauses [DefImplicitClause] β=β ConstrExpr DefDef(_, <init>, vparamss, EmptyTree, expr | Block)
DefSig ::= id [DefParamClauses] [DefImplicitClause]
TypeDef ::= id [HkTypeParamClause] {FunParamClause} TypeAndCtxBounds TypeDefTree(_, name, tparams, bound
[β=β TypeDefRHS]
| id `^` TypeAndCtxBounds [β=β TypeDefRHS] -- under captureChecking
TypeDefRHS ::= Type
| CaptureSet -- under captureChecking
TmplDef ::= ([βcaseβ] βclassβ | βtraitβ) ClassDef
| [βcaseβ] βobjectβ ObjectDef
| βenumβ EnumDef
| βgivenβ (GivenDef | OldGivenDef)
ClassDef ::= id ClassConstr [Template] ClassDef(mods, name, tparams, templ)
ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses with DefDef(_, <init>, Nil, vparamss, EmptyTree, EmptyTree) as first stat
ConstrMods ::= {Annotation} [AccessModifier]
ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor
EnumDef ::= id ClassConstr InheritClauses EnumBody
GivenDef ::= [id ':'] GivenSig
GivenSig ::= GivenImpl
| '(' ')' '=>' GivenImpl
| GivenConditional '=>' GivenSig
GivenImpl ::= GivenType ([β=β Expr] | TemplateBody)
| ConstrApps TemplateBody
GivenConditional ::= DefTypeParamClause
| DefTermParamClause
| '(' FunArgTypes ')'
| GivenType
GivenType ::= AnnotType1 {id [nl] AnnotType1}
OldGivenDef ::= [OldGivenSig] (AnnotType [β=β Expr] | StructuralInstance) -- syntax up to Scala 3.5, to be deprecated in the future
OldGivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} β:β -- one of `id`, `DefTypeParamClause`, `UsingParamClause` must be present
StructuralInstance ::= ConstrApp {βwithβ ConstrApp} [βwithβ WithTemplateBody]
Extension ::= βextensionβ [DefTypeParamClause] {UsingParamClause}
β(β DefTermParam β)β {UsingParamClause} ExtMethods
ExtMethods ::= ExtMethod | [nl] <<< ExtMethod {semi ExtMethod} >>>
ExtMethod ::= {Annotation [nl]} {Modifier} βdefβ DefDef
| Export
Template ::= InheritClauses [TemplateBody]
InheritClauses ::= [βextendsβ ConstrApps]
[βderivesβ QualId {β,β QualId}]
[βusesβ UseRef {β,β UseRef}]
ConstrApps ::= ConstrApp ({β,β ConstrApp} | {βwithβ ConstrApp})
ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs}
ConstrExpr ::= SelfInvocation
| <<< SelfInvocation {semi BlockStat} >>>
SelfInvocation ::= βthisβ ArgumentExprs {ArgumentExprs}
UseRef ::= CaptureRef [βinitiallyβ]
WithTemplateBody ::= <<< [SelfType] TemplateStat {semi TemplateStat} >>>
TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>>
TemplateStat ::= Import
| Export
| {Annotation [nl]} {Modifier} Def
| Extension
| Expr1
| EndMarker
|
SelfType ::= id [β:β InfixType] β=>β ValDef(_, name, tpt, _)
| βthisβ β:β InfixType β=>β
EnumBody ::= :<<< [SelfType] EnumStat {semi EnumStat} >>>
EnumStat ::= TemplateStat
| {Annotation [nl]} {Modifier} EnumCase
EnumCase ::= βcaseβ (id ClassConstr [βextendsβ ConstrApps]] | ids)
TopStats ::= TopStat {semi TopStat}
TopStat ::= Import
| Export
| {Annotation [nl]} {Modifier} Def
| Extension
| Packaging
| PackageObject
| EndMarker
|
Packaging ::= βpackageβ QualId :<<< TopStats >>>
PackageObject ::= βpackageβ βobjectβ ObjectDef
CompilationUnit ::= {βpackageβ QualId semi} TopStats