假设我有这个RegexParsers函数解析一个简单的x = value语句:
def term: Parser[String] = """[a-zA-Z0-9"']+""".r ^^ { _.toString }
def assign: Parser[(varLabel, ValueThing)] = term <~ "=" ~ term ^^ {
case v ~ t => (v, ValueThing(t))
}
足够简单。好吧,假设需要根据标签(第一项)解析分配的值(第二项)?
不知何故,我想解析第一个术语并以某种方式将其传递给第二个术语的解析器 - 换句话说,条件解析。也许我有一个Parsers查找表,基于'x'我查找正确的Parser来解析赋值。
(那么为什么我不使用'|'?因为它是无上下文的。我可能有> 1个子解析器用于分配的值可以工作 - 例如解析一个double值。一个只是解析为double,而另一个用可选的文本术语解析一个double。两个都用于一个裸的双重w / o这个术语。如果我知道'x'在'x = 2.34'中是什么,那么我就知道是否要解析2.34作为裸体双人或双人w / o它是可选术语。也许不是一个很好的例子,但我有很多这类事情。)
答案 0 :(得分:1)
这些解析器组合非常酷!有一些叫做的东西,缩写&gt;&gt;这样做。看起来像这样:
def assign: Parser[Int] = (term <~ "=") >> (target => lookup(target))
def one: Parser[Int] = term ^^ {
case s => if(s == "hey") 1 else 0
}
def two: Parser[Int] = term ^^ {
case s => if(s == "you") 100 else -100
}
val lookup = Map("x" -> one, "y" -> two)
愚蠢的例子,但显示了一点:你可以抓住第一个术语然后使用该值随后进一步解析,在我的情况下从表中查找“处理程序”解析器。当然,选择逻辑和子解析器可能要复杂得多。