parsers.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,932 行 · 第 1/5 页
SCALA
1,932 行
/** LocalModifiers ::= {LocalModifier} * LocalModifier ::= abstract | final | sealed | implicit | lazy */ def localModifiers(): Modifiers = { 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 IMPLICIT => loop(addMod(mods, Flags.IMPLICIT)) case LAZY => loop(addMod(mods, Flags.LAZY)) case _ => mods } loop(NoMods) } /** Annotations ::= {Annotation [nl]} * Annotation ::= `@' AnnotationExpr */ def annotations(skipNewLines: Boolean): List[Annotation] = { var annots = new ListBuffer[Annotation] while (inToken == AT) { inNextToken annots += annotationExpr() if (skipNewLines) newLineOpt() } annots.toList } /** TypeAttributes ::= {`[' Exprs `]'} * * Type attributes may be arbitrary expressions. */ def typeAttributes(): List[Tree] = { val exps = new ListBuffer[Tree] while(inToken == LBRACKET) { accept(LBRACKET) exps ++= exprs() accept(RBRACKET) } exps.toList } /** AnnotationExpr ::= StableId [TypeArgs] [`(' [Exprs] `)'] [[nl] `{' {NameValuePair} `}'] * NameValuePair ::= val id `=' PrefixExpr */ def annotationExpr(): Annotation = { def nameValuePair(): Tree = { var pos = inCurrentPos accept(VAL) val aname = ident() accept(EQUALS) val rhs = stripParens(prefixExpr()) atPos(pos) { ValDef(NoMods, aname, TypeTree(), rhs) } } val pos = inCurrentPos var t: Tree = convertToTypeId(stableId()) if (inToken == LBRACKET) t = atPos(inCurrentPos)(AppliedTypeTree(t, typeArgs(false, false))) val args = if (inToken == LPAREN) argumentExprs() else List() newLineOptWhenFollowedBy(LBRACE) val nameValuePairs: List[Tree] = if (inToken == LBRACE) { inNextToken val nvps = new ListBuffer[Tree] + nameValuePair() while (inToken == COMMA) { inNextToken nvps += nameValuePair() } accept(RBRACE) nvps.toList } else List() val constr = atPos(pos) { New(t, List(args)) } Annotation(constr, nameValuePairs) setPos pos }//////// PARAMETERS ////////////////////////////////////////////////////////// /** ParamClauses ::= {ParamClause} [[nl] `(' implicit Params `)'] * ParamClause ::= [nl] `(' [Params] ')' * Params ::= Param {`,' Param} * Param ::= {Annotation} Id [`:' ParamType] * ClassParamClauses ::= {ClassParamClause} [[nl] `(' implicit ClassParams `)'] * ClassParamClause ::= [nl] `(' [ClassParams] ')' * ClassParams ::= ClassParam {`,' ClassParam} * ClassParam ::= {Annotation} [{Modifier} (`val' | `var')] Id [`:' ParamType] */ def paramClauses(owner: Name, implicitViews: List[Tree], ofCaseClass: Boolean): List[List[ValDef]] = { var implicitmod = 0 var caseParam = ofCaseClass def param(): ValDef = { var pos = inCurrentPos { val annots = annotations(false) var mods = Modifiers(Flags.PARAM) if (owner.isTypeName) { mods = modifiers() | Flags.PARAMACCESSOR if (mods.hasFlag(Flags.LAZY)) syntaxError("lazy modifier not allowed here. Use call-by-name parameters instead", false) if (inToken == VAL) { inNextToken } else if (inToken == VAR) { mods = mods | Flags.MUTABLE inNextToken } else { if (mods.flags != Flags.PARAMACCESSOR) accept(VAL) if (!(caseParam)) mods = mods | Flags.PRIVATE | Flags.LOCAL } if (caseParam) mods = mods | Flags.CASEACCESSOR } val namePos = inCurrentPos val name = ident() if (name != nme.ERROR) pos = namePos var bynamemod = 0 val tpt = if (settings.Xexperimental.value && !owner.isTypeName && inToken != COLON) { TypeTree() } else { // XX-METHOD-INFER accept(COLON) if (inToken == ARROW) { if (owner.isTypeName && !mods.hasFlag(Flags.LOCAL)) syntaxError( inCurrentPos, (if (mods.hasFlag(Flags.MUTABLE)) "`var'" else "`val'") + " parameters may not be call-by-name", false) else bynamemod = Flags.BYNAMEPARAM } paramType() } atPos(pos){ ValDef((mods | implicitmod | bynamemod) withAnnotations annots, name, tpt, EmptyTree) } } } def paramClause(): List[ValDef] = { val params = new ListBuffer[ValDef] if (inToken != RPAREN) { if (inToken == IMPLICIT) { if (!implicitViews.isEmpty) syntaxError("cannot have both view bounds `<%' and implicit parameters", false) inNextToken implicitmod = Flags.IMPLICIT } params += param() while (inToken == COMMA) { inNextToken; params += param() } } params.toList } val vds = new ListBuffer[List[ValDef]] val pos = inCurrentPos newLineOptWhenFollowedBy(LPAREN) while (implicitmod == 0 && inToken == LPAREN) { inNextToken vds += paramClause() accept(RPAREN) caseParam = false newLineOptWhenFollowedBy(LPAREN) } val result = vds.toList if (owner == nme.CONSTRUCTOR && (result.isEmpty || (!result.head.isEmpty && result.head.head.mods.hasFlag(Flags.IMPLICIT)))) if (inToken == LBRACKET) syntaxError(pos, "no type parameters allowed here", false) else if(inToken == EOF) incompleteInputError("auxiliary constructor needs non-implicit parameter list") else syntaxError(pos, "auxiliary constructor needs non-implicit parameter list", false) addImplicitViews(owner, result, implicitViews) } /** ParamType ::= Type | `=>' Type | Type `*' */ def paramType(): Tree = if (inToken == ARROW) atPos(inSkipToken) { AppliedTypeTree( scalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName), List(typ())) } else { val t = typ() if (isIdent && inName == STAR) { inNextToken atPos(t.pos) { AppliedTypeTree( scalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t)) } } else t } /** TypeParamClauseOpt ::= [TypeParamClause] * TypeParamClause ::= `[' VariantTypeParam {`,' VariantTypeParam} `]'] * VariantTypeParam ::= [`+' | `-'] TypeParam * FunTypeParamClauseOpt ::= [FunTypeParamClause] * FunTypeParamClause ::= `[' TypeParam {`,' TypeParam} `]'] * TypeParam ::= Id TypeParamClauseOpt TypeBounds [<% Type] */ def typeParamClauseOpt(owner: Name, implicitViewBuf: ListBuffer[Tree]): List[TypeDef] = { def typeParam(): TypeDef = { var mods = Modifiers(Flags.PARAM) if (owner.isTypeName && isIdent) { if (inName == PLUS) { inNextToken mods = mods | Flags.COVARIANT } else if (inName == MINUS) { inNextToken mods = mods | Flags.CONTRAVARIANT } } val pos = inCurrentPos val pname = (if (inToken == USCORE) { // @M! also allow underscore inNextToken nme.WILDCARD } else ident()).toTypeName val tparams = typeParamClauseOpt(pname, null) // @M TODO null --> no higher-order view bounds for now val param = atPos(pos) { TypeDef(mods, pname, tparams, typeBounds()) } if (inToken == VIEWBOUND && (implicitViewBuf ne null)) implicitViewBuf += atPos(inSkipToken) { makeFunctionTypeTree(List(Ident(pname)), typ()) } param } val params = new ListBuffer[TypeDef] newLineOptWhenFollowedBy(LBRACKET) if (inToken == LBRACKET) { inNextToken params += typeParam() while (inToken == COMMA) { inNextToken params += typeParam() } accept(RBRACKET) } params.toList } /** TypeBounds ::= [`>:' Type] [`<:' Type] */ def typeBounds(): TypeBoundsTree = TypeBoundsTree( bound(SUPERTYPE, nme.Nothing), bound(SUBTYPE, nme.Any)) def bound(tok: Int, default: Name): Tree = if (inToken == tok) { inNextToken; typ() } else scalaDot(default.toTypeName)//////// DEFS //////////////////////////////////////////////////////////////// /** Import ::= import ImportExpr {`,' ImportExpr} */ def importClause(): List[Tree] = { accept(IMPORT) val ts = new ListBuffer[Tree] + importExpr() while (inToken == COMMA) { inNextToken; ts += importExpr() } ts.toList } /** ImportExpr ::= StableId `.' (Id | `_' | ImportSelectors) * XXX: Hook for IDE */ def importExpr(): Tree = atPos(inCurrentPos) { var t: Tree = null //var pos : ScanPosition = null.asInstanceOf[ScanPosition] var pos : Int = -1 if (inToken == THIS) { t = atPos(inCurrentPos) { This(nme.EMPTY.toTypeName) } t = atPos(accept(DOT)) { selector(t) } pos = accept(DOT) } else { val i = atPos(inCurrentPos) { Ident(ident()) } pos = accept(DOT) if (inToken == THIS) { inNextToken t = atPos(i.pos) { This(i.name.toTypeName) } t = atPos(accept(DOT)) { selector(t) } pos = accept(DOT) } else { t = i } } def loop: Tree = if (inToken == USCORE) { inNextToken Import(t, List((nme.WILDCARD, null))) } else if (inToken == LBRACE) { Import(t, importSelectors()) } else { val identPos = inCurrentPos val name = ident() // @S: use position of identifier, not dot! pos = if (name == nme.ERROR) pos else identPos if (inToken == DOT) { t = atPos(pos) { Select(t, name) } pos = accept(DOT) loop } else { Import(t, List((name, name))) } } loop } /** ImportSelectors ::= `{' {ImportSelector `,'} (ImportSelector | `_') `}' */ def importSelectors(): List[(Name, Name)] = { val names = new ListBuffer[(Name, Name)] accept(LBRACE) var isLast = importSelector(names) while (!isLast && inToken == COMMA) { inNextToken isLast = importSelector(names) } accept(RBRACE) names.toList } /** ImportSelector ::= Id [`=>' Id | `=>' `_'] */ def importSelector(names: ListBuffer[(Name, Name)]): Boolean = if (inToken == USCORE) { inNextToken; names += (nme.WILDCARD, null); true } else { val name = ident() names += ( name, if (inToken == ARROW) { inNextToken if (inToken == USCORE) { inNextToken; nme.WILDCARD } else ident() } else { name }) false } /** Def ::= val PatDef * | var VarDef * | def FunDef * | type [nl] TypeDef * | TmplDef * Dcl ::= val ValDcl * | var ValDcl * | def FunDcl * | type [nl] TypeDcl */ def defOrDcl(mods: Modifiers): List[Tree] = { if ((mods.hasFlag(Flags.LAZY)) && in.token != VAL) syntaxError("lazy not allowed here. Only vals can be lazy", false) inToken match { case VAL => patDefOrDcl(mods) case VAR => patDefOrDcl(mods | Flags.MUTABLE) case DEF => List(funDefOrDcl(mods)) case TYPE => inNextToken newLinesOpt() List(typeDefOrDcl(mods)) case _ => List(tmplDef(mods)) } } /** IDE hook: for non-local defs or dcls with modifiers and annotations */ def nonLocalDefOrDcl : List[Tree] = { val annots = annotations(true) defOrDcl(modifiers() withAnnotations annots) } /** PatDef ::= Pattern2 {`,' Pattern2} [`:' Type] `=' Expr * ValDcl ::= Id {`,' Id} `:' Type * VarDef ::= PatDef | Id {`,' Id} `:' Ty
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?