aboutsummaryrefslogblamecommitdiff
path: root/docs/docs/internals/syntax.md
blob: 804a0f57abc30881ad023ff95dd72b5ef67368e6 (plain) (tree)
1
2
3
4
5
6
7
8
   
                

                             
 

                                                                                 
 








                                                                                             
 


                                                                     
 
       
                                                                               



                                                                                                     

                                                                               


                                                                                   

                                                                                                             







                                     
                                                                                                  
                                                                                              
                                                   
 
                                                                       
                                                    
                                                                     
                                            
                                             

                    

                                                                              

                                                            

                                                                           
 
                                              
 
                                                                     
 
                                                     
                                                        
                                                         
                                   
                                   
                                                                    
                      

                                                                                                                     
                              


                                                                                           
 
                                     
 

                                                                                                     
 
                                              
                                        

   
 
                      

                                                               
        
 
                      
       

                                                     





                                             
                                 
 

                                      

                               
                                              
                         


                                                                           
   
 

         

                                                                                                       

                                
                                                                           



                                                                                                      
                                                                                                        
                                                                                                   
                               

                                                                                                            
                                         

                                                                                                                      
                                          
                                                          
                           
                                                                                                   
                                                






                                                                                                                      
   
 

               
                                                                                                                                                                           


                                                                

                               
                              








                                                                                                                               
                              

                                                                                                          
                                               


                                                                                                                                
                                       
                                                                                                   
                                 


                                                                                                                  
                                
                                                                                                      

                              
                              



                                                                                                     
                              
                                                          

                                               

                                                                                                                                             

                                       


                                                                                                               
                             
                                                                     

                                                           
 


                                                                                                                         


                                                          

                                                                                                       
                                           
 
                                                                                                                                   
                                                                        


                                                                                                                           
                               




                                                                                                                


                                                                   

                                                
                            

                                                
                                                                                                       
                                                                                          
   
 

                             
                                                                          
                                                                                                                                   
                                                                                                            
 
                                                                          

                                                                          
                                                                          

                                                                     

                                                                                         

                                 

                                                                                       
                                                  

                                                                                                                                       
                                                          

                          


                                                                                       
                                                                                                                                       
   
 

                        
                                                                
                                                                                                                     


                                     








                                                                          
                                                                                                    
 
                                                                                                     


                                                       
                                   
                            
                     
                                                                                                               
                                                            

                                                                   
                                                                                                          
                                                                                          
                                                                                                                     
   
 

                                



                                              

                          


                                                                                                                                      
                                                              

                                                                                                                      
 



                                              

                              
                                                                                                                       
                             
                                                       


                                                                                                                                             

                                                              




                                                                                                                                                          
                                     
                                                                            
                                                                                                                                  





                                                                                                                                     
                                                                   
                                                                                                                      
                                                       
                                                                                               

                                     
                                                               
                                                                      





                                                           

                                                                                                                    
 
                                                                                                       
   
---
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(_, <init>, Nil, vparamss, EmptyTree, expr | Block)
                       (‘=’ ConstrExpr | [nl] ConstrBlock)

TmplDef           ::=  ([case | `enum'] ‘class’ | [`enum'] trait) ClassDef
                    |  [case | `enum'] ‘object’ ObjectDef
                    |  `enum' EnumDef
ClassDef          ::=  id ClassConstr TemplateOpt                               ClassDef(mods, name, tparams, templ)
ClassConstr       ::=  [ClsTypeParamClause] [ConstrMods] ClsParamClauses         with DefDef(_, <init>, 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)
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)
```