我正在尝试使用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)?
谢谢!
答案 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
^
您还可以将~>
,^^
等运算符与>>
一起使用,flatMap
是for
的别名,但我个人认为{{1}在这种情况下,理解更加清晰。