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 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 ::= ‘.’ ‘as’ ‘[’ QualId ’]’ -- under captureChecking Expressions
Expr ::= FunParams (‘=>’ | ‘?=>’) Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) | TypTypeParamClause ‘=>’ Expr PolyFunction(ts, expr) | 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 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 ‘*’ ‘)’ 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}] ConstrApps ::= ConstrApp ({‘,’ ConstrApp} | {‘with’ ConstrApp}) ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} ConstrExpr ::= SelfInvocation | <<< SelfInvocation {semi BlockStat} >>> SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} 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