【问题标题】:Scala external DSL - infinite loop caused by alternative repetitionsScala外部DSL - 由替代重复引起的无限循环
【发布时间】:2013-05-23 18:55:23
【问题描述】:

我正在尝试在 Scala 中构建一个简单的外部 DSL,它能够解析如下字符串:

value = "john${tom}peter${greg}${sue}meg"

通常,引号内的子字符串包含交错的名称以及位于${} 之间的名称。

我的语法如下:

class Grammar extends JavaTokenParsers {
  def workflow = "value" ~> "=" ~> "\"" ~> pair <~ "\""

  def pair = rep(str | token)

  def str = rep(char)

  def char: Parser[String] = """[a-z]""".r

  def token = "$" ~> "{" ~> str <~ "}"
}

执行者:

var res = parseAll(workflow, str)
println(res)

我认为def pair = rep(str | token) 方法可以正确解析它。不仅不起作用,还会导致parseAll方法内出现无限循环。

那我该如何解析这样的字符串呢?似乎另一种重复 (rep) 不是正确的方法。

【问题讨论】:

    标签: scala grammar dsl parser-combinators


    【解决方案1】:

    您应该将rep 替换为rep1

    rep 总是成功的(除非它是一个Error),所以在rep(char) | token 的右边部分(token)是无用的 - 你会得到一个空的 successful 结果rep(char).

    此外,您可以将"""[a-z]""".r 替换为accept('a' to 'z') 或将str 定义为def str: Parser[String] = """[a-z]+""".r。使用Regex 来匹配单个Char 是一种矫枉过正。

    【讨论】:

    • 我错过了,谢谢。此外,这里使用Regex 当然是矫枉过正,但我​​只是想分享导致问题的相同版本的代码。
    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多