gpt4 book ai didi

Scala Packrat解析器 : backtracking seems not to work

转载 作者:行者123 更新时间:2023-12-01 19:03:09 24 4
gpt4 key购买 nike

以下 scala 代码无法按预期工作:

import scala.util.parsing.combinator.PackratParsers
import scala.util.parsing.combinator.syntactical.StandardTokenParsers
import scala.util.parsing.combinator.lexical.StdLexical

object Minimal extends StandardTokenParsers with PackratParsers {
override val lexical = new StdLexical

lexical.delimiters += ("<", "(", ")")

lazy val expression: PackratParser[Any] = (
numericLit
| numericLit ~ "<" ~ numericLit
)

def parseAll[T](p: PackratParser[T], in: String): ParseResult[T] =
phrase(p)(new PackratReader(new lexical.Scanner(in)))

def main(args: Array[String]) = println(parseAll(expression, "2 < 4"))
}

我收到错误消息:

[1.3] failure: end of input expected

2 < 4
^

如果我将“表达式”的定义更改为

  lazy val expression: PackratParser[Any] = (
numericLit ~ "<" ~ numericLit
| numericLit
)

问题消失了。

问题似乎是,对于“表达式”的原始定义代码,应用了仅由“numericLit”组成的第一条规则,这样解析器确实期望输入随后立即结束。我不明白为什么解析器在注意到输入确实没有结束时不立即回溯; scala PackratParsers 应该是回溯的,并且我还确保按照另一个问题的答案中的建议将“def”替换为“lazy val”。

最佳答案

您看到此行为的原因是交替运算符(竖线)旨在接受第一个成功的替代选项。在您的情况下,numericLit 成功,因此交替永远不会考虑其他替代方案。

对于这种语法规范,您必须小心一个替代项是否可以与另一个替代项的前缀匹配。正如您所看到的,较长的替代方案应该放在替代方案的前面,否则它永远不会成功。

如果您希望较短的替代项仅在其后没有更多输入的情况下才匹配,那么您可以尝试使用 not 组合器来表达该额外条件。但是,如果要在其他构造中使用表达式,则此方法将导致问题。

关于Scala Packrat解析器 : backtracking seems not to work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24987739/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com