Skip to content

Commit e108486

Browse files
committed
Eliminate WITHEOL token
Change parsing algorithm so that we do not need a separate WITHEOL token. The grammar remains unaffected.
1 parent eb44b34 commit e108486

File tree

3 files changed

+19
-23
lines changed

3 files changed

+19
-23
lines changed

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ object Parsers {
12831283

12841284
def possibleTemplateStart(isNew: Boolean = false): Unit =
12851285
in.observeColonEOL()
1286-
if in.token == COLONEOL || in.token == WITHEOL then
1286+
if in.token == COLONEOL || in.token == WITH then
12871287
if in.lookahead.isIdent(nme.end) then in.token = NEWLINE
12881288
else
12891289
in.nextToken()
@@ -3545,7 +3545,7 @@ object Parsers {
35453545
ValDef(name, parents.head, subExpr())
35463546
else
35473547
DefDef(name, tparams, vparamss, parents.head, subExpr())
3548-
else if in.token != WITH && in.token != WITHEOL && parentsIsType then
3548+
else if in.token != WITH && parentsIsType then
35493549
if name.isEmpty then
35503550
syntaxError(em"anonymous given cannot be abstract")
35513551
DefDef(name, tparams, vparamss, parents.head, EmptyTree)
@@ -3633,12 +3633,12 @@ object Parsers {
36333633
/** `{`with` ConstrApp} but no EOL allowed after `with`.
36343634
*/
36353635
def withConstrApps(): List[Tree] =
3636-
if in.token == WITH then
3637-
in.observeWithEOL() // converts token to WITHEOL if at end of line
3638-
if in.token == WITH && in.lookahead.token != LBRACE then
3639-
in.nextToken()
3640-
constrApp() :: withConstrApps()
3641-
else Nil
3636+
def isTemplateStart =
3637+
val la = in.lookahead
3638+
la.isAfterLineEnd || la.token == LBRACE
3639+
if in.token == WITH && !isTemplateStart then
3640+
in.nextToken()
3641+
constrApp() :: withConstrApps()
36423642
else Nil
36433643

36443644
/** Template ::= InheritClauses [TemplateBody]
@@ -3708,8 +3708,8 @@ object Parsers {
37083708

37093709
/** with Template, with EOL <indent> interpreted */
37103710
def withTemplate(constr: DefDef, parents: List[Tree]): Template =
3711-
if in.token != WITHEOL then accept(WITH)
3712-
possibleTemplateStart() // consumes a WITHEOL token
3711+
if in.token != WITH then syntaxError(em"`with` expected")
3712+
possibleTemplateStart() // consumes a WITH token
37133713
val (self, stats) = templateBody()
37143714
Template(constr, parents, Nil, self, stats)
37153715
.withSpan(Span(constr.span.orElse(parents.head.span).start, in.lastOffset))

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ object Scanners {
7474

7575
def isNestedStart = token == LBRACE || token == INDENT
7676
def isNestedEnd = token == RBRACE || token == OUTDENT
77+
78+
/** Is current token first one after a newline? */
79+
def isAfterLineEnd: Boolean = lineOffset >= 0
7780
}
7881

7982
abstract class ScannerCommon(source: SourceFile)(using Context) extends CharArrayReader with TokenData {
@@ -512,15 +515,12 @@ object Scanners {
512515
|Previous indent : $lastWidth
513516
|Latest indent : $nextWidth"""
514517

515-
private def switchAtEOL(testToken: Token, eolToken: Token): Unit =
516-
if token == testToken then
518+
def observeColonEOL(): Unit =
519+
if token == COLON then
517520
lookAhead()
518521
val atEOL = isAfterLineEnd || token == EOF
519522
reset()
520-
if atEOL then token = eolToken
521-
522-
def observeColonEOL(): Unit = switchAtEOL(COLON, COLONEOL)
523-
def observeWithEOL(): Unit = switchAtEOL(WITH, WITHEOL)
523+
if atEOL then token = COLONEOL
524524

525525
def observeIndented(): Unit =
526526
if indentSyntax && isNewLine then
@@ -610,9 +610,6 @@ object Scanners {
610610
}
611611
}
612612

613-
/** Is current token first one after a newline? */
614-
def isAfterLineEnd: Boolean = lineOffset >= 0
615-
616613
/** Is there a blank line between the current token and the last one?
617614
* A blank line consists only of characters <= ' '.
618615
* @pre afterLineEnd().

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,7 @@ object Tokens extends TokensCommon {
204204
final val QUOTE = 87; enter(QUOTE, "'")
205205

206206
final val COLONEOL = 88; enter(COLONEOL, ":", ": at eol")
207-
final val WITHEOL = 89; enter(WITHEOL, "with", "with at eol")
208-
final val SELFARROW = 90; enter(SELFARROW, "=>") // reclassified ARROW following self-type
207+
final val SELFARROW = 89; enter(SELFARROW, "=>") // reclassified ARROW following self-type
209208

210209
/** XML mode */
211210
final val XMLSTART = 99; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
@@ -277,8 +276,8 @@ object Tokens extends TokensCommon {
277276
final val closingRegionTokens = BitSet(RBRACE, RPAREN, RBRACKET, CASE) | statCtdTokens
278277

279278
final val canStartIndentTokens: BitSet =
280-
statCtdTokens | BitSet(COLONEOL, WITHEOL, EQUALS, ARROW, LARROW, WHILE, TRY, FOR, IF)
281-
// `if` is excluded because it often comes after `else` which makes for awkward indentation rules TODO: try to do without the exception
279+
statCtdTokens | BitSet(COLONEOL, WITH, EQUALS, ARROW, LARROW, WHILE, TRY, FOR, IF)
280+
// TODO: add THROW, CTXARROW
282281

283282
/** Faced with the choice between a type and a formal parameter, the following
284283
* tokens determine it's a formal parameter.

0 commit comments

Comments
 (0)