scala解析组合器强制解析器排序

时间:2015-12-06 06:44:36

标签: scala parsing

假设有两个解析器:p& q
现在,给出以下代码:

val p1 = p | q
val p2 = "$" ~> p1 <~ "$"
发生了一些奇怪的事情。假设一些字符串:val input = "..."

parseAll(p1, input)

使用p的解析结果成功,但是:

parseAll(p2, "$" + input +"$")

q的解析结果成功 订单很重要。我只想在q失败后尝试p

有什么办法可以强制解析器在p之前评估q吗?

编辑:

在仔细检查文档之后:

  如果p | q成功或p成功,

q会成功。   请注意,q仅在p失败为非致命(即允许回溯)时才会尝试。

所以我的代码应该可以工作 所以我尝试用一​​个简单的例子进行复制(我的原始代码也是特定于用例的,而且大多数都与这里不相关)。但并没有成功。相反,我设法提出了一个解析器,它应该成功时失败。在以下REPL会话中显示:

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.util.parsing.combinator._
import scala.util.parsing.combinator._

scala> object MyParser extends RegexParsers {
     |   val xyz = "xyz".r ^^ { case s => Right(s) }
     |   val any = "\\S+".r ^^ { case s => Left(s) }
     |   val either: Parser[Either[String,String]] = xyz | any
     |   val wrapped = "$" ~> either <~ "$"
     |   def parseMeATest1(input: String) = parseAll(either, input) match {
     |     case Success(Right(s),_) => println(s"right: $s")
     |     case Success(Left(s),_) => println(s"left: $s")
     |     case NoSuccess(msg, _) => println(msg)
     |   }
     |   def parseMeATest2(input: String) = parseAll(wrapped, input) match {
     |     case Success(Right(s),_) => println(s"right: $s")
     |     case Success(Left(s),_) => println(s"left: $s")
     |     case NoSuccess(msg, _) => println(msg)
     |   }
     | }
defined object MyParser

scala> MyParser.parseMeATest1("xyz")
right: xyz

scala> MyParser.parseMeATest1("zzz")
left: zzz

scala> MyParser.parseMeATest2("$xyz$")
right: xyz

scala> MyParser.parseMeATest2("$zzz$")
`$' expected but end of source found

那么,我在这里错过了什么,或者这是scala解析组合器的错误

解决:

问题是p解析器消耗了尾随的$字符,导致整体失败,但由于使用了回溯,因此q不消耗$字符的{{1}}成功完成

0 个答案:

没有答案