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 + -
显示快捷键?