parsers.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,932 行 · 第 1/5 页

SCALA
1,932
字号
    }    /** Convert tree to formal parameter    */    def convertToParam(tree: Tree): ValDef =      atPos(tree.pos) {        tree match {          case Ident(name) =>            ValDef(Modifiers(Flags.PARAM), name, TypeTree(), EmptyTree)          case Typed(tree @ Ident(name), tpe) if (tpe.isType) => // get the ident!            ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree).setPos(tree.pos)          case _ =>            syntaxError(tree.pos, "not a legal formal parameter", false)            ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree, EmptyTree)        }      }    /** Convert (qual)ident to type identifier     */    def convertToTypeId(tree: Tree): Tree = tree match {      case Ident(name) =>        Ident(name.toTypeName).setPos(tree.pos)      case Select(qual, name) =>        Select(qual, name.toTypeName).setPos(tree.pos)      case _ =>        syntaxError(tree.pos, "identifier expected", false)        errorTypeTree    }    /** make closure from tree staring with a `.' */    def makeDotClosure(tree: Tree): Tree = {      val pname = freshName(tree.pos, "x$")      def insertParam(tree: Tree): Tree = atPos(tree.pos) {        tree match {          case Ident(name) =>            Select(Ident(pname), name)          case Select(qual, name) =>            Select(insertParam(qual), name)          case Apply(fn, args) =>            Apply(insertParam(fn), args)          case TypeApply(fn, args) =>            TypeApply(insertParam(fn), args)          case _ =>            syntaxError(tree.pos, "cannot convert to closure", false)            errorTermTree        }      }      Function(List(makeSyntheticParam(pname)), insertParam(tree))    }/////// OPERAND/OPERATOR STACK /////////////////////////////////////////////////    var opstack: List[OpInfo] = Nil    def precedence(operator: Name): Int =      if (operator eq nme.ERROR) -1      else {        val firstCh = operator(0)        if (((firstCh >= 'A') && (firstCh <= 'Z')) ||            ((firstCh >= 'a') && (firstCh <= 'z')))          1        else          firstCh match {            case '|'             => 2            case '^'             => 3            case '&'             => 4            case '=' | '!'       => 5            case '<' | '>'       => 6            case ':'             => 7            case '+' | '-'       => 8            case '*' | '/' | '%' => 9            case _               => 10          }      }    def checkSize(kind: String, size: Int, max: Int) {      if (size > max) syntaxError("too many "+kind+", maximum = "+max, false)    }    def checkAssoc(pos: Int, op: Name, leftAssoc: Boolean) =       if (treeInfo.isLeftAssoc(op) != leftAssoc)        syntaxError(          pos, "left- and right-associative operators with same precedence may not be mixed", false)    def reduceStack(isExpr: Boolean, base: List[OpInfo], top0: Tree, prec: Int, leftAssoc: Boolean): Tree = {      var top = top0      if (opstack != base && precedence(opstack.head.operator) == prec)        checkAssoc(opstack.head.pos, opstack.head.operator, leftAssoc)      while (opstack != base &&              (prec < precedence(opstack.head.operator) ||              (leftAssoc && prec == precedence(opstack.head.operator)))) {        top = atPos(opstack.head.pos) {          makeBinop(isExpr, opstack.head.operand, opstack.head.operator, top)        }        opstack = opstack.tail      }      top    }/////// IDENTIFIERS AND LITERALS ////////////////////////////////////////////////////////////    def ident(): Name =      if (inToken == IDENTIFIER || inToken == BACKQUOTED_IDENT) {        val name = inName.encode        inNextToken        name      } else {        accept(IDENTIFIER)        nme.ERROR      }    def selector(t: Tree) =       atPos(inCurrentPos)(Select(t, ident()))        /** Path       ::= StableId     *              |  [Ident `.'] this     *  AnnotType ::= Path [`.' type]     */    def path(thisOK: Boolean, typeOK: Boolean): Tree = {      var t: Tree = null      if (inToken == THIS) {        t = atPos(inSkipToken) { This(nme.EMPTY.toTypeName) }        if (!thisOK || inToken == DOT) {          t =  selectors(t, typeOK, accept(DOT))        }      } else if (inToken == SUPER) {	      // val pos = inCurrentPos	val pos = inSkipToken        val (mix,usePos) = mixinQualifierOpt(pos)              t = atPos(usePos) {          Super(nme.EMPTY.toTypeName, mix)        }        t = atPos(accept(DOT)) { selector(t) }        if (inToken == DOT)          t = selectors(t, typeOK, inSkipToken)      } else {        val i = atPos(inCurrentPos) {           if (inToken == BACKQUOTED_IDENT) new BackQuotedIdent(ident())          else Ident(ident())         }        t = i        if (inToken == DOT) {          val pos = inSkipToken          if (inToken == THIS) {            inNextToken            t = atPos(i.pos) { This(i.name.toTypeName) }            if (!thisOK || inToken == DOT)              t = selectors(t, typeOK, accept(DOT))          } else if (inToken == SUPER) {            inNextToken            val (mix,pos) = mixinQualifierOpt(i.pos)            t = atPos(pos) { Super(i.name.toTypeName, mix) }            t = atPos(accept(DOT)) {selector(t)}            if (inToken == DOT)              t = selectors(t, typeOK, inSkipToken)          } else {            t = selectors(t, typeOK, pos)          }        }      }      t    }    def selectors(t: Tree, typeOK: Boolean, pos : Int): Tree =      if (typeOK && inToken == TYPE) {        inNextToken        atPos(pos) { SingletonTypeTree(t) }      } else {        val t1 = atPos(pos) { selector(t); }        if (inToken == DOT) { selectors(t1, typeOK, inSkipToken) }        else t1      }    /** MixinQualifier ::= `[' Id `]'    */    def mixinQualifierOpt(pos : Position): (Name,Position) =      if (inToken == LBRACKET) {        inNextToken        val pos = inCurrentPos        val name = ident().toTypeName        accept(RBRACKET)        (name,pos)      } else {        (nme.EMPTY.toTypeName,pos)      }    /** StableId ::= Id     *            |  Path `.' Id     *            |  [id '.'] super [`[' id `]']`.' id     */    def stableId(): Tree =      path(false, false)    /** QualId ::= Id {`.' Id}    */    def qualId(): Tree = {      val id = atPos(inCurrentPos) { Ident(ident()) }      if (inToken == DOT) { selectors(id, false, inSkipToken) }      else id    }    /** SimpleExpr    ::= literal    *                  | symbol    *                  | null    */          def literal(isPattern: Boolean, isNegated: Boolean): Tree = {      def litToTree() = atPos(inCurrentPos) {        Literal(          inToken match {            case CHARLIT => Constant(charVal)            case INTLIT =>  Constant(intVal(isNegated))            case LONGLIT => Constant(longVal(isNegated))            case FLOATLIT =>Constant(floatVal(isNegated))            case DOUBLELIT => Constant(doubleVal(isNegated))            case STRINGLIT | SYMBOLLIT => Constant(stringVal)            case TRUE => Constant(true)            case FALSE => Constant(false)            case NULL => Constant(null)            case _ =>              syntaxErrorOrIncomplete("illegal literal", true)              null          })      }      val isSymLit = inToken == SYMBOLLIT      val t = litToTree()      val pos = inSkipToken      if (isSymLit) {        atPos(pos) {          var symid = scalaDot(nme.Symbol)          Apply(symid, List(t))        }      } else {        t      }    }    def newLineOpt() {      if (inToken == NEWLINE) inNextToken    }    def newLinesOpt() {      if (inToken == NEWLINE || inToken == NEWLINES)        inNextToken    }    def newLineOptWhenFollowedBy(token: Int) {      // note: next is defined here because current == NEWLINE      if (inToken == NEWLINE && inNextTokenCode == token) newLineOpt()    }    def newLineOptWhenFollowing(p: Int => Boolean) {      // note: next is defined here because current == NEWLINE      if (inToken == NEWLINE && p(inNextTokenCode)) newLineOpt()    }//////// TYPES ///////////////////////////////////////////////////////////////    /** TypedOpt ::= [`:' Type]    */    def typedOpt(): Tree =      if (inToken == COLON) { inNextToken; typ() }       else TypeTree()    /** RequiresTypedOpt ::= [requires AnnotType]    */    def requiresTypeOpt(): Tree =      if (inToken == REQUIRES) {         deprecationWarning(in.currentPos, "`requires T' has been deprecated; use `{ self: T => ...'  instead")        inNextToken; annotType(false)      } else TypeTree()    /** Types ::= Type {`,' Type}      *  (also eats trailing comma if it finds one)     */    def types(isPattern: Boolean, isTypeApply: Boolean, isFuncArg: Boolean): List[Tree] = {      val ts = new ListBuffer[Tree] + argType(isPattern, isTypeApply, isFuncArg)      while (inToken == COMMA) {        val pos = inCurrentPos        inNextToken        if (inToken == RPAREN) {          deprecationWarning(pos, "Trailing commas have been deprecated")          return ts.toList        } else {          ts += argType(isPattern, isTypeApply, isFuncArg)        }      }      ts.toList    }    /** modes for infix types */    object InfixMode extends Enumeration {      val FirstOp, LeftOp, RightOp = Value    }    /** Type ::= InfixType `=>' Type     *         | `(' [`=>' Type] `)' `=>' Type     *         | InfixType [ExistentialClause]     *  ExistentialClause ::= forSome `{' ExistentialDcl {semi ExistentialDcl}} `}'     *  ExistentialDcl    ::= type TypeDcl | val ValDcl     */    def typ(): Tree = typ(false)    def typ(isPattern: Boolean): Tree = placeholderTypeBoundary {      val t =         if (inToken == LPAREN) {          val pos = inSkipToken          if (inToken == RPAREN) {            inNextToken            atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ(isPattern)) }          /* Not more used          } else if (inToken == ARROW) {            inNextToken            val t0 = typ(isPattern)            accept(RPAREN)            atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ(isPattern)) }          */          } else {            val ts = types(isPattern, false, true)            accept(RPAREN)            if (inToken == ARROW) atPos(inSkipToken) { makeFunctionTypeTree(ts, typ(isPattern)) }            else {              for (t <- ts) t match {                case AppliedTypeTree(Select(_, n), _)                 if (n == nme.BYNAME_PARAM_CLASS_NAME.toTypeName) =>                  syntaxError(t.pos, "no by-name parameter type allowed here", false)                case _ =>              }              infixTypeRest(pos, annotTypeRest(pos, isPattern, makeTupleType(ts, true)), false, InfixMode.FirstOp)            }          }        } else {          infixType(isPattern, InfixMode.FirstOp)        }      if (inToken == ARROW)        atPos(inSkipToken) {           makeFunctionTypeTree(List(t), typ(isPattern))         }      else if (inToken == FORSOME)        atPos(inSkipToken) {          val whereClauses = refinement()          for (wc <- whereClauses) {            wc match {              case TypeDef(_, _, _, TypeBoundsTree(_, _)) | ValDef(_, _, _, EmptyTree) | EmptyTree =>                ;              case _ =>                syntaxError(wc.pos, "not a legal where clause", false)             }          }          ExistentialTypeTree(t, whereClauses)        }      else t    }    /** InfixType ::= CompoundType {id [nl] CompoundType}      */    def infixType(isPattern: Boolean, mode: InfixMode.Value): Tree = placeholderTypeBoundary {      infixTypeRest(inCurrentPos, infixTypeFirst(isPattern), isPattern, mode)    }    def infixTypeFirst(isPattern: Boolean) =       if (inToken == LBRACE) scalaAnyRefConstr else annotType(isPattern)    def infixTypeRest(pos: Int, t0: Tree, isPattern: Boolean, mode: InfixMode.Value): Tree = {      val t = compoundTypeRest(pos, t0, isPattern)      if (isIdent && inName != nme.STAR) {        val opPos = inCurrentPos        val leftAssoc = treeInfo.isLeftAssoc(inName)        if (mode == InfixMode.LeftOp) checkAssoc(opPos, inName, true)        else if (mode == InfixMode.RightOp) checkAssoc(opPos, inName, false)        val op = ident()        newLineOptWhenFollowing(isTypeIntroToken)        def mkOp(t1: Tree) = atPos(opPos) { AppliedTypeTree(Ident(op.toTypeName), List(t, t1)) }        if (leftAssoc)          infixTypeRest(inCurrentPos, mkOp(compoundType(isPattern)), isPattern, InfixMode.LeftOp)        else          mkOp(infixType(isPattern, InfixMode.RightOp))      } else t    }    /** CompoundType ::= AnnotType {with AnnotType} [Refinement]      *                |  Refinement     */      def compoundType(isPattern: Boolean): Tree =

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?