【发布时间】:2018-02-21 02:06:20
【问题描述】:
我正在尝试使用出色的 parboiled2 库解析文件格式,其中某些字段的存在取决于已处理的一个或多个字段的值。
例如,假设我有两个字段,其中第一个是指示第二个是否存在的标志。也就是说,如果第一个字段是true,那么第二个字段(在这个例子中是一个整数值)存在并且必须被处理 - 但如果它是false,那么第二个字段不存在于全部。请注意,第二个字段不是可选——它要么必须被处理(如果第一个字段是true)要么不能被处理已处理(如果第一个字段是 false)。
因此,如果第三个字段(我们假设始终存在)是带引号的字符串,则以下两行均有效:
true 52 "Some quoted string"
false "Some other quoted string"
但这将是无效的:
false 25 "Yet another quoted string"
忽略第三个字段,如何编写规则来解析前两个? (我无法从文档中看出,谷歌搜索到目前为止还没有帮助......)
更新:我应该澄清我不能使用如下规则,因为我正在解析的格式实际上比我的示例复杂得多:
import org.parboiled2._
class MyParser(override val input: ParserInput)
extends Parser {
def ws = // whitepsace rule, puts nothing on the stack.
def intField = // parse integer field, pushes Int onto stack...
def dependentFields = rule {
("true" ~ ws ~ intField) | "false" ~> //etc.
}
}
更新 2:我已修改以下内容以使我的意图更清晰:
我正在寻找的是与以下(不存在的)规则等效的有效规则,该规则仅在满足条件时才执行匹配:
import org.parboiled2._
class MyParser(input: ParserInput)
extends Parser {
def ws = // whitepsace rule, puts nothing on the stack.
def intField = // parse integer field, pushes Int onto stack...
def boolField = // parse boolean field, pushes Boolean onto stack...
def dependentFields = rule {
boolField ~> {b =>
// Match "ws ~ intField" only if b is true. If match succeeds, push Some(Int); if match
// fails, the rule fails. If b is false, pushes None without attempting the match.
conditional(b, ws ~ intField)
}
}
}
也就是说,ws ~ intField 仅在 boolField 产生 true 值时才匹配。这样的事情可能吗?
【问题讨论】:
标签: scala parboiled2