Yoo*_*Lee 5 compiler-construction compiler-theory parser-generator ll-grammar
你好伙伴堆栈流量成员.
我正在学习编译器类.我确实理解Top-Down Parser应该避免左递归,并转换为右递归方式.
问题是,
a)我理解正确的自上而下的解析器等于LL而自下而上的解析器等于LR?
b)我发现左递归是规则,自称为ex)Expr:== Expr'+'Term | 可能导致无限循环查找Expr的术语.但无论如何,在C或Java中考虑输入的任何示例代码?(我不想要解析器或扫描器代码)我需要的是具有句子形式的案例代码示例,它通过左递归发生无限循环.
c)在自上而下的解析器中使用右递归的方式实际上有什么不同?
ANS c)无需回溯.还有别的吗?
ANS b)x - 2 * y还有其他什么?因为这个用回溯方式解析.
我已经找到了非左递归和左递归的案例.
A -> Ax
Run Code Online (Sandbox Code Playgroud)
A -> Bx
B -> Ay
Run Code Online (Sandbox Code Playgroud)
两者都进入无限循环.
谢谢你,感谢所有专家.
a)我理解正确的自上而下的解析器等于LL而自下而上的解析器等于LR?是
自上而下的解析器进入带有左递归的无限循环,因为代码中的产生如下所示:
A() {
A(); match(x);
}
Run Code Online (Sandbox Code Playgroud)
A永远调用自身,永远不会从输入流中删除任何内容.
左递归不一定是立即的,所以你的"非左递归语法"仍然是递归的:
A -> Bx | z
B -> Ay
Run Code Online (Sandbox Code Playgroud)
如果用生产代替B,你可以看到它是递归的:
A -> Ayx | z
Run Code Online (Sandbox Code Playgroud)
下面是将左递归语法正确转换为右递归语法的示例:左递归:
E -> E + T | T
Run Code Online (Sandbox Code Playgroud)
正确的递归:
E -> T B
B -> + T B | Lambda
Run Code Online (Sandbox Code Playgroud)
E - > TB以来,在规则E - > E + T | 完成规则的应用后,T,T将始终出现在最左侧.由于最左侧由E - > TB处理,我们可以自由地构造我们用B - > + T B做的弦的右侧.我们需要一个lambda生产给我们一个停止点递归.
A - > Ax和A - > xA将是等效的语法,只剩下一个,另一个是右递归.