目录

第一课: 《编译原理求语法树的短语和直接短语等等》

第二课:《消除左递归消除回朔的方法》

第三课:《如何求First集和Follow集》

课上练习:《LL(1)文法》

第一种求LL(1)文法的方式(用SELECT集合)

第二种求LL(1)文法的方式(用公式)​​​​​​​

给出输入串的分析过程怎么写?

 第五课:《构建LR(0)分析表》

第六课:《SLR(1)分析表》

第六课:《 确定有限自动机(DFA) 》 


第一课: 《编译原理求语法树的短语和直接短语等等》

二义性是什么?

如果最左推导和最右推导的结果不一致,那么说明文法有二义性

短语是什么?

找短语就是找能长叶子的结点,有五个如图圆圈标号1 2 3 4 5

直接短语(简单短语):说简单点就是一个孩子一个爹,本题中的i

素短语:在短语中找,至少含有一个终结符,且不含其他更小素短语

例题:

画出语法树:

短语:就是非叶子结点生成的叶子结点。

直接短语就是:一个孩子一个爹,这里是S、a

句柄就是:在树最左边的直接短语,那就是S

第二课:《消除左递归消除回朔的方法》

消除左递归:

先将后面的B往前提,然后新建一个A‘,然后A’->除了A的所有往前移A‘/空串

如果不是本文法的则不是左递归,直接写即可。 

消除回溯:

含公共左因子a的提出来,然后给一个A‘,如果不含则不提。

 A‘->(除了公共因子a的所有)/(如果只有a就是空串)/(没有a的已经在上一部提出,不用再写)

例题:

 第一条为回溯,第二条为坐递归。答案为蓝色字体

第三课:《如何求First集和Follow集》

如何求FIRST集和FOLLOW集?

First集看的是产生式的左边,Follow集看的是产生式的右边。

FIRST集如何写?

看产生式的左边:1.如果是终结符就直接写 2.如果是非终结符就到该产生式中去找

 较为复杂的FIRST集的解决

FOLLOW集如何写?

看产生式的右边:有以下三步

(1) 若B后为空,则将产生式右边的FOLLOW(A)集加入FOLLOW(B)集

(2) 若B后不为空:

        后面跟着终结符:终结符直接加入FOLLOW(B)集中

        后面跟着非终结符:将非终结符的FIRST集加入FOLLOW(B)集中

        ⚠️如果跟着非终结符能推出的是空的话,那又回到了(1)的情况来解决

例题: 

课上练习:《LL(1)文法》

第一种求LL(1)文法的方式(用SELECT集合)

(1)根据FIRST集合和FOLLOW集合求出SELECT集

                - 具体方法是:

                - 如果不能推出空串,就用FIRST集;

                - 如果能推出空串就填FOLLOW集;

(2)如果每条推导式推出来的两个SELECT集没有交集,则是LL(1)文法

(3)写出LL(1)分析表

                -具体方法是:

                -如果推出的不是空集,将推导式填入对应FIRST集中的元素区域;

                -如果推出的是空集,则填入对应FOLLOW集合的元素区域;


第二种求LL(1)文法的方式(用公式)

怎么求LL(1)文法的分析表?

(1)消除左递归,消除回溯

(2)写出改造后的文法G'(A)

(3)写出FIRST集,FOLLOW集

(4)构造G‘(A)的LL(1)分析表

分析表的写法:

(1)FIRST集中能推出终结符的直接写入

(2)推导式如果可以推导出空串,就将对应FOLLOW集对应表中终结符讲推导式写入

如何判断是否为LL(1)文法?

我们要分析改造后的文法中G'(A)的产生式中能产生两项的式子。

如下,A产生a/B:

        如果B不是空串,且FIRST集不相交,则为LL(1)文法;

        如果B为空串,且FIRST(a)集与FOLLOW(A)不相交,则为LL(1)文法;

判断是否为LL(1)文法的例子:

改造文法:

判断过程:

两个产生式的B都是空串,所以比较公式为:

产生式右边第一项的FIRST集和产生式左边的FOLLOW集。

(1)对于A‘->AB1/空        比较FIRST(A)与FOLLOW(A')不相交✅

(2)对于B‘->bB'/空        比较FIRST(b)与FOLLOW(B')不相交✅

结论:

为LL(1)文法。


给出输入串的分析过程怎么写?

第一类题目(所用规则)

需要注意的:

当我们写了所用规则时,输入串就不动,只动分析栈;

当我们懂了分析栈时,输入串要动,不写所用规则;

第二类题目(当前输入符号)

给出输入串aad1#用上述的G'[A]改造后文法分析。

解题思路:

(1)注意是反着压入,每次用符号站最右边当前输入符号比较

(2)如果相同,则将输入串对应的最左符号消去

(3)如果不相同,则继续向下分析

​​​​​​​ ​​​​​​​​​​​​​​

 第五课:《构建LR(0)分析表》

试构造下述文法的LR(0)分析表?

(0)构建流程:

(1)首先将每一个推导式分开写出,并且标上序号

 (2)写出构造簇:将每个推导式前面加一个 · 符号

 (3)看其要经过一个什么符号,经过相同的放在一个框内

 (4)完成(3)后,如果后面的符号是非终结符,那就要将其对应的构造簇全部写下

 (5)如果是重复的情况,就直接指向对应的框即可

 (6)分析完I0分析I1直到全部分析完,如下画出DFA表。

如何画出ACTION GOTO表?

很简单哒!

当我们得出了上面的表,显然:

从I0经过一个E到达I1,将1写入表中。

从I0经过一个T到达I2,将2写入表中。

从I0经过一个(到达I3,将S3写入表中。(⚠️此时是终结符,我们需要写入的是S3)

 如果·符号在最后面,那就整行都填上,r(推导式结束标号)

 最终表:

第六课:《SLR(1)分析表》

试构造下述文法的SLR(1)分析表:

(1)根据文法,消除左递归,消除回溯,写出改造后的文法G‘[A]

(2)根据G'[A]画出DFA表

        ⚠️当·符号右边是一个非终结符,我们需要将其推导式再次写进框内

 (3)根据这个表来画ACTION GO图

        ⚠️与之前不同的是原来结束写r的那一行先不要写,把他的文法的FOLLOW集求出来

        ⚠️而后再在对应FOLLOW集中对应终结符的位置写上r2即可(就不用整行全写了)

如何确定其是一个SLR(1)的文法?

找出一个框内,点在结尾,并且点在终结符前。

判断 (此终结符)(点在结尾的推导式) 的 (左边的FOLLOW集)相交为空。

为空则为SLR(1)文法。

例题:

写出活前缀DFA:

每次移动·符号,如果后面是非总结符就将其构造簇全部加入。

判断是否为SLR(1)文法:

以上并没有一个框内,·在末尾,并且·不在末尾。所以不包含冲突,即为SLR(1)文法。

画出ACTION GOTO表:

终结符用S表示,非终结符用数字表示;

如果结束了,就用acc表示;

如果结束了,就去找FOLLOW(左侧元素),配合r填入表中;

第六课:《 确定有限自动机(DFA) 》 

DFA的状态转换图与状态转换矩阵

(1)状态转换图:

S0经过a去S1,S0经过b去S2,S1经过a去S1,S1经过b去S2...终态S2画两个圈

(2)状态转换矩阵:

列是三个状态,横是过程元素,f是映射关系,S0是初态,S2是终态

S0经过a去S1,S0经过b去S2,S1经过a去S1,S1经过b去S2

NFA的状态转换图与状态转换矩阵

状态转换图和DFA一样,只不过NFA有可能同时去多个状态

状态转换表也有可能写多个

NFA正则表达式

NFA转换规则 

例题:

⚠️正则闭包改写为克林闭包:R+ = RR*

DFA正则表达式

画出转换表:

第一行第一列的就是起始将空串合并

Ia就是I经过a能到达哪里

Ib就是I经过b能到达哪里

然后将没出现过的Ia、Ib向下挪

 转换矩阵:将对应集合标号即可

DFA:根据转换矩阵画出DFA表

⚠️转换矩阵中含有Y的表明是终态

化简完后:

化简规则:输入a和b如果都能去到相同的地方那就归为一类。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐