2017-02-01 50 views
0

我有一个包含一些类似这样的解析器的SBT插件:SBT分析器失败OutOfMemoryException异常

package sbtpin 

import sbt.complete._ 
import DefaultParsers._ 

object InputParser { 
    private lazy val dotParser: Parser[Char] = '.' 
    private lazy val objectId = identifier(Letter, IDChar | dotParser) 

    private lazy val addCommand1 = "add" ~> Space.+ ~> objectId ~ (Space.+ ~> NotSpace.+).? map(p => AddCommand1(p._1, p._2)) 
    private lazy val addCommand2 = "add -n" ~> Space.+ ~> objectId ~ (Space.+ ~> NotSpace.+).? map(p => AddCommand1(p._1, p._2)) 
    private lazy val addCommand2 = "add -l" ~> Space.+ ~> objectId ~ (Space.+ ~> NotSpace.+).? map(p => AddCommand1(p._1, p._2)) 

    lazy val parser: Parser[Command] = Space.* ~> (addCommand1 | addCommand2 | addCommand3) 
} 

当试图用这种分析器运行测试时,出现“java.lang.OutOfMemoryError:Java堆空间“

at scala.collection.mutable.StringBuilder.<init>(StringBuilder.scala:46) 
    at scala.collection.mutable.StringBuilder.<init>(StringBuilder.scala:51) 
    at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:286) 
    at scala.collection.AbstractTraversable.mkString(Traversable.scala:105) 
    at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:288) 
    at scala.collection.AbstractTraversable.mkString(Traversable.scala:105) 
    at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:290) 
    at scala.collection.AbstractTraversable.mkString(Traversable.scala:105) 
    at sbt.complete.ParserMain$$anon$3$$anonfun$string$1.apply(Parser.scala:313) 
    at sbt.complete.ParserMain$$anon$3$$anonfun$string$1.apply(Parser.scala:313) 
    at sbt.complete.Parser$Value.map(Parser.scala:161) 
    at sbt.complete.MapParser.resultEmpty$lzycompute(Parser.scala:704) 
    at sbt.complete.MapParser.resultEmpty(Parser.scala:704) 
    at sbt.complete.Repeat.derive(Parser.scala:834) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 
    at sbt.complete.HomParser.derive(Parser.scala:632) 

编译也需要很长时间,这是意想不到的。

回答

0

我意识到我使用Space,+,Space *等,当Space,OptSpace等就足够了。这是因为Space和OptSpace(在DefaultParsers中定义)已经匹配多个字符。

我改变了代码以下,工作正常:

package sbtpin 

import sbt.complete._ 
import DefaultParsers._ 

object InputParser { 
    private lazy val dotParser: Parser[Char] = '.' 
    private lazy val objectId = identifier(Letter, IDChar | dotParser) 

    private lazy val addCommand1 = "add" ~> Space ~> objectId ~ (Space ~> NotSpace).? map(p => AddCommand1(p._1, p._2)) 
    private lazy val addCommand2 = "add -n" ~> Space ~> objectId ~ (Space.+ ~> NotSpace).? map(p => AddCommand1(p._1, p._2)) 
    private lazy val addCommand2 = "add -l" ~> Space ~> objectId ~ (Space ~> NotSpace).? map(p => AddCommand1(p._1, p._2)) 

    lazy val parser: Parser[Command] = OptSpace ~> (addCommand1 | addCommand2 | addCommand3) 
} 

这是怎么了空间,OptSpace等在SBT定义:

/** Matches a single character that is not a whitespace character. */ 
lazy val NotSpaceClass = charClass(!_.isWhitespace, "non-whitespace character") 

/** Matches a single whitespace character, as determined by Char.isWhitespace.*/ 
lazy val SpaceClass = charClass(_.isWhitespace, "whitespace character") 

/** Matches a non-empty String consisting of non-whitespace characters. */ 
lazy val NotSpace = NotSpaceClass.+.string 

/** Matches a possibly empty String consisting of non-whitespace characters. */ 
lazy val OptNotSpace = NotSpaceClass.*.string 

/** Matches a non-empty String consisting of whitespace characters. 
* The suggested tab completion is a single, constant space character.*/ 
lazy val Space = SpaceClass.+.examples(" ") 

/** Matches a possibly empty String consisting of whitespace characters. 
* The suggested tab completion is a single, constant space character.*/ 
lazy val OptSpace = SpaceClass.*.examples(" ")