Skip to content

Commit 8c8a8d2

Browse files
committed
Parser and grammar cleanups
1 parent 9c18a70 commit 8c8a8d2

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3516,20 +3516,8 @@ object Parsers {
35163516
syntaxError(i"extension clause can only define methods", stat.span)
35173517
}
35183518

3519-
def givenConstrApps(): List[Tree] =
3520-
val t = constrApp()
3521-
if in.token == WITH then
3522-
in.observeWithEOL() // converts token to WITHEOL if at end of line
3523-
if in.token == WITH && in.lookahead.token != LBRACE then
3524-
in.nextToken()
3525-
t :: givenConstrApps()
3526-
else t :: Nil
3527-
else
3528-
t :: Nil
3529-
3530-
/** GivenDef ::= [GivenSig] Type ‘=’ Expr
3531-
* | [GivenSig] ConstrApps [TemplateBody]
3532-
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’
3519+
/** GivenDef ::= [GivenSig] (Type [‘=’ Expr] | StructuralInstance)
3520+
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
35333521
*/
35343522
def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) {
35353523
var mods1 = addMod(mods, givenMod)
@@ -3550,7 +3538,7 @@ object Parsers {
35503538
if !(name.isEmpty && noParams) then
35513539
if isIdent(nme.as) then in.nextToken()
35523540
else accept(COLON)
3553-
val parents = givenConstrApps()
3541+
val parents = constrApp() :: withConstrApps()
35543542
val parentsIsType = parents.length == 1 && parents.head.isType
35553543
if in.token == EQUALS && parentsIsType then
35563544
accept(EQUALS)
@@ -3560,7 +3548,7 @@ object Parsers {
35603548
ValDef(name, parents.head, subExpr())
35613549
else
35623550
DefDef(name, tparams, vparamss, parents.head, subExpr())
3563-
else if newSyntax && in.token != WITH && in.token != WITHEOL && parentsIsType then
3551+
else if newSyntax && in.token != WITH && in.token != WITHEOL && parentsIsType then
35643552
if name.isEmpty then
35653553
syntaxError(em"anonymous given cannot be abstract")
35663554
DefDef(name, tparams, vparamss, parents.head, EmptyTree)
@@ -3571,10 +3559,7 @@ object Parsers {
35713559
val constr = makeConstructor(tparams1, vparamss1)
35723560
val templ =
35733561
if newSyntax || in.token == WITHEOL || in.token == WITH then
3574-
if in.token != WITHEOL then accept(WITH)
3575-
possibleTemplateStart()
3576-
val (self, stats) = templateBody()
3577-
Template(constr, parents, Nil, self, stats)
3562+
withTemplate(constr, parents)
35783563
else
35793564
possibleTemplateStart()
35803565
templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil)
@@ -3652,6 +3637,18 @@ object Parsers {
36523637
else Nil
36533638
t :: ts
36543639

3640+
3641+
/** `{`with` ConstrApp} but no EOL allowed after `with`.
3642+
*/
3643+
def withConstrApps(): List[Tree] =
3644+
if in.token == WITH then
3645+
in.observeWithEOL() // converts token to WITHEOL if at end of line
3646+
if in.token == WITH && in.lookahead.token != LBRACE then
3647+
in.nextToken()
3648+
constrApp() :: withConstrApps()
3649+
else Nil
3650+
else Nil
3651+
36553652
/** Template ::= InheritClauses [TemplateBody]
36563653
* InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}]
36573654
*/
@@ -3717,6 +3714,14 @@ object Parsers {
37173714
template(emptyConstructor)
37183715
r
37193716

3717+
/** with Template, with EOL <indent> interpreted */
3718+
def withTemplate(constr: DefDef, parents: List[Tree]): Template =
3719+
if in.token != WITHEOL then accept(WITH)
3720+
possibleTemplateStart() // consumes a WITHEOL token
3721+
val (self, stats) = templateBody()
3722+
Template(constr, parents, Nil, self, stats)
3723+
.withSpan(Span(constr.span.orElse(parents.head.span).start, in.lastOffset))
3724+
37203725
/* -------- STATSEQS ------------------------------------------- */
37213726

37223727
/** Create a tree representing a packaging */

docs/docs/internals/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Expr1 ::= [‘inline’] ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[
209209
| ‘inline’ InfixExpr MatchClause
210210
Ascription ::= ‘:’ InfixType Typed(expr, tp)
211211
| ‘:’ Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*)
212-
StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ TemplateBody] New templ
212+
StructuralInstance ::= ConstrApp {‘with’ ConstrApp} ‘with’ TemplateBody New templ
213213
Catches ::= ‘catch’ (Expr | ExprCaseClause)
214214
PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op)
215215
InfixExpr ::= PrefixExpr

0 commit comments

Comments
 (0)