parsers.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,932 行 · 第 1/5 页
SCALA
1,932 行
placeholderParams = param :: placeholderParams t = atPos(pos) { Ident(pname) } case LPAREN => val pos = inSkipToken val ts = if (inToken == RPAREN) List() else exprs() accept(RPAREN) t = Parens(ts) setPos (pos) case LBRACE => t = blockExpr() canApply = false case NEW => t = atPos(inSkipToken) { val (parents, argss, self, stats) = template(false) makeNew(parents, self, stats, argss) } canApply = false case _ => syntaxErrorOrIncomplete("illegal start of simple expression", true) t = errorTermTree } simpleExprRest(t, canApply) } def simpleExprRest(t: Tree, canApply: Boolean): Tree = { if (canApply) newLineOptWhenFollowedBy(LBRACE) inToken match { case DOT => simpleExprRest(atPos(inSkipToken) { selector(stripParens(t)) }, true) case LBRACKET => val t1 = stripParens(t) t1 match { case Ident(_) | Select(_, _) => val pos = if (t1.pos == NoPosition) i2p(inCurrentPos) else t1.pos simpleExprRest(atPos(pos) { TypeApply(t1, typeArgs(false, true)) }, true) case _ => t1 } case LPAREN | LBRACE if (canApply) => // again, position should be on idetifier, not ( var pos = if (t.pos == NoPosition) i2p(inCurrentPos) else t.pos simpleExprRest(atPos(pos) { Apply(stripParens(t), argumentExprs()) }, true) case USCORE => atPos(inSkipToken) { Typed(stripParens(t), Function(List(), EmptyTree)) } case _ => t } } /** ArgumentExprs ::= `(' [Exprs [`,']] `)' * | [nl] BlockExpr */ def argumentExprs(): List[Tree] = { if (inToken == LBRACE) { List(blockExpr()) } else { val ts = surround(LPAREN,RPAREN)(if (inToken == RPAREN) List() else exprs(), List()) ts } } /** BlockExpr ::= `{' (CaseClauses | Block) `}' */ def blockExpr(): Tree = { assert(inToken == LBRACE) val res = atPos(accept(LBRACE)) { // no need to surround if (inToken == CASE) Match(EmptyTree, caseClauses()) else block() } accept(RBRACE) res } /** Block ::= BlockStatSeq */ def block(): Tree = makeBlock(blockStatSeq(new ListBuffer[Tree])) /** CaseClauses ::= CaseClause {CaseClause} */ def caseClauses(): List[CaseDef] = { val ts = new ListBuffer[CaseDef] do { ts += caseClause() } while (inToken == CASE) ts.toList } /** CaseClause ::= case Pattern [Guard] `=>' Block */ def caseClause(): CaseDef = atPos(accept(CASE)) { val pat = pattern() val gd = guard() makeCaseDef(pat, gd, caseBlock()) } // IDE HOOK (so we can memoize case blocks) def caseBlock(): Tree = atPos(accept(ARROW))(block()) /** Guard ::= if PostfixExpr */ def guard(): Tree = if (inToken == IF) { inNextToken; stripParens(postfixExpr()) } else EmptyTree /** Enumerators ::= Generator {semi Enumerator} * Enumerator ::= Generator * | Guard * | val Pattern1 `=' Expr */ def enumerators(): List[Enumerator] = { val newStyle = inToken != VAL // todo: deprecate old style //if (!newStyle) // deprecationWarning(inCurrentPos, "for (val x <- ... ) has been deprecated; use for (x <- ... ) instead") val enums = new ListBuffer[Enumerator] generator(enums, false) while (isStatSep) { inNextToken if (newStyle) { if (inToken == IF) enums += Filter(guard()) else generator(enums, true) } else { if (inToken == VAL) generator(enums, true) else enums += Filter(expr()) } } enums.toList } /** Generator ::= val Pattern1 `<-' Expr [Guard] */ def generator(enums: ListBuffer[Enumerator], eqOK: Boolean) { if (inToken == VAL) inNextToken val pos = inCurrentPos; val pat = pattern1(false) val tok = inToken if (tok == EQUALS && eqOK) inNextToken else accept(LARROW) enums += makeGenerator(pos, pat, tok == EQUALS, expr) if (inToken == IF) enums += Filter(guard()) } //def p2i(pos : ScanPosition) : Int;//////// PATTERNS //////////////////////////////////////////////////////////// /** Patterns ::= Pattern { `,' Pattern } * SeqPatterns ::= SeqPattern { `,' SeqPattern } * * (also eats trailing comma if it finds one) */ def patterns(seqOK: Boolean): List[Tree] = { val ts = new ListBuffer[Tree] + pattern(seqOK) while (inToken == COMMA) { val pos = inCurrentPos inNextToken if (inToken == RPAREN) { deprecationWarning(pos, "Trailing commas have been deprecated") return ts.toList } else { ts += pattern(seqOK) } } ts.toList } /** Pattern ::= Pattern1 { `|' Pattern1 } * SeqPattern ::= SeqPattern1 { `|' SeqPattern1 } */ def pattern(seqOK: Boolean): Tree = { val pos = inCurrentPos val t = pattern1(seqOK) if (isIdent && inName == BAR) { val ts = new ListBuffer[Tree] + t while (isIdent && inName == BAR) { inNextToken; ts += pattern1(seqOK) } atPos(pos) { makeAlternative(ts.toList) } } else t } def pattern(): Tree = pattern(false) /** Pattern1 ::= varid `:' TypePat * | `_' `:' TypePat * | Pattern2 * SeqPattern1 ::= varid `:' TypePat * | `_' `:' TypePat * | [SeqPattern2] */ def pattern1(seqOK: Boolean): Tree = { //if (false && /*disabled, no regexp matching*/ seqOK && !isExprIntro) { //atPos(inCurrentPos) { Sequence(List()) } //} else { val p = pattern2(seqOK) p match { case Ident(name) if (treeInfo.isVarPattern(p) && inToken == COLON) => atPos(inSkipToken) { Typed(p, compoundType(true)) } case _ => p } //} } /* Pattern2 ::= varid [ @ Pattern3 ] * | Pattern3 * SeqPattern2 ::= varid [ @ SeqPattern3 ] * | SeqPattern3 */ def pattern2(seqOK: Boolean): Tree = { val p = pattern3(seqOK) if (inToken == AT) { p match { case Ident(name) => if (name == nme.WILDCARD) { inNextToken; pattern3(seqOK) } else if (treeInfo.isVarPattern(p)) { inNextToken atPos(p.pos) { Bind(name, pattern3(seqOK)) } } else { p } case _ => p } } else p } /* Pattern3 ::= SimplePattern * | SimplePattern {Id [nl] SimplePattern} * SeqPattern3 ::= SeqSimplePattern [ '*' | '?' | '+' ] * | SeqSimplePattern {Id [nl] SeqSimplePattern} */ def pattern3(seqOK: Boolean): Tree = { val base = opstack var top = simplePattern(seqOK) if (seqOK && isIdent) { if (inName == STAR) return atPos(inSkipToken)(Star(top)) else if (inName == PLUS) return atPos(inSkipToken)(makePlus(top)) else if (inName == OPT) return atPos(inSkipToken)(makeOpt(top)) } while (isIdent && inName != BAR) { top = reduceStack( false, base, top, precedence(inName), treeInfo.isLeftAssoc(inName)) val op = inName opstack = OpInfo(top, op, inCurrentPos) :: opstack ident() top = simplePattern(seqOK) } stripParens(reduceStack(false, base, top, 0, true)) } def xmlLiteralPattern() : Tree /** SimplePattern ::= varid * | `_' * | literal * | XmlPattern * | StableId [TypeArgs] [`(' [SeqPatterns [`,']] `)'] * | `(' [Patterns [`,']] `)' * SimpleSeqPattern ::= varid * | `_' * | literal * | XmlPattern * | `<' xLiteralPattern * | StableId [TypeArgs] [`(' [SeqPatterns [`,']] `)'] * | `(' [SeqPatterns [`,']] `)' * * XXX: Hook for IDE */ def simplePattern(seqOK: Boolean): Tree = inToken match { case IDENTIFIER | BACKQUOTED_IDENT | THIS => var t = stableId() inToken match { case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT => t match { case Ident(name) if name == nme.MINUS => return literal(true, true) case _ => } case _ => }/* not yet if (inToken == LBRACKET) atPos(inCurrentPos) { val ts = typeArgs(true, false) accept(LPAREN) val ps = if (inToken == RPAREN) List() else patterns(true, false) accept(RPAREN) Apply(TypeApply(convertToTypeId(t), ts), ps) } else */ if (inToken == LPAREN) { atPos(t.pos) { Apply(t, argumentPatterns()) } } else t case USCORE => atPos(inSkipToken) { Ident(nme.WILDCARD) } case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => literal(true, false) case LPAREN => val pos = inSkipToken val ps = if (inToken == RPAREN) List() else patterns(false) accept(RPAREN) Parens(ps) setPos (pos) case XMLSTART => xmlLiteralPattern() case _ => syntaxErrorOrIncomplete("illegal start of simple pattern", true) errorPatternTree } def argumentPatterns(): List[Tree] = { accept(LPAREN) val ps = if (inToken == RPAREN) List() else patterns(true) accept(RPAREN) ps }////////// MODIFIERS and ANNOTATIONS ///////////////////////////////////////////////// private def normalize(mods: Modifiers): Modifiers = if ((mods hasFlag Flags.PRIVATE) && mods.privateWithin != nme.EMPTY.toTypeName) mods &~ Flags.PRIVATE else if ((mods hasFlag Flags.ABSTRACT) && (mods hasFlag Flags.OVERRIDE)) mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE else mods private def addMod(mods: Modifiers, mod: Long): Modifiers = { if (mods hasFlag mod) syntaxError(inCurrentPos, "repeated modifier", false) inNextToken mods | mod } /** AccessQualifier ::= "[" (Id | this) "]" */ def accessQualifierOpt(mods: Modifiers) = { var result = mods if (inToken == LBRACKET) { inNextToken if (mods.privateWithin != nme.EMPTY.toTypeName) syntaxError("duplicate private/protected qualifier", false) result = if (inToken == THIS) { inNextToken; mods | Flags.LOCAL } else Modifiers(mods.flags, ident().toTypeName) accept(RBRACKET) } result } /** AccessModifier ::= (private | protected) [AccessQualifier] */ def accessModifierOpt(): Modifiers = normalize { inToken match { case PRIVATE => inNextToken; accessQualifierOpt(Modifiers(Flags.PRIVATE)) case PROTECTED => inNextToken; accessQualifierOpt(Modifiers(Flags.PROTECTED)) case _ => NoMods } } /** Modifiers ::= {Modifier} * Modifier ::= LocalModifier * | AccessModifier * | override */ def modifiers(): Modifiers = normalize { def loop(mods: Modifiers): Modifiers = inToken match { case ABSTRACT => loop(addMod(mods, Flags.ABSTRACT)) case FINAL => loop(addMod(mods, Flags.FINAL)) case SEALED => loop(addMod(mods, Flags.SEALED)) case PRIVATE => loop(accessQualifierOpt(addMod(mods, Flags.PRIVATE))) case PROTECTED => loop(accessQualifierOpt(addMod(mods, Flags.PROTECTED))) case OVERRIDE => loop(addMod(mods, Flags.OVERRIDE)) case IMPLICIT => loop(addMod(mods, Flags.IMPLICIT)) case LAZY => loop(addMod(mods, Flags.LAZY)) case _ => mods } loop(NoMods) }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?