【问题标题】:Backtracking Recursive Descent Parser for the following grammar用于以下语法的回溯递归下降解析器
【发布时间】:2015-06-01 10:15:31
【问题描述】:

我正在尝试找出一些涉及解析表达式语法的细节,并被困在以下问题上:

对于给定的语法:

a = b Z
b = Z Z | Z

(其中小写字母表示产生式,大写字母表示终端)。 产生式“a”是否应该与字符串“Z Z”匹配?

这是我看到上述语法被翻译成的伪代码,其中每个产生式都映射到一个输出两个值的函数。第一个指示解析是否成功。第二个表示解析后在流中的结果位置。

defn parse-a (i:Int) -> [True|False, Int] :
   val [r1, i1] = parse-b(i)
   if r1 : eat("Z", i1)
   else : [false, i]

defn parse-b1 (i:Int) -> [True|False, Int] :
   val [r1, i1] = eat("Z", i)
   if r1 : eat("Z", i1)
   else : [false, i]

defn parse-b2 (i:Int) -> [True|False, Int] :
   eat("Z", i)

defn parse-b (i:Int) -> [True|False, Int] :
   val [r1, i1] = parse-b1(i)
   if r1 : [r1, i1]
   else : parse-b2(i)

在尝试解析输入“Z Z”上的产生式“a”时,上述代码将失败。这是因为“b”的解析函数不正确。它会贪婪地消耗输入中的两个 Z 并成功,然后什么都不留给 a 解析。这是解析表达式语法应该做的吗?福特论文中的伪代码似乎表明了这一点。

非常感谢。

-帕特里克

【问题讨论】:

    标签: parsing backtracking peg recursive-descent


    【解决方案1】:

    在 PEG 中,析取项(替代项)确实是有序的。在 Ford 的论文中,运算符写作 /,称为“有序选择”,这与 | 析取运算符区别开来。

    这使得 PEG 从根本上不同于 CFG。特别是,给定 PEG 规则 a -> b Zb -> Z Z / Za 将不匹配 Z Z

    【讨论】:

      【解决方案2】:

      感谢您的回复 Rici。

      我更仔细地重新阅读了福特的论文,它重申了你所说的。 PEGs / operator 都是有序的 贪婪的。所以上面提出的规则应该是失败的。

      -帕特里克

      【讨论】:

        猜你喜欢
        • 2018-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多