我无法使用包含epsilon产品的语法为LR(1)解析器构建项集合。例如,给定以下语法(其中eps代表epsilon)
S -> a S U
U -> b
| eps
State0将是
S' -> .S, $
S -> .a S U, $
随着' a'移动从State0将给出以下状态,让我们称之为State2
S -> a .S U, $
S -> .a S U, $/???
为了对State2的第二项进行预测,我需要计算FIRST(U $)。我知道FIRST(U)= {' b',eps}。我的第一个问题是:State2第二项的前瞻是$和' b&#39 ;?由于U可以是eps,我的大脑告诉我,我也可以将$作为前瞻,而不仅仅是' b'。它本来只是' b'如果FIRST(U)只是{' b'}。这是对的吗?
第二个问题:在某些时候我会得到一个状态如下
S -> a S .U, $
U -> .b, $
U -> .eps, $
我在这做什么?我是否需要使用eps移动并使用项目U -> eps., $
设置?如果我有另一个终端作为前瞻,即X -> .eps, a/$
怎么办?如果我移动,最终得到一组X -> eps., $
形式,我会减少吗?
还有更多:我是否需要在解析表中插入eps作为符号?
由于
答案 0 :(得分:2)
FIRST(U$)
表示“可以在U$
的派生中首先出现的符号集”。显然,如果U
可以派生出空字符串,$
必须是此集合的一部分。输入结束标记$
确保我们永远不必担心FIRST
集中的epsilons。 (如果我们使用LR(k)而不是LR(1),我们将使用k
结束标记,以便FIRSTk
中的所有字符串都具有k
的长度。
与U →
相关联的项目(如果您坚持,则为U → ε
)为U → •
。换句话说,它是可以减少的,并且应该在匹配前瞻时触发减少操作。
ε
不是符号;我们只使用它(有时)使空字符串可见。但是空字符串是空的。