我有一个sbt插件,其中包含类似于此的Parser:
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 :(得分: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)
}
这就是在sbt:
中定义Space,OptSpace等的方式/** 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(" ")