为此而努力工作:http://www.diku.dk/hjemmesider/ansatte/torbenm/Basics/
可空的示例计算首先使用定点计算。 (见3.8节)
我正在使用Scheme做事并且非常依赖递归。
如果你尝试实现可空或首先通过递归,那么应该很清楚你会在像
这样的制作上无限重复 N -> N a b
其中N是非终端,a,b是终端。
这可以通过维护生产规则左侧看到的一组非终端来递归解决,并在我们考虑过一次之后忽略它们吗?
这似乎适用于可空。先做什么?
编辑:这是我从玩耍中学到的东西。源代码链接在底部。
在计算第一个终端时不能忽略非终端,除非它们可以为空。
考虑:
N -> N a
N -> X
N ->
我们可以忽略N
中的N a
,因为N
可以为空。我们可以将N -> N a
替换为N -> a
,并推断a
是first(N)
的成员。
我们不能忽视N
:
N -> N a
N -> M
M -> b
如果我们忽略了N
中的N -> N a
,我们会推断出a
中的first(N)
是错误的。相反,我们看到N不可为空,因此在首先计算时,我们可以省略任何找到N
作为RHS中第一个符号的生产。
这会产生:
N -> M
M -> b
告诉我们b
位于first(N)
。
源代码:http://gist.github.com/287069
所以...听起来不错吗?
答案 0 :(得分:1)
我建议继续阅读:)
3.13 Rewriting a grammar for LL(1) parsing
,尤其是3.13.1 Eliminating left-recursion
。
请注意,您也可以遇到间接左递归:
A -> Bac
B -> A
B -> _also something else_
但是这里的解决方案非常类似于在第一个示例中消除直接左递归。
您可能需要查看this paper,以更直接的方式解释它。理论较少:)