我有一个用于递归下降解析器的BNF。解决此问题的步骤之一是验证语法是否为LL(1),但我一直在进行验证以确保语法不是LL(1)。
有问题的BNF,或更确切地说,是我遇到的确切区域:
<S> -> start <vars> <block>
<block> -> begin <vars> <stats> end
<vars> -> e | id = number <vars>
<stats> -> <if> | <block> | <loop> | <assign>
还有更多,但我相信,这是与该问题有关的唯一作品。
我解决这个问题的方法是计算那些有选择权的作品右手边的FIRST。如果没有选择,我会跳过,因为我知道它们已经是k = 0。
FIRST(e | id = number <vars>) = {e, id} // Since it produces the empty set, I must also compute follow.
FOLLOW( e | id = number <vars> ) = FOLLOW(<vars>)
非终结符“ vars”出现在2个产品中:和,其后是两个非终结符:“ block”和“ stats”
FIRST(<block>) = {begin}
FIRST(<stats>) = { ... begin ... } // contains all terminals
现在,我的问题。在计算FOLLOW()时,我发现了两个开始标记,这使我说该语法不是LL(1)。但是,我不认为此练习的答案是不可能创建递归下降解析器,所以我相信我在某个地方犯了错误或执行算法不正确。
有人能指出我正确的方向吗?
答案 0 :(得分:0)
因此,您已经正确地发现FOLLOW( var )= FIRST( block )∪FIRST( stats )。这些都是集合,因此,当计算前两个集合(每个集合都包含begin
)的并集时,最终只会得到一个begin
。只要这两个集合都没有包含id
,一切都很好,您的语法仍然是LL(1)。