Scala组合语法分析器:重复和后续连接规则中重复规则的子集



我正在使用scala组合子分析字符串,我想要这样的字符串"Ph"或"Ph."或"Ph.D"或"Ph.D"将被成功解析,其中,就目前而言,前三个已成功解析,但当我执行println(parseAll(name, "Ph.D."))时,我看到以下内容:

[1.6] failure: string matching regex `p{IsLatin}+' expected but end of source found
Ph.D.
     ^

我的直觉是,因为nameSepSubsetnameSep使用的规则,所以rep1(nameSub ~ nameSep)消耗了"Ph.D."中的所有内容,因此不产生对nameSub ~ nameSepSubset的输入。除了rep1,还有其他运算符或定义语法的其他方法可以解决这个问题吗?

语法:

lazy val nameSub = """[a-zA-Z]+""".r
lazy val nameSepSubset = (
    rep1(" ")
    ||| "." ~ rep1(" ")
    ||| ".")
lazy val nameSep = (
        nameSepSubset
        ||| rep(" ") ~ "," ~ rep(" ")
        ||| rep(" ") ~> "-" <~ rep(" ")
        ||| "'")

lazy val name = (rep1(nameSub ~ nameSep) ~ nameSub ~ nameSepSubset
                 ||| nameSub ~ nameSepSubset)

一个解决方案可以是使用名称的递归定义来重新定义名称规则:

lazy val name = nameSub ~ nameSep ~ name //(1)
                ||| nameSub ~ nameSepSubset /*(2)*/ ||| "" /*(3)*/

你可以看到合法的输出是:

来自规则(2)的nameSub ~ nameSepSubset,其等价于可从规则(3)导出的nameSub ~ nameSepSubset ~ ""

nameSub ~ nameSep ~ nameSub ~ nameSepSub

nameSub ~ nameSep ~ nameSub ~ nameSep ~ nameSub ~ nameSepSub

最新更新