回溯递归下降解析器用于以下语法

时间:2015-03-27 23:10:40

标签: parsing backtracking peg recursive-descent

我试图找出一些涉及解析表达式语法的细节,并且坚持以下问题:

对于给定的语法:

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并成功,然后留下任何东西来进行解析。这是解析表达式语法应该做的吗?福特论文中的伪代码似乎表明了这一点。

非常感谢。

-Patrick

2 个答案:

答案 0 :(得分:0)

在PEGs中,确实订购了分离(替代品)。在福特的论文中,运算符写成 / 并称为"有序选择",它将它与 | 析取运算符区分开来。

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

答案 1 :(得分:0)

感谢您的回复Rici。

我更加仔细地阅读了福特的论文,并重申了你所说的话。 PEGs /运算符都是贪婪的。所以上面提到的规则应该是失败的。

-Patrick