《编译原理》是同学们在大学期间普遍认为比较晦涩难懂的一门课程,笔者认为其原因主要是其中的逻辑性较强,推理过程较为复杂,导致同学们听的是云里雾里。
今天给同学们带来的是编译原理中非常重要的一章——自顶向下语法分析方法,这一章有一个考试必考的知识点,那就是LL(1)文法的判断及证明,通俗的来说就是判断一个文法是否为LL(1)文法,笔者给同学们总结了一下解题过程。
(1)求出能推出ε的非终结符
这一块书上还是讲的十分清晰的,我就直接附图了,大家跟着书上的思路一步一步进行推导,应该没有太大的问题。
(2)计算FIRST集
这一块如果你看书或者是看网课可能就会开始懵了,大家可以看看我总结的方法(字可能比较丑)
(3)计算FOLLOW集
首先来说明一下求解规则
我们要看产生式的后面
(1)文法开始符,必有#
(2)A->αB FOLLOW(B) B后为空,将FOLLOW(A)加入到FOLLOW(B)中
(3)A->αBβ B后不为空 β是终结符,直接写下来。β是非终结符,First(β)(除ε以外)加 到 FOLLOW(B)中。如果β->ε,带入A->αBβ,得到A->αB
我们再来看看一道例题
我们先列出哪些推导式可以推导出 ε,我们可以发现E'->ε,T'->ε,F'->ε
我们先找FOLLOW(E),将#加入到FOLLOW(E),接着我们可以发现推导式右部含有E的有E'->+E|ε,P->(E)|a|b|^,第一个推导式E的后面为空,故符合第二条规则,将FOLLOW(E')加入到FOLLOW(E)中,第二个推导式符合第三条规则,E的后面是终结符),故将)加入到FOLLOW(E)中
我们接着求FOLLOW(E'),我们可以发现推导式右部含有E'的推导式有E->TE',故符合第二条规则,将FOLLOW(E) 加入到FOLLOW(E')
接着求FOLLOW(T),我们可以发现推导式T'->T|ε,故符合第二条规则,将FOLLOW(T')加入到FOLLOW(T)。以此类推
直接上图
(4)计算SELECT集
先上计算方法
第一步,我们要根据推导之前的FRIST集来求推导以后的FRIST集,推导方法和之前求FRIST集是一样的
第二步根据每一个推导式来求出其对应的SELECT集,计算方法在上面已给出
第三步就是最终的判断了
如果每一个推导式经过推导其对应的SELECT集的交集为空,其为LL(1)文法。