首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >快解析不会回溯

快解析不会回溯
EN

Stack Overflow用户
提问于 2016-10-11 21:29:29
回答 1查看 356关注 0票数 1

编辑(概括问题):

我想解析一个语法,其中

代码语言:javascript
复制
<prefix> ::= [a-z]*
<middle> ::= xxx
<suffix> ::= b+
<grammar> ::= <prefix><middle><suffix>

我希望(例如)传递以下单词:aaaaxxxbbaxxxaaxxxbbbxxxxxxbb

原始员额:

我期望下面的解析器能够回溯并最终找到解决方案:

代码语言:javascript
复制
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部件贪婪地解析所有文本,解析器在没有回溯的情况下失败。

我是不是遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-13 06:46:45

我最终解决了这个问题。

解析器不会在regex中回溯是合理的,因此我认为应该重写AnyChar.rep部分作为递归规则,如下所示:

代码语言:javascript
复制
val before: P[Any] = P(AnyChar | (AnyChar ~ before))

--但这还不够,快速解析似乎没有回溯。

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

代码语言:javascript
复制
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
  }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39987067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档