一种是按照步骤一步步推进,用于解决一些题目
另一种是比较快速的判断方法
首先文法G[S]
S->a
S->^
S->(T)
T->SN
N->,SN
N->#
是否=># |
First集 |
Follow集 |
|
S |
否 |
{a,^,(} |
{#, ’,’ , ) } |
T |
否 |
{a,^,(} |
{ ) } |
N |
是 |
{‘,’ , #} |
{ ) } |
Select(S->a) = {a}
Select(S->^) ={^}
Select(S->(T)) ={ ( }
Select(T->SN) = {a,^,(}
Select(N->,SN)={ , }
Select(N->#) ={ ) }
第一种判断方法:
对于文法的产生式任一产生式:
(1)文法不存在左递归
(2)假设A->α | β是其中一个产生式, 如果α 或者 β都不能推出 ε,则FIRST(α )∩first( β)=∅
(3)假设A->α | β是其中一个产生式, 如果α 或者 β至多有一个能推出 ε,或者其中一个经过若干步能推出ε,
则first(α)∩follow(A)=∅(这里假设β能推出 ε)
文法所有的产生式都要满足以上三种情况才符合LL(1)文法
第二种判断方法:
第一步:求能推出#的非终结符
结果如下图:
是否=># |
|
S |
否 |
T |
否 |
N |
是 |
(1)初值:“未定”
(2)扫描:
①先删除右部有终结符(只要有就删除)的产生式,若某符号的产生式全部被删除光了,则定义“否”(这里S直接可以定义否)
这个时候产生式剩下:
T->SN
N->,SN
N->#
②若某产生式右部为#,则该非终结符标“是”,并删除该终结符相关的所有产生式; (这里N可以定义为“是”,并N在左部的所有产生式)
这个时候产生式剩下:
T->SN
(3)扫描右部的每一个符号
①右部“是”对应的非终结符都要被删除(在经历(2)中的扫描产生的“是”的非终结符,这里是指N ; 这里的删除值得是删除单个字符,),若这使得某个某个产生式右部为空,则该产生式左部的符号,可以直接标“是”,然后删除该符号的相关产生式
例子:
经历扫描前还剩下 T->SN
之后删除N
T->S
(4)扫描右部的每一个符号
同上,右部如果对应为“否”的符号,则删除整个产生式(注意:区别上面的(3)上面是先删除单个字符,这里是直接删除整个产生式),若这使得产生式左部相关符号的所有的产生式都被删除,则标记“否”
S标记为“否”,则删除T->S,这时,关于T的所有产生式都被删除,这时T被标记“否”
得下图(也就是上文的图标):
是否=># |
|
S |
否 |
T |
否 |
N |
是 |
然后求相应的first集,follow集,select集
相应的求法可以看博主的另一篇博客,里面的例子是本文法的first集,follow集,select集的求法步骤和解析:点击这里跳转
求出first,follow,select集如下:
是否=># |
First集 |
Follow集 |
|
S |
否 |
{a,^,(} |
{#, ’,’ , ) } |
T |
否 |
{a,^,(} |
{ ) } |
N |
是 |
{‘,’ , #} |
{ ) } |
Select(S->a) = {a}
Select(S->^) ={^}
Select(S->(T)) ={ ( }
Select(T->SN) = {a,^,(}
Select(N->,SN)={ , }
Select(N->#) ={ ) }
现在进行LL(1)文法的判断:
左部符号相同的进行交集比较,如果全部交集为空,则符合LL(1)文法:
Select(S->a)∩Select(S->^)∩Select(S->(T)) = {a}∩{^}∩{ ( } = ∅
Select(N->,SN)∩Select(N->#) ={ ) }∩{ , } =∅
都为空集,因此符合LL(1)文法