但是,由于L' 是可空的,Follow(L) 是否也包含Follow(C)?
相反。 Follow(C) 将包含 Follow(L)。想想下面这句话:
...Lx...
其中 X 是某个终端,因此位于 Follow(L) 中。这可以扩展为:
...CL'x...
并进一步:
...Cx...
所以跟在L后面的,也可以跟在C后面。反之则不一定。
要计算以下,请考虑一个图,其中节点是 (NT, n),这意味着非终结符 NT 具有以下标记的长度(在 LL(1) 中,n 是 1 或0)。您的图表如下所示:
_______
|/_ \
(L, 1)----->(L', 1) _(C, 1)
| \__________|____________/| |
| | |
| | |
| _______ | |
V |/_ \ V V
(L, 0)----->(L', 0) _(C, 0)
\_______________________/|
其中(X, n)--->(Y, m) 表示X 的长度为n 的跟随,取决于Y 的长度为m 的跟随(当然,m <= n)。也就是计算(X, n),首先你应该计算(Y, m),然后你应该查看每个包含右侧X和左侧Y的规则例如:
Y -> ... X REST
对于[0, n) 中的每个m,将REST 扩展为长度n - m,然后将每个结果与(Y, m) 集合中的每个关注连接起来。您可以在计算REST 的第一个时计算REST 扩展为什么,只需持有一个标志,说明REST 是完全扩展为第一个还是部分扩展。此外,添加REST 的第一个,长度为n,如下X。例如:
S -> A a b c
A -> B C d
C -> epsilon | e | f g h i
然后找到长度为 3 的 B 的后续(e d a、d a b 和 f g h),我们看规则:
A -> B C d
我们取句子C d,看看它能产生什么:
"C d" with length 0 (complete):
"C d" with length 1 (complete):
d
"C d" with length 2 (complete):
e d
"C d" with length 3 (complete or not):
f g h
现在我们把这些和follow(A, m)合并:
follow(A, 0):
epsilon
follow(A, 1):
a
follow(A, 2):
a b
follow(A, 3):
a b c
"C d" with length 0 (complete) concat follow(A, 3):
"C d" with length 1 (complete) concat follow(A, 2):
d a b
"C d" with length 2 (complete) concat follow(A, 1):
e d a
"C d" with length 3 (complete or not) concat follow(A, 0) (Note: follow(X, 0) is always epsilon):
f g h
这是我们要找的系列。所以简而言之,算法就变成了:
值得注意的是,上述算法适用于任何 LL(K)。对于 LL(1),情况要简单得多。