diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 508b4f3ef48f..26f967d96846 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -3,10 +3,10 @@ layout: doc-page title: "Scala 3 Syntax Summary" --- -The following descriptions of Scala tokens uses literal characters `‘c’` when +The following description 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 +_Unicode escapes_ are used to represent the [Unicode character](https://www.w3.org/International/articles/definitions-characters/) with the given hexadecimal code: ```ebnf @@ -17,6 +17,7 @@ hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | Informal descriptions are typeset as `“some comment”`. ### Lexical Syntax + The lexical syntax of Scala is given by the following grammar in EBNF form. @@ -28,9 +29,9 @@ 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)” +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’ | ‘"’ | ‘'’ | ‘\’) @@ -42,7 +43,6 @@ plainid ::= alphaid | op id ::= plainid | ‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’ - | INT // interpolation id, only for quasi-quotes idrest ::= {letter | digit} [‘_’ op] quoteId ::= ‘'’ alphaid @@ -83,29 +83,49 @@ comment ::= ‘/*’ “any sequence of characters; nested comments ar nl ::= “new line character” semi ::= ‘;’ | nl {nl} -colonEol ::= ": at end of line that can start a template body" ``` + +## Optional Braces + +The lexical analyzer also inserts `indent` and `outdent` tokens that represent regions of indented code [at certain points](../reference/other-new-features-indentation.html) + +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 `:` at the end of a line. + + +``` + <<< ts >>> ::= ‘{’ ts ‘}’ + | indent ts outdent +:<<< ts >>> ::= [nl] ‘{’ ts ‘}’ + | `:` 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 package -private protected override return super sealed then throw -trait true try type val var while with -yield -: = <- => <: :> # @ -=>> ?=> +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 ``` -derives end extension inline infix opaque open transparent using | * + - +derives end extension infix inline opaque open transparent using | * + - ``` + +See the [separate section on soft keywords](./soft-modifier.md) 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 @@ -147,10 +167,9 @@ FunArgTypes ::= InfixType | FunParamClause FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ TypedFunParam ::= id ‘:’ Type -MatchType ::= InfixType `match` ‘{’ TypeCaseClauses ‘}’ +MatchType ::= InfixType `match` <<< TypeCaseClauses >>> InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2) -RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds) -WithType ::= AnnotType {‘with’ AnnotType} (deprecated) +RefinedType ::= AnnotType {[nl] Refinement} RefinedTypeTree(t, ds) AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleLiteral SingletonTypeTree(l) @@ -209,7 +228,7 @@ PostfixExpr ::= InfixExpr [id] InfixExpr ::= PrefixExpr | InfixExpr id [nl] InfixExpr InfixOp(expr, op, expr) | InfixExpr MatchClause -MatchClause ::= ‘match’ ‘{’ CaseClauses ‘}’ Match(expr, cases) +MatchClause ::= ‘match’ <<< CaseClauses >>> Match(expr, cases) PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr PrefixOp(expr, op) SimpleExpr ::= SimpleRef | Literal @@ -218,9 +237,8 @@ SimpleExpr ::= SimpleRef | ‘$’ ‘{’ Block ‘}’ | Quoted | quoteId -- only inside splices - | ‘new’ ConstrApp {‘with’ ConstrApp} New(constr | templ) - [[colonEol] TemplateBody - | ‘new’ [colonEol] TemplateBody + | ‘new’ ConstrApp {‘with’ ConstrApp} [TemplateBody] New(constr | templ) + | ‘new’ TemplateBody | ‘(’ ExprsInParens ‘)’ Parens(exprs) | SimpleExpr ‘.’ id Select(expr, id) | SimpleExpr ‘.’ MatchClause @@ -237,7 +255,7 @@ ParArgumentExprs ::= ‘(’ [‘using’] ExprsInParens ‘)’ | ‘(’ [ExprsInParens ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ exprs :+ Typed(expr, Ident(wildcardStar)) ArgumentExprs ::= ParArgumentExprs | BlockExpr -BlockExpr ::= ‘{’ (CaseClauses | Block) ‘}’ +BlockExpr ::= <<< (CaseClauses | Block) >>> Block ::= {BlockStat semi} [BlockResult] Block(stats, expr?) BlockStat ::= Import | {Annotation {nl}} [‘implicit’ | ‘lazy’] Def @@ -356,7 +374,6 @@ EndMarkerTag ::= id | ‘if’ | ‘while’ | ‘for’ | ‘match’ | RefineDcl ::= ‘val’ ValDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl - | INT Dcl ::= RefineDcl | ‘var’ VarDcl ValDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree) @@ -372,7 +389,7 @@ Def ::= ‘val’ PatDef | ‘type’ {nl} TypeDcl | TmplDef PatDef ::= ids [‘:’ Type] ‘=’ Expr - | Pattern2 [‘:’ Type] ‘=’ Expr PatDef(_, pats, tpe?, expr) + | Pattern2 [‘:’ Type] ‘=’ Expr PatDef(_, pats, tpe?, expr) VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ DefDef ::= DefSig [‘:’ Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) @@ -386,23 +403,23 @@ ClassDef ::= id ClassConstr [Template] ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses with DefDef(_, , Nil, vparamss, EmptyTree, EmptyTree) as first stat ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor -EnumDef ::= id ClassConstr InheritClauses [colonEol] EnumBody +EnumDef ::= id ClassConstr InheritClauses EnumBody GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance) GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefParamClause`, `UsingParamClause` must be present StructuralInstance ::= ConstrApp {‘with’ ConstrApp} ‘with’ TemplateBody Extension ::= ‘extension’ [DefTypeParamClause] ‘(’ DefParam ‘)’ {UsingParamClause}] ExtMethods -ExtMethods ::= ExtMethod | [nl] ‘{’ ExtMethod {semi ExtMethod ‘}’ +ExtMethods ::= ExtMethod | [nl] <<< ExtMethod {semi ExtMethod} >>> ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef -Template ::= InheritClauses [colonEol] [TemplateBody] Template(constr, parents, self, stats) +Template ::= InheritClauses [TemplateBody] InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] ConstrApps ::= ConstrApp ({‘,’ ConstrApp} | {‘with’ ConstrApp}) -ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} Apply(tp, args) +ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} ConstrExpr ::= SelfInvocation - | ‘{’ SelfInvocation {semi BlockStat} ‘}’ + | <<< SelfInvocation {semi BlockStat} >>> SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} -TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ +TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>> TemplateStat ::= Import | Export | {Annotation [nl]} {Modifier} Def @@ -414,12 +431,12 @@ TemplateStat ::= Import SelfType ::= id [‘:’ InfixType] ‘=>’ ValDef(_, name, tpt, _) | ‘this’ ‘:’ InfixType ‘=>’ -EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’ +EnumBody ::= :<<< [SelfType] EnumStat {semi EnumStat} >>> EnumStat ::= TemplateStat | {Annotation [nl]} {Modifier} EnumCase EnumCase ::= ‘case’ (id ClassConstr [‘extends’ ConstrApps]] | ids) -TopStatSeq ::= TopStat {semi TopStat} +TopStats ::= TopStat {semi TopStat} TopStat ::= Import | Export | {Annotation [nl]} {Modifier} Def @@ -428,8 +445,8 @@ TopStat ::= Import | PackageObject | EndMarker | -Packaging ::= ‘package’ QualId [nl | colonEol] ‘{’ TopStatSeq ‘}’ Package(qid, stats) -PackageObject ::= ‘package’ ‘object’ ObjectDef object with package in mods. +Packaging ::= ‘package’ QualId :<<< TopStats >>> +PackageObject ::= ‘package’ ‘object’ ObjectDef -CompilationUnit ::= {‘package’ QualId semi} TopStatSeq Package(qid, stats) +CompilationUnit ::= {‘package’ QualId semi} TopStats ``` diff --git a/docs/docs/reference/other-new-features/indentation.md b/docs/docs/reference/other-new-features/indentation.md index 08cd79f02a71..17c8794bf62b 100644 --- a/docs/docs/reference/other-new-features/indentation.md +++ b/docs/docs/reference/other-new-features/indentation.md @@ -3,14 +3,13 @@ layout: doc-page title: Optional Braces --- -As an experimental feature, Scala 3 enforces some rules on indentation and allows -some occurrences of braces `{...}` to be optional. -It can be turned off with the compiler flag `-noindent`. +Scala 3 enforces some rules on indentation and allows some occurrences of braces `{...}` to be optional: - First, some badly indented programs are flagged with warnings. - Second, some occurrences of braces `{...}` are made optional. Generally, the rule is that adding a pair of optional braces will not change the meaning of a well-indented program. +These changescan can be turned off with the compiler flag `-noindent`. ### Indentation Rules The compiler enforces two rules for well-indented programs, flagging violations as warnings. diff --git a/docs/docs/reference/syntax.md b/docs/docs/reference/syntax.md index 764844e48042..d271de2a8369 100644 --- a/docs/docs/reference/syntax.md +++ b/docs/docs/reference/syntax.md @@ -83,14 +83,23 @@ comment ::= ‘/*’ “any sequence of characters; nested comments ar nl ::= “new line character” semi ::= ‘;’ | nl {nl} -colonEol ::= ": at end of line that can start a template body" ``` +## Optional Braces + The lexical analyzer also inserts `indent` and `outdent` tokens that represent regions of indented code [at certain points](../reference/other-new-features-indentation.html) 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`. +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 `:` at the end of a line. + +``` + <<< ts >>> ::= ‘{’ ts ‘}’ + | indent ts outdent +:<<< ts >>> ::= [nl] ‘{’ ts ‘}’ + | `:` indent ts outdent ## Keywords @@ -226,8 +235,8 @@ SimpleExpr ::= SimpleRef | ‘$’ ‘{’ Block ‘}’ | Quoted | quoteId -- only inside splices - | ‘new’ ConstrApp {‘with’ ConstrApp} [[colonEol] TemplateBody - | ‘new’ [colonEol] TemplateBody + | ‘new’ ConstrApp {‘with’ ConstrApp} [TemplateBody] + | ‘new’ TemplateBody | ‘(’ ExprsInParens ‘)’ | SimpleExpr ‘.’ id | SimpleExpr ‘.’ MatchClause @@ -242,7 +251,7 @@ ParArgumentExprs ::= ‘(’ [‘using’] ExprsInParens ‘)’ | ‘(’ [ExprsInParens ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ ArgumentExprs ::= ParArgumentExprs | BlockExpr -BlockExpr ::= ‘{’ (CaseClauses | Block) ‘}’ +BlockExpr ::= <<< (CaseClauses | Block) >>> Block ::= {BlockStat semi} [BlockResult] BlockStat ::= Import | {Annotation {nl}} [‘implicit’ | ‘lazy’] Def @@ -384,15 +393,15 @@ ClassDef ::= id ClassConstr [Template] ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] -EnumDef ::= id ClassConstr InheritClauses [colonEol] EnumBody -GivenDef ::= [GivenSig] (Type [‘=’ Expr] | StructuralInstance) +EnumDef ::= id ClassConstr InheritClauses EnumBody +GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance) GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefParamClause`, `UsingParamClause` must be present StructuralInstance ::= ConstrApp {‘with’ ConstrApp} ‘with’ TemplateBody Extension ::= ‘extension’ [DefTypeParamClause] ‘(’ DefParam ‘)’ {UsingParamClause}] ExtMethods -ExtMethods ::= ExtMethod | [nl] ‘{’ ExtMethod {semi ExtMethod ‘}’ +ExtMethods ::= ExtMethod | [nl] <<< ExtMethod {semi ExtMethod} >>> ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef -Template ::= InheritClauses [colonEol] [TemplateBody] +Template ::= InheritClauses [TemplateBody] InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] ConstrApps ::= ConstrApp ({‘,’ ConstrApp} | {‘with’ ConstrApp}) ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} @@ -400,7 +409,7 @@ ConstrExpr ::= SelfInvocation | <<< SelfInvocation {semi BlockStat} >>> SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} -TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ +TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>> TemplateStat ::= Import | Export | {Annotation [nl]} {Modifier} Def @@ -412,7 +421,7 @@ TemplateStat ::= Import SelfType ::= id [‘:’ InfixType] ‘=>’ | ‘this’ ‘:’ InfixType ‘=>’ -EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’ +EnumBody ::= :<<< [SelfType] EnumStat {semi EnumStat} >>> EnumStat ::= TemplateStat | {Annotation [nl]} {Modifier} EnumCase EnumCase ::= ‘case’ (id ClassConstr [‘extends’ ConstrApps]] | ids) @@ -426,7 +435,7 @@ TopStat ::= Import | PackageObject | EndMarker | -Packaging ::= ‘package’ QualId [nl | colonEol] ‘{’ TopStats‘}’ +Packaging ::= ‘package’ QualId :<<< TopStats >>> PackageObject ::= ‘package’ ‘object’ ObjectDef CompilationUnit ::= {‘package’ QualId semi} TopStats