@@ -177,6 +177,7 @@ object Parsers {
177
177
def parse (): Tree = {
178
178
val t = compilationUnit()
179
179
accept(EOF )
180
+ println(t)
180
181
t
181
182
}
182
183
@@ -553,19 +554,27 @@ object Parsers {
553
554
def inDefScopeBraces [T ](body : => T , rewriteWithColon : Boolean = false ): T =
554
555
inBracesOrIndented(body, rewriteWithColon)
555
556
556
- /** part { `separator` part }
557
- */
558
- def tokenSeparated [T ](separator : Int , part : () => T ): List [T ] = {
557
+ /** part { `,` part }
558
+ * @param expectedEnd If set to something other than [[EMPTY ]],
559
+ * assume this comma separated list must be followed by this token.
560
+ * If the parser consumes a `part` that is not followed by a comma or this expected
561
+ * token, issue a syntax error and try to recover at the next safe point.
562
+ */
563
+ def commaSeparated [T ](part : () => T , expectedEnd : Token = EMPTY ): List [T ] = {
559
564
val ts = new ListBuffer [T ] += part()
560
- while (in.token == separator ) {
565
+ while (in.token == COMMA ) {
561
566
in.nextToken()
562
567
ts += part()
563
568
}
569
+ if (expectedEnd != EMPTY && in.token != expectedEnd) {
570
+ syntaxErrorOrIncomplete(ExpectedTokenButFound (expectedEnd, in.token))
571
+ if (in.token == COMMA ) {
572
+ ts ++= commaSeparated(part, expectedEnd)
573
+ }
574
+ }
564
575
ts.toList
565
576
}
566
577
567
- def commaSeparated [T ](part : () => T ): List [T ] = tokenSeparated(COMMA , part)
568
-
569
578
def inSepRegion [T ](f : Region => Region )(op : => T ): T =
570
579
val cur = in.currentRegion
571
580
in.currentRegion = f(cur)
@@ -1509,7 +1518,7 @@ object Parsers {
1509
1518
/** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
1510
1519
*/
1511
1520
def funParamClause (): List [ValDef ] =
1512
- inParens(commaSeparated(() => typedFunParam(in.offset, ident())))
1521
+ inParens(commaSeparated(() => typedFunParam(in.offset, ident()), RPAREN ))
1513
1522
1514
1523
def funParamClauses (): List [List [ValDef ]] =
1515
1524
if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil
@@ -1622,7 +1631,7 @@ object Parsers {
1622
1631
else
1623
1632
def singletonArgs (t : Tree ): Tree =
1624
1633
if in.token == LPAREN && in.featureEnabled(Feature .dependent)
1625
- then singletonArgs(AppliedTypeTree (t, inParens(commaSeparated(singleton))))
1634
+ then singletonArgs(AppliedTypeTree (t, inParens(commaSeparated(singleton, RPAREN ))))
1626
1635
else t
1627
1636
singletonArgs(simpleType1())
1628
1637
@@ -1638,7 +1647,7 @@ object Parsers {
1638
1647
def simpleType1 () = simpleTypeRest {
1639
1648
if in.token == LPAREN then
1640
1649
atSpan(in.offset) {
1641
- makeTupleOrParens(inParens(argTypes(namedOK = false , wildOK = true )))
1650
+ makeTupleOrParens(inParens(argTypes(namedOK = false , wildOK = true , RPAREN )))
1642
1651
}
1643
1652
else if in.token == LBRACE then
1644
1653
atSpan(in.offset) { RefinedTypeTree (EmptyTree , refinement(indentOK = false )) }
@@ -1722,7 +1731,7 @@ object Parsers {
1722
1731
* | NamedTypeArg {`,' NamedTypeArg}
1723
1732
* NamedTypeArg ::= id `=' Type
1724
1733
*/
1725
- def argTypes (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = {
1734
+ def argTypes (namedOK : Boolean , wildOK : Boolean , expectedEnd : Token ): List [Tree ] = {
1726
1735
1727
1736
def argType () = {
1728
1737
val t = typ()
@@ -1739,7 +1748,7 @@ object Parsers {
1739
1748
val rest =
1740
1749
if (in.token == COMMA ) {
1741
1750
in.nextToken()
1742
- commaSeparated(arg)
1751
+ commaSeparated(arg, expectedEnd )
1743
1752
}
1744
1753
else Nil
1745
1754
first :: rest
@@ -1752,7 +1761,7 @@ object Parsers {
1752
1761
case firstArg =>
1753
1762
otherArgs(firstArg, () => argType())
1754
1763
}
1755
- else commaSeparated(() => argType())
1764
+ else commaSeparated(() => argType(), expectedEnd )
1756
1765
}
1757
1766
1758
1767
/** FunArgType ::= Type | `=>' Type
@@ -1781,7 +1790,7 @@ object Parsers {
1781
1790
/** TypeArgs ::= `[' Type {`,' Type} `]'
1782
1791
* NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]'
1783
1792
*/
1784
- def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = inBrackets(argTypes(namedOK, wildOK))
1793
+ def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = inBrackets(argTypes(namedOK, wildOK, RBRACKET ))
1785
1794
1786
1795
/** Refinement ::= `{' RefineStatSeq `}'
1787
1796
*/
@@ -2145,7 +2154,7 @@ object Parsers {
2145
2154
var mods1 = mods
2146
2155
if isErased then mods1 = addModifier(mods1)
2147
2156
try
2148
- commaSeparated(() => binding(mods1))
2157
+ commaSeparated(() => binding(mods1), RPAREN )
2149
2158
finally
2150
2159
accept(RPAREN )
2151
2160
else {
@@ -2376,7 +2385,7 @@ object Parsers {
2376
2385
/** ExprsInParens ::= ExprInParens {`,' ExprInParens}
2377
2386
*/
2378
2387
def exprsInParensOpt (): List [Tree ] =
2379
- if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
2388
+ if (in.token == RPAREN ) Nil else commaSeparated(exprInParens, RPAREN )
2380
2389
2381
2390
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2382
2391
* | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
@@ -2386,9 +2395,9 @@ object Parsers {
2386
2395
(Nil , false )
2387
2396
else if isIdent(nme.using) then
2388
2397
in.nextToken()
2389
- (commaSeparated(argumentExpr), true )
2398
+ (commaSeparated(argumentExpr, RPAREN ), true )
2390
2399
else
2391
- (commaSeparated(argumentExpr), false )
2400
+ (commaSeparated(argumentExpr, RPAREN ), false )
2392
2401
}
2393
2402
2394
2403
/** ArgumentExprs ::= ParArgumentExprs
@@ -2532,7 +2541,7 @@ object Parsers {
2532
2541
if (leading == LBRACE || in.token == CASE )
2533
2542
enumerators()
2534
2543
else {
2535
- val pats = patternsOpt()
2544
+ val pats = patternsOpt(EMPTY )
2536
2545
val pat =
2537
2546
if (in.token == RPAREN || pats.length > 1 ) {
2538
2547
wrappedEnums = false
@@ -2724,7 +2733,7 @@ object Parsers {
2724
2733
case USCORE =>
2725
2734
wildcardIdent()
2726
2735
case LPAREN =>
2727
- atSpan(in.offset) { makeTupleOrParens(inParens(patternsOpt())) }
2736
+ atSpan(in.offset) { makeTupleOrParens(inParens(patternsOpt(RPAREN ))) }
2728
2737
case QUOTE =>
2729
2738
simpleExpr(Location .InPattern )
2730
2739
case XMLSTART =>
@@ -2759,17 +2768,17 @@ object Parsers {
2759
2768
2760
2769
/** Patterns ::= Pattern [`,' Pattern]
2761
2770
*/
2762
- def patterns (location : Location = Location .InPattern ): List [Tree ] =
2763
- commaSeparated(() => pattern(location))
2771
+ def patterns (expectedEnd : Token = EMPTY , location : Location = Location .InPattern ): List [Tree ] =
2772
+ commaSeparated(() => pattern(location), expectedEnd )
2764
2773
2765
- def patternsOpt (location : Location = Location .InPattern ): List [Tree ] =
2766
- if (in.token == RPAREN ) Nil else patterns(location)
2774
+ def patternsOpt (expectedEnd : Token , location : Location = Location .InPattern ): List [Tree ] =
2775
+ if (in.token == RPAREN ) Nil else patterns(expectedEnd, location)
2767
2776
2768
2777
/** ArgumentPatterns ::= ‘(’ [Patterns] ‘)’
2769
2778
* | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’
2770
2779
*/
2771
2780
def argumentPatterns (): List [Tree ] =
2772
- inParens(patternsOpt(Location .InPatternArgs ))
2781
+ inParens(patternsOpt(RPAREN , Location .InPatternArgs ))
2773
2782
2774
2783
/* -------- MODIFIERS and ANNOTATIONS ------------------------------------------- */
2775
2784
@@ -2950,7 +2959,7 @@ object Parsers {
2950
2959
TypeDef (name, lambdaAbstract(hkparams, bounds)).withMods(mods)
2951
2960
}
2952
2961
}
2953
- commaSeparated(() => typeParam())
2962
+ commaSeparated(() => typeParam(), RBRACKET )
2954
2963
}
2955
2964
2956
2965
def typeParamClauseOpt (ownerKind : ParamOwner .Value ): List [TypeDef ] =
@@ -2959,7 +2968,7 @@ object Parsers {
2959
2968
/** ContextTypes ::= FunArgType {‘,’ FunArgType}
2960
2969
*/
2961
2970
def contextTypes (ofClass : Boolean , nparams : Int , impliedMods : Modifiers ): List [ValDef ] =
2962
- val tps = commaSeparated(funArgType)
2971
+ val tps = commaSeparated(funArgType, RPAREN )
2963
2972
var counter = nparams
2964
2973
def nextIdx = { counter += 1 ; counter }
2965
2974
val paramFlags = if ofClass then Private | Local | ParamAccessor else Param
@@ -3063,7 +3072,7 @@ object Parsers {
3063
3072
! impliedMods.is(Given )
3064
3073
|| startParamTokens.contains(in.token)
3065
3074
|| isIdent && (in.name == nme.inline || in.lookahead.isColon())
3066
- if isParams then commaSeparated(() => param())
3075
+ if isParams then commaSeparated(() => param(), RPAREN )
3067
3076
else contextTypes(ofClass, nparams, impliedMods)
3068
3077
checkVarArgsRules(clause)
3069
3078
clause
@@ -3755,7 +3764,7 @@ object Parsers {
3755
3764
val derived =
3756
3765
if (isIdent(nme.derives )) {
3757
3766
in.nextToken()
3758
- tokenSeparated( COMMA , () => convertToTypeId(qualId()))
3767
+ commaSeparated( () => convertToTypeId(qualId()))
3759
3768
}
3760
3769
else Nil
3761
3770
possibleTemplateStart()
0 commit comments