Parsing 语法中的间接递归
我试图从以下语法中删除间接递归:Parsing 语法中的间接递归,parsing,recursion,compiler-construction,grammar,Parsing,Recursion,Compiler Construction,Grammar,我试图从以下语法中删除间接递归: F -> P X X -> R C R -> C R | I R | epsilon 所有大写字母都是非终端,我刚刚停止制作,因为它们并不重要 在这之后,您可以看到我将得到类似于F->p(C | I)*C的东西,这会给我的递归下降解析器带来问题 任何有效的表达式都必须以C结尾,但这个最终的C总是通过重复使用R产品来使用,没有为X->R C产品的最终C留下任何标记 以下面的令牌表达式为例:“p C I C” 我们使用F->px产品删除第一个P
F -> P X
X -> R C
R -> C R | I R | epsilon
所有大写字母都是非终端,我刚刚停止制作,因为它们并不重要
在这之后,您可以看到我将得到类似于F->p(C | I)*C的东西,这会给我的递归下降解析器带来问题
任何有效的表达式都必须以C结尾,但这个最终的C总是通过重复使用R产品来使用,没有为X->R C产品的最终C留下任何标记
以下面的令牌表达式为例:“p C I C”
- 我们使用F->px产品删除第一个P,留下“cic”
- 然后X->R C->C R C,这样我们就可以消耗C,留下“I C”
- 然后R C->I R C,这样我们就可以消耗离开“C”的I
- R C->C R C,所以我们消耗最后一个字符C,不留下任何剩余标记李>
p(C | I)*C
重写为pi*C+(I+C+)*
,这很容易作为递归下降解析器实现。如果你把它写成一个正确的递归BNF语法,你会得到不正确的结合性,但是通常你会用循环来编写递归下降解析器,使用上面的扩展BNF。[注1]
实际上,一旦解析了p
,就会得到如下结果:
do {
while (try_parse(I)) {}
parse(C);
while (try_parse(C)) {}
} while (try_parse(I));
笔记
@如果你对不涉及递归的语法使用“递归”下降解析器,它不是递归下降解析器…@Am\u I\u help它在逻辑上是正确的。如果语法没有递归,那么解析时就不需要递归。在OP的语法中解析R的方法必然会递归,因为语法是递归的。@davmac-嗯,的确如此。学习编译器设计课程已经有很长时间了(一年多以前),你是对的。我同意,@OP-应该是单词
下降
,不合适。输入后面是否有一个终止符(文件结尾或类似的东西),您可以使用它(通过向前看)为R
选择正确的生成规则?在后面(F)是第一(I)吗?