LL(1)文法的判断

一种是按照步骤一步步推进,用于解决一些题目

另一种是比较快速的判断方法


首先文法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)文法



猜你喜欢

转载自blog.csdn.net/hxfghgh/article/details/80152402