1

编辑(概括问题):

我想解析一个语法,在哪里

<prefix> ::= [a-z]*
<middle> ::= xxx
<suffix> ::= b+
<grammar> ::= <prefix><middle><suffix>

我希望(例如)以下单词通过:aaaaxxxbb, axxxaaxxxbbb,xxxxxxbb

原帖:

我希望以下解析器能够回溯并最终找到解决方案:

val before = P(AnyChar.rep.!)
val content = P("xxx".!)
val after = P("b".rep.!)
val all = P(before ~ content ~ after ~ End)
def test() = {
  val r = all.parse("aaaaxxxbbb")
  println(r)
}

相反,看起来该before部分贪婪地解析了所有文本,并且解析器在没有回溯的情况下失败。

我错过了什么吗?

4

1 回答 1

0

我最终能够解决这个问题。

解析器不会在正则表达式中回溯是合理的,所以我认为我应该将该AnyChar.rep部分重写为递归规则,如下所示:

val before: P[Any] = P(AnyChar | (AnyChar ~ before))

但这还不够,fastparse 似乎仍然没有回溯。

我偶然发现了这个关于解析歧义语法的问题。所以我尝试使用GLL 组合子而不是 Fastparse,这使它工作。

object TestParser1 extends Parsers with RegexParsers {

  lazy val before: Parser[String] = (".".r | (".".r ~ before)) ^^ {
    case a ~ b => a.toString + b.toString
    case x => x.toString
  }
  lazy val content: Parser[String] = "xxx"
  lazy val after: Parser[String] = "b+".r
  lazy val all: Parser[String] = before ~ content ~ after ^^ {
    case (b, c, a) => s"$b $c $a"
  }

  def test() = {
    val r = all("aaaaxxxbbb")
    r.toList foreach println
  }

}
于 2016-10-13T06:46:45.660 回答