【20200409】编译原理课程课业打卡十四之改写非LL(1)文法并判断是否为LL(1)型文法
叮嘟!这里是小啊呜的学习课程资料整理。好记性不如烂笔头,今天也是努力进步的一天。一起加油进阶吧!
一、课业打卡十四之改写非LL(1)文法并判断是否为LL(1)型文法
问题描述:
1、问题一解答过程
2、问题二解答过程
二、知识巩固之例题拓展
1、例题拓展一
文法 G(S):
(1)S -> AB
(2)A ->Da|ε
(3)B -> cC
(4)C -> aADC |ε
(5)D -> b|ε
验证文法 G(S)是不是 LL(1)文法?
答:
证明:FIRST(Da) = {b, a}
FIRST(ε) = {ε}
FIRST(aADC) = {a}
FIRST(b) = {b}
FOLLOW(A) = {c, b, a, #}
FOLLOW(C) = {#,}
FOLLOW(D) = {a, #}
SELECT(A -> Da) = FIRST(Da) = {b, a}
SELECT(A -> ε) = FIRST(ε) - {ε}UFOLLOW(A) = FOLLOW(A) = {c, b, a, #}
因为SELECT(A -> Da) ∩ SELECT(A -> ε) ≠ Ø
所以G(S)不是 LL(1)文法。
2、例题拓展二
文法消除左递归之后的表达式文法为:
(1)E -> TE’
(2)E’ -> +TE’ | ε
(3)T -> FT’
(4)T’ -> *FT’ | ε
(5)F -> (E) | i
判断是否是LL(1)文法?
答:
FIRST(+TE') = {+}
FIRST(ε) = {ε}
FIRST(*FT') = {*}
FIRST((E)) = { ( }
FIRST(i) = {i}
FOLLOW(E') = { ), # }
FOLLOW(T') = {+, ), #}
FOLLOW(F) = {*, +, ), #}
SELECT(E' -> +TE') = FIRST(+TE') = {+}
SELECT(E' -> ε) = FIRST(ε) - {ε}UFOLLOW(E') = FOLLOW(E') = { ), # }
SELECT(T' -> *FT') = FIRST(*FT') = {*}
SELECT(T' -> ε) = FIRST(ε) - {ε}UFOLLOW(T') = FOLLOW(T') = { +, ), # }
SELECT(F -> (E)) = FIRST((E)) = { ( }
SELECT(F->i)=FIRST(i)={i}
因为SELECT(E' -> +TE') ∩ SELECT(E' -> ε) = Ø
SELECT(T' -> *FT') ∩ SELECT(T' -> ε) = Ø
SELECT(F -> (E)) ∩ SELECT(F -> i) = Ø
所以此表达式文法是LL(1)文法。
3、例题拓展三【两种方法详细解答】
判断是否是LL(1)文法?
已知文法G[S]:
S->a
S->^
S->(T)
T->SN
N->,SN
N->#
解法一:
Select(S->a) = {a}
Select(S->^) ={^}
Select(S->(T)) ={ ( }
Select(T->SN) = {a,^,(}
Select(N->,SN)={ , }
Select(N->#) ={ ) }
左部符号相同的进行交集比较,如果全部交集为空,则符合LL(1)文法:
Select(S->a) ∩ Select(S->^) ∩ Select(S->(T)) = {a} ∩ {^} ∩ { ( } = ∅
Select(N->,SN) ∩ Select(N->#) ={ ) } ∩ { , } =∅
都为空集,因此符合LL(1)文法。
解法二:
1、判断非终结符是否能推出 #(空字)。
结果如下图:
推导步骤:
(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被标记“否”
得下图:
2、然后求相应的first集,follow集,select集;
求出first,follow,select集如下:
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)文法。
4、关于 LL(1)文法
对于文法的产生式任一产生式:
(1)文法不存在左递归
(2)假设A->α | β是其中一个产生式, 如果α 或者 β都不能推出 ε,则FIRST(α )∩first( β)=∅
(3)假设A->α | β是其中一个产生式, 如果α 或者 β至多有一个能推出 ε,或者其中一个经过若干步能推出ε,则first(α)∩follow(A)=∅(这里假设β能推出 ε)
文法所有的产生式都要满足以上三种情况才符合LL(1)文法
Ending!
更多课程知识学习记录随后再来吧!
就酱,嘎啦!
注:
1、人生在勤,不索何获。
2、LL(1)文法的判断例题参见博客:
https://blog.csdn.net/hxfghgh/article/details/80152402