按照设置自上而下解析

时间:2014-05-08 10:55:35

标签: parsing compiler-construction ll

我对以下规则的跟随集有疑问:

L -> CL'
L' -> epsilon
       | ; L
C -> id:=G
      |if GC
      |begin L end

我已经计算出Follow(L)位于Follow(L')。另外Follow(L')位于Follow(L),因此它们都包含:{end, $}。但是,由于L'为Nullable,Follow(L)还会包含Follow(C)吗?

我已计算出Follow(C) = First(L')以及Follow(C) subset Follow(L) = { ; $ end}

在答案中,Follow(L)Follow(L')仅包含{end, $},但不应包含; Follow(C) L' {1}}可以为空?

由于

1 个答案:

答案 0 :(得分:2)

  

但是,由于L'为Nullable,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)表示n的{​​{1}}长度的跟随,取决于X的长度m的跟随(当然,Y })。这是计算m <= n,首先您应该计算(X, n),然后您应该查看右侧包含(Y, m)的每条规则和左侧的X方:例如:

Y

Y -> ... X REST 中的每个REST,将n - m扩展为m长度,然后将每个结果与[0, n)集合中的每个结果相连。您可以计算(Y, m)在计算REST的第一时扩展到的内容,只需按住一个标记,说明REST是否完全扩展到第一个或部分扩展。此外,添加REST长度REST的第一,如下n。例如:

X

然后,为了找到长度为3的B(S -> A a b c A -> B C d C -> epsilon | e | f g h i e d ad 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)

我们正在寻找的是哪一套。简而言之,算法变为:

  • 创建关注依赖关系的图表
  • 找到connected components并从中创建DAG
  • 从末尾遍历DAG(来自不具有任何依赖性的节点)并使用上述算法计算以下内容,事先计算出第一次。

值得注意的是,上述算法适用于任何LL(K)。对于LL(1),情况要简单得多。