编译原理:first集合和follow集合的求法及LL(1)文法判定

(个人经验,觉得比较好判断的可以试试)

文法

S->Ab
A->a|B|e
B->b|e

e为空符号,大写字母为非终结符,小写字母为终结符
first集合求法
因为B能推导出两个终结符,所以它的first集合比较容易求出来
1.若X->a,X->b,X->c,则将终结符a加入first(X)中,即first(X)={a,b,c}
2.若X->e ,则将终结符e加入first(X)中
由上面步骤知例子中first(B)={b,e}
因为A有一个非终结符B,且B的first集合已经知道了,所以判断A
3.若X->BCD,先检测到B,则先将first(B)中所有元素(除了空集)加入first(X),若first(B)中不存在空集, 即停止检测,若存在则向B的后面查看,将first(C)中所有元素(除了空集)加入first(X),再判断first(C)中是否有e…直到最后,若D之前的所有非终结符的first集中都含有e,就检测到D时,将first(D)也加入first(X),若first(D)中含有e,则将 e加入first(X)
由上面的步骤,例子中first(A)={a}Ufirst(B)U{e}={a,b,e}
最后,例子中first(S)=(first(A)-{e})U{b}={a,b}
如果文法改为S->AB,则first(S)=(first(A)-{e})Ufirst(B)

follow集合求法
首先看到开始符号S,发现它没有在任何一个产生式的右部出现
1.对文法开始符号S,置#于fOLLOW(S)中
follow(S)={#}
再看例子中的非终结符A,它出现在第一个产生式的右部,后面一个是b,所以follow(A)={b}
2.对于产生式:A->aBC,将除去空集e的first(C)加入follow(B)中
3.对于产生式:A->aB或者A->aBC,(其中C可以推导出空串,C=>*e),则将follow(A)加入follow(B)中
所以对于例子的非终结符B来说,它出现在第二个产生式的右部,即相当于A->B,根据步骤,将follow(A)加入到follow(B)当中,即follow(B)=follow(A)={b}
如果将例子的第一个产生式改为S->AB,则follow(A)=first(B)-{e}={b}

LL(1)文法判断

借用

对于例子来说
首先判断该文法不含左递归
由于first(A)n follow(A)={b}不为空集,所以该文法不是LL(1)文法
判断一个文法不是LL(1)文法只要一个条件不满足就可以判断

再一个例子

S->ABc
A->a|e
B->b|e

 求解过程就简约点了
first(A)={a,e}
first(B)={b,e}
first(S)=(first(A)-{e})U(first(B)-{e})U{c}={a,b,c}
follow(S)={#}
follow(A)=(first(B)-{e})U{c}={b,c}
follow(B)={c}
由于first(A) n follow(A)=空集,first(B) n follow(B)=空集
且first(a) n first(e)=空集,first(b) n first(e)=空集
所以这个文法是LL(1)文法。
 第一次写博客,希望能帮到大家。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值