我一直盯着自己对这个问题视而不见,我想这可能是一个真正愚蠢的问题.但我必须吞下自己的骄傲.
我有这个组合器解析器,它没有像我想象的那样回溯.我一直在将它简化为一个小例子而没有完全删除上下文.感觉像“foobar” – 例子更难阅读.我来啦:
@RunWith(classOf[JUnitRunner]) class ParserBacktrackTest extends RegexParsers with Spec with ShouldMatchers { override def skipwhitespace = false lazy val optSpace = opt(whiteSpace) lazy val number = """\d+([\.]\d+)?""".r lazy val numWithOptSpace = number <~ optSpace private def litre = numWithOptSpace <~ ("litre" | "l") def volume = litre ^^ { case _ => "volume" } private def namedPieces = numWithOptSpace <~ ("pcs") ^^ { case _ => "explPcs" } private def implicitPieces = number ^^ { case _ => "implPcs" } protected def unitAmount = namedPieces | implicitPieces def nameOfIngredient = ".*".r def amount = volume | unitAmount // def amount = unitAmount protected def ingredient = (amount <~ whiteSpace) ~ nameOfIngredient describe("IngredientParser") { it("should parse volume") { shouldParse("1 litre lime") } it("should parse explicit pieces") { shouldParse("1 pcs lime") } it("should parse implicit pieces") { shouldParse("1 lime") } } def shouldParse(row: String) = { val result = parseAll(ingredient,row) result match { case Success(value,_) => println(value) case x => println(x) } result.successful should be(true) } }
那么会发生的是第三次测试失败:
(volume~lime) (explPcs~lime) [1.4] failure: string matching regex `\s+' expected but `i' found 1 lime ^
所以似乎升解析器消耗了l然后当它找不到任何空间时失败了.但我会认为它会回溯并尝试下一个生产规则.显然,implicitPieces解析器解析了这一行,因为如果删除前面的卷解析器(删除注释),它就会成功
(implPcs~litre lime) (explPcs~lime) (implPcs~lime)
为什么金额不回溯?我有什么误会?
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。