目录
第二种求LL(1)文法的方式(用公式)
第一课: 《编译原理求语法树的短语和直接短语等等》
二义性是什么?
如果最左推导和最右推导的结果不一致,那么说明文法有二义性
短语是什么?
找短语就是找能长叶子的结点,有五个如图圆圈标号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如果都能去到相同的地方那就归为一类。