计算FIRST和FOLLOW设置语法?

时间:2016-01-30 17:25:14

标签: parsing grammar ll

我必须计算以下语法的FIRST和FOLLOW集:

S -> ABC
A -> a | Cb | 1
B -> c | dA | 1
C -> e | f

但是,我不完全确定我是否明白该怎么做。根据我的理解,我得到以下计算:

FIRST(S)= {a, e, f, b, c, d}
FIRST(A)= {a, e, f, 1}
FIRST(B)= {c, d, a, e, f, b, 1}
FIRST(C)= {e, f}

FOLLOW(S)= {$}
FOLLOW(A)= {c, d, a, e, f, b}
FOLLOW(B)= {e, f}
FOLLOW(C)= {$}

这是对的吗?我错过了什么?如果是这样,有人可以解释我错过了什么,以及如何计算正确的FIRST和FOLLOW集合?另外,通过查看生成的集合,如何判断它是否为LL(1)语法?

1 个答案:

答案 0 :(得分:0)

当S(目标非终止符号)扩展时,其派生中的第一个终止必须仅来自A,因为这正是语法在S-> ABC中指示的含义。 (除非语法中的“ 1”表示epsilon,即为空的右侧;在这种情况下,我们移至B并找到B的FIRST集。)A可以直接扩展为a和1,并通过C扩展为e和f 。因此,S的第一个集合是a,1,e,f(所有这些端子的并集)。语法看起来是LL(1),因为每个实际标记似乎都确定了在推导的每个步骤中要使用哪个右侧。计算所有FIRST集以确认此猜测。如果同一终端在同一非终端LHS的两个RHS的FIRST集合中,则该语法不是LL(1),因为该终端会导致在选择使用哪种产品时会产生歧义。 LL(1)语法必须是明确的,并且每个非终结符必须具有一个非空的FIRST条目,这意味着该语法没有左递归。

请注意,不需要FOLLOW集,因为不存在右侧为空的产生式(此类产生式可用于以LL(1)语法对LL(2)语言进行建模,但会增加解析器的成本复杂性)。