[英]Recursive descent same prefix
我正在学习递归正确的解析,并提出了一些我认为算法不起作用的场景。 其中一个是,考虑到这个简单的语法:
S→E;
E→id | id + id
然后是字符串id + id;
在该语法的语言中有效。 但是,如果我们执行递归下降算法,它会从S
下降到E
然后下降到id
,这是第一个匹配的终端。 现在输入位于+
,我们回到S
试图匹配;
然后失败; 但在S
级没有其他规则可供选择。
我认为语法不含糊,因为语言id;
中只有2个字符串id;
和id + id;
,每个都有一个独特的解析树。 这里的一般问题是非终端具有相同前缀的产生,并且可能做出在递归中更深层次匹配但在较浅层次上创建无效输入的选择。
我已经阅读了关于递归下降的典型问题,如左递归,但没有发现上面提到的问题。 这真的是一个问题,还是我错过了什么?
我从“ Parsing Techniques: A Practical Guide p.182-188
找到了一个权威的答案,它将上述方法归类为天真的递归体面,并突出了同样的问题。 有两种解决方案总是适用于一般情况而没有预测(因为通常所需的前瞻长度随前缀长度而增加):穷举递归下降需要使用连续和广度优先递归下降。
我对此非常生疏,以至于我可能要发布垃圾,但这不是可以解决的问题吗? 就像是:
func recogniseS
expect(E)
expect(semicolon)
fund recogniseE
expect(id)
if nextTokenIs(plus) then
expect(plus)
expect(id)
endif
或者,类似地,您可以重新表述为:
S → id [+ id];
即本质上只是+
是可选的。 因此,只要可以处理任何可选项,就可以处理这种情况。
这不是一个问题,因为人们可以像这样将语法分解(其中E'
的第一个替代方案是空的):
S → E ;
E → id E'
E' → | + id
对于E'
,如果下一个标记是,我们预测第一个选择;
如果下一个标记是+
,则第二个。
这是一个问题,如果你写这样的PEG语法,它将无法正常工作。 这是一个已知的问题,偶尔被描述为PEG解析的一个问题,但是我认为将人们编写的语言归咎于PEG是不公平的,因为其他解析形式也无法免疫。
如果它不是PEG语法而是普通的旧CFG,那么除非您使用的工具是愚蠢或有问题,否则应该没有问题。 它应该能够将其转换为有效的解析器,无论它是使用递归下降还是其他算法。 如果它使用递归下降,它可能会使用前瞻,这将摆脱这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.