Scala JavaTokenParsers动态解析

时间:2015-04-13 19:53:57

标签: scala parsing tokenize

我正在尝试使用JavaTokenParser来解析从前一个标记读取大小的字符串的重复次数, 即。

list-name:5
ABCDE

second-list-name:2
AB  //<--the length of the string determines by the value at the token before

所以repN将由列表名称

之后的令牌I确定
def body = (listname <~ ":") ~ (numOfRepeat <~ LF) ~ repN(?, char)
def char = """[A-Z]""".r

我是否可以将 just-passed-token (numOfRepeat)作为Int值传递给下一个解析器(repN)?

谢谢!

1 个答案:

答案 0 :(得分:6)

是的! - 这正是monadic解析允许你做的事情:后续解析取决于早期的结果。例如:

import scala.util.parsing.combinator._

object parser extends JavaTokenParsers {
  override val skipWhitespace = false

  val lengthAndBody: Parser[String] = for {
    _ <- ident
    _ <- literal(":")
    n <- decimalNumber
    _ <- literal("\\n")
    body <- repN(n.toInt, "[A-Z]".r)
  } yield body.mkString

  def apply(in: String) = parseAll(lengthAndBody, in)
}

然后:

scala> parser("""listName:5\nABCDE""")
res5: parser.ParseResult[String] = [1.18] parsed: ABCDE

可是:

scala> parser("""listName:5\nABCD""")
res6: parser.ParseResult[String] =
[1.17] failure: string matching regex `[A-Z]' expected but end of source found

listName:5\nABCD
                ^

并且:

scala> parser("""listName:5\nABCDEF""")
res7: parser.ParseResult[String] =
[1.18] failure: string matching regex `\z' expected but `F' found

listName:5\nABCDEF
                 ^

您还可以将~>^^等运算符与>>一起使用,flatMapfor的别名,但我个人认为{{1}在这种情况下,理解更加清晰。