编译原理2024期末复习(面向做题,大题速学)【太原理工大学】

本篇文章所覆盖的题目类型都是根据老师给的复习PPT提炼出来的,真实有效。

并且老师说了今年题型(10个选择题,5个填空,剩下都是大题),所以这篇文章应该对大家对于大题的学习与复习有一定帮助!

本篇文章题目顺序是根据课本顺序走的,方便大家查找!


1.给出文法写出字符串的推导

这一题是比较简单的,根据给的字符串进行推导。

知识点:VN:代表非终结符(就是可以推导出其他符号)VT:代表终结符(就是无法推导出其他符号,比如小写字母a,0.....)

答案


 这一道题是让通过最左推导和最右推导来推导,所以要先知道这两个推导是什么?

知识点:最右推导是规范推导,最左归约是规范规约(两者正好互为逆过程)  。   

做题思路:

       最左推导就是每次推导时先将最左边的非终结符进行替换。就比如下面这道题的最左推导答案中(T,S)的下一步推导时是先将T->S,而不是将S->(T)。同理最右推导就是每次推导时先将最右边的非终结符进行替换。就比如下面这道题的最右推导答案中(T,S)的下一步推导时是先将S->(T),而不是将T->S。

答案


2.给出文法写出符合的句子

知识点:给了文法可以确定唯一的语言。给了语言可以确定文法,但不确定唯一文法。

就是给了文法,写出的语言是唯一的。给了语言可以写出多个能推出该语言的文法。

还有就是句子是不包含非终结符的,是由终结符组成的。句型中可以包含非终结符。

所以说:句子肯定是句型,句型不一定是句子。

答案

 3.消除文法左递归

知识点:消除左递归分为两种类型,一种是消除直接左递归就像(A->Ab)这种。一种是间接左递归就像(S->Ab,A->S)这种,通过多步来达到S->S这种效果。

做题思路:

        消除直接左递归的话,假设非终结符A的规则为A'->Aα / b。其中,b是不以A开头的符号串。那么,我们可以把A的规则改写为如下的非直接左递归形式: A'->bA’   A’'->αA’ / ε。就比如上面第一张照片中的A直接左递归了,所以这一条文法就可以改成A->BA'   A'->vBA'/ε,B也同理。

        消除间接左递归的话,就是先将间接左递归的文法转换为直接左递归在消除。比如上面的第二张照片,S是间接左递归了,我们可以先将这个文法转换为S的直接左递归在进行消除。那么一步可能不好直接写出,我们可以先把A的写出来A->Sab/ab/b,然后再写S的S->Sabc/abc/bc/c,这样就写出了S的直接递归式,再按照直接递归的方法消除就好了!

答案


4.证明文法二义性 

做题思路:

        就是通过构建该文法能推出的一条句子的两个语法树,若是有两个不同的语法树能表达出这一条句子,那么证明该文法是二义性的。
         构建语法树思路:如果有对称的非终结符(如上图的EAE),那么就是左边的非终结符构建一次,右边的非终结符构建一次,看能不能成功。如果没有对称的非终结符(比如第二张图),那么就是含有非终结符的句型一上一下构建语法树,看能不能成功构建两个描述同一句子的语法树。

 答案


5.给出语言写文法

做题思路:

        先将给出的语言转化成没有终结符的句子,根据句子来构建文法。(我感觉相对简单一些)

答案:


6.已知(正则)文法画出状态转换图 

做题思路:

        我做这个题喜欢从右往左推的画。从起始状态出发,先看哪个状态可以通过一个终结符来推出来(本题是A状态可以通过终结符a一步推出来,所以先画这一步),将第一个状态画出来后在从这个状态出发往前推(将A状态推出来后,根据文法可以看出A状态在经过a可以推出它自身,所以在用一个箭头指向自己上面写上a,这样A就完全推完了)。一个状态推完后,在从这个推出来的状态出发推上面没有推出来的状态,也是从右边出发往左推。Z状态就不写了,一样的。

答案


7.通过正则表达式识别语言,构造正则文法

做题思路:

        语言就是先写固定的,本道题结尾是固定的所以先写结尾的组成,再写不确定位置的组成字符串。

        正则表达式构造其等价的正则文法,我做题的思路是:先将固定的(000)表达出来,最后只剩下不确定的((0|1)*)在表达,如下面答案:

答案

 C的推导也可以写成C->C0|C1|ε  (0|1)可省略


8.NFA->DFA,并化简DFA,并分析符号串(重点)

知识点:NFA是不确定的有穷自动机,DFA是确定的有穷自动机。两者的区别是:NFA的一个状态通过一个终结符可能前往多个状态,而DFA的一个状态通过一个终结符只可能前往一个状态。

                化简的意思就是DFA的多个状态通过相同的终结符前往的状态是一样的,所以这几个状态可以合并(比如S1状态通过a可以前往状态S2(它只有这一个状态去向),S0状态通过a可以前往状态S2(它也只有这一个状态去向),所以他俩可以合并)

8.1 提供了NFA的状态转换图

 做题思路:

        先画出每个状态通过不同的终结符能够到达哪一个状态,(因为DFA每一个状态通过一个终结符只能到达一个状态,而NFA可能达到多个状态(知识点里面说了)所以NFA到达的状态汇总看成一个状态),然后根据画的图画出状态转换图(此时的状态转换图可能需要化简,不是最终的)。(终结状态是包含原先终结状态的状态)化简的话比较简单,先将非终结状态和终结状态分开,先看非终结状态集合中的每个状态通过不同的终结符能达到哪个状态,如果达到的状态不属于这个集合中的状态,那么该状态分离出该集合,证明该状态不能合并。以此类推,如果有几个状态通过相同的终结符到达相同的状态,那么这几个状态就可以合并了。

答案


8.2正则表达式构造DFA

知识点:正则表达式转换成状态转换图有两种正则表达式的构建。

一种是*,一种是+(+多一个状态)

 做题思路:

        先将正则表达式转换成状态转换图,就变成和8.1相同的了,后面步骤就一样了


8.3告知NFA表达式求DFA,并分析符号串

做题思路:

        通过它提供的NFA表达式中的M可以画出那个(每个状态通过不同的终结符能够到达哪一个状态)的图,通过倒数两项可以得知起始符号和终结符号,就可以画出未化简的DFA状态转换图了,接着按上面化简的步骤走就行了。

        识别字符串就是从初始状态出发,开始一个一个看,能否通过输入串余留部分的首字母到达新的状态。如果输入串每个字母都能的话证明符号串能被接收。

答案:

那个做的时候发现题目有错误,所以没做,其实前面步骤做法是一样的,所以就看识别符号串那块的答案就行了(抱歉了)


 9.求FIRST集和FOLLOW集

做题思路:

        求first集就是看推导式的右边的首字母,如果首字母是终结符,那么该非终结符的first集就是它(S->aB  FIRST(S)={a})。如果首字母是非终结符,并且该非终结符无法推出ε,那么first集就是该终结符的first集(S->Aa A->bB  FIRST(S)=FIRST(A)={b})。如果首字母是非终结符,并且该非终结符能够推出ε,那么first集就是该终结符的first集并上下一个符号的first集(S->ABc  A->a|ε B->b|ε  FIRST(S)=FIRST(A)∪FIRST(B)∪FIRST(c)={a,b,c}

        求follow集就是看该字母右边的东西,如果求的是开始符号,在follow集中要加入#,如果后面跟的是终结符,那么将后面跟的加入到follow集中(S->Aa FOLLOW(A)={s})。如何后面跟的是非终结符,将该非终结符的first集加入到follow集里(S->AC FOLLOW(A)=FIRST(C)),如果后面没东西了,或者后面有东西,但这个东西可以推出ε。将->左边字母的fllow集加入到Follow集中(S->aA,或者S->aAC C->ε 将follow(B)加入到follow(A)的集合中

 答案


10.根据文法求LL(1)文法,构造LL(1)分析表,并分析符号串

 知识点:要先将文法消除左递归(方法在上面有,可以自己在看一下)

                LL(1)分析表中的R表示重读(意思是没匹配)

                LL(1)分析表中的C表示继续读(意思是匹配上了,可以继续)

 做题思路:

        先将文法消除左递归,得到的文法就是LL(1)文法,在构建LL(1)分析表之前,要先将每个推导式的select集求出来。求select集其实就是求first集和follow集,我原本是先将每个非终结符的first集和follow集求出来在求select集,发现速度有点慢,不如直接求select集,遇到哪个first集和follow集再求,节省时间。

        select集的求解就是看->右边首字母的first集,如果该首字母能够推导出ε,那么需要将->左边的follow集求出来,并在一起。如图:

        当每条推导式的select集求出来时,就可以 构建LL(1)分析表了,表的第一行是该文法出现的终结符+#,第一列是非终结符+每个推导式->右边没有出现在首字母位置的终结符+#。里面的填法也比较简单,就是看每一个推导式的select集推导出了哪个终结符,就在哪个终结符对应的位置写上->右边的倒序,如果能够消除该终结符那么就将->右边的推导式消除该终结符写上去再写上/R,如果没有消除该终结符那么就将->右边的推导式原封不动写上去再写上/C。像第一列中的终结符就在对于的位置写上ε/C,#那块写succ(固定的)。这样LL(1)分析表就完成了

答案

 补充一个分析符号串的题(和上面不是一道题)(这个比较简单,看图应该就会了哇(不是不想写了))


 11.求句型的短语,简单短语,素短语,句柄

知识点:我的理解:短语(一个完整(子)树的叶子结点) 

                                (直接)简单短语(只有两层的(子)树的叶子结点)

                                素短语(至少有一个终结符,并且除它自身外不包含更小的素短语)

                                句柄(最左边的简单短语)

 做题思路:

        我觉得先将短语求出来,在看其他的求解比较好。

 答案     

主要是我写的字太丑太乱了,不好意思发出去了 。(污染眼睛了)


 12.算符优先算法求FIRSTVT,LASTVT,构造优先关系表,判断是否为算符优先文法并分析输入串

知识点:FIRSTVT,LASTVT求解

 做题思路:

        FIRSTVT的求解:若->右边以终结符开头,就将该终结符写入FIRSTVT(A->a FIRSTVT(A)={a})。若->右边以非终结符开头,就将该非终结符的FIRSTVT写入FIRSTVT(A->BCa FIRSTVT(A)=FIRSTVT(B))。若->右边以非终结符开头跟着终结符,就将该终结符写入FIRSTVT(A->Ba FIRSTVT(A)=FIRSTVT(B)∪a)。
        LASTVT的求解也同理,若->右边以终结符结尾,就将该终结符写入LASTVT(A->a LASTVT(A)={a})。若->右边以非终结符结尾,就将该非终结符的LASTVT写入LASTVT(A->aBC LASTVT(A)=LASTVT(C))。若->右边以非终结符结尾前面跟着终结符,就将该终结符写入LASTVT(A->aBLASTVT(A)=LASTVT(B)∪a)。

        接着就可以通过如下条件,得出终结符之间的优先级。

         而#与其他的终结符之间的优先级可以通过#起始状态#得出。同样使用上面的规则得出。
  接着就通过得到的终结符之间的优先级关系构造优先关系表

        就是这种形式的表。 

        在构建完优先关系表后,1.先看给的文法->右边有没有两个非终结符相邻的情况,如果没有则为算符文法。2.接着看任意两个终结符之间是否只有唯一优先关系,如果是的话则该文法为算符优先文法。

        接着进行输入串分析,要注意的是,分析的过程中会出现归约成非终结符的情况,这种情况下,判断优先级的时候忽略该非终结符,用它前面的终结符进行判断优先级,只有又要归约的时候在带上它。如下图的第五行(不是dang看A与1的优先级关系,A也没有,是看它前面的0)什么情况下需要归约呢?当判断优先级关系为>时需要,因为出现>时说明该终结符需要比输入串中比较的终结符先归约才行。归约几位是看什么时候出现<(如第四行,*的优先级>1,*需要归约了,接着看*前面的终结符与*比较优先集,若0的优先级=*的优先级那么说明他俩的优先级一样,应该一块归约,就接着比较前面的终结符*与0的优先级关系,直到出现<,那么将<与>之间的字母归约)


13.简单优先文法 

知识点:判断该文法是否为简单优先文法,只需要看任何产生式->右边相同吗,都不相同则为简单优先文法。

                简单优先文法的判断优先级比较简单,并且优先级之间比较不仅包含终结符,还包含非终结符。

                #小于所有符号,所有符号大于#

做题思路:

        优先级比较:相邻就是= ,<就是若遇到的第一个字母为非终结符就一直往下套最左边的。

>就是若遇到的最后一个字母为非终结符就一直往下套最右边的。剩下的步骤和算符优先文化一样。


14.已知文法求LR(0)分析表,并分析输入串 

知识点:在求项目集规范族前要想将文法拓广(就是加一句S'->S(首符号))。

 做题思路:

        先将拓广后的文法标号,在写项目集规范族。从初始状态S0开始,从第一条语句开始写,现将->右边首字母前面写一个△,后继符号就是小三角后面紧挨着的那个符号。后继状态就是S1,以此类推S2,S3......。如果△后面是一个非终结符,我们就需要把以该非终结符做为开始符号的所有句子都写进当前项目集中,如下图1:(将S,C,D的所有开头的句子引进来了,注意如果有两个后继符号是相同的非终结符的话,只需要引一次该非终结符到项目集中就行)如下图2:(引一次A就行了,不然成死循环了)

注意:相同状态里,后继符号一样,后继状态一样(不管句子以及△的位置)。

        不同状态里,后继符号一样,只有句子完全一样(包括△),后继状态才一样,不然后继状态按顺序+1     

当状态S0执行完成后,接着执行S1,将S0里面的后继状态为S1的句子△往后挪一位,接着写后继符号和后继状态,如果后继符号是非终结符的话,接着将该非终结符开头的句子引进来,要注意引进来的句子,不管前面有没有出现过,△要放在->右边首字母前面,重新开始,后继状态根据注意里写的判断的写。直到执行到当△到了末尾的时候表明该句子结束了,后继符号那里写#该句子(没有△)接着下面重复上面操作,直到后继状态全部写到了,才结束项目集规范族的书写!

一个完整的项目集规范族如下:

接着就可以画LR(0)分析表了,该表也是根据上面求的项目集规范族来画,有了项目集规范族就特别好求。首先表头由三部分组成(状态,ACTION,GOTO)。状态那块会写上面规范族写出来的所有状态,ACTION那块会将该文法的所有终结符+#写上去,GOTO那块会将该文法的所有非终结符写那块(不包括拓广写的S')。每一个状态对应的怎么添呢?返回到规范族去看,如果后继符号是终结符,就将后继状态写到ACTION对应终结符那块。如果后继符号是非终结符,就将后继状态写到GOTO对应非终结符那块(将S去掉写,只留数字)。如果后继符号是#句子,就将该条句子对应的序号(前面拓广文法后标号了)写到ACTION里面那一行r+对应序号。如图(对应上面的规范族):

这样分析表就写完了!

接着就可以分析输入串了

 这里就不分析了,我也不会讲了(笑哭),需要注意的是归约操作,移进操作一看就懂了就不说了,归约操作那块我举个例子大家就明白了。比如第六行(图上标号还错了,错了)那块看S5遇到0是归约操作,根据分析表可以得出,归约到句子6(B->1),所以ACTION那块写r6,那么GOTO到哪了是这样看的,因为是归约一位,归约到B,所以往前看一个状态,看S6遇到B是到哪,根据分析表S6GOTO(B)是3,所以那块添3,下面一行状态那,消去一位状态(从右往左看)加入GOTO后的状态S3,然后接着往后比对,剩下的就一样了。


15.区别LR(0)与SLR(1)

知识点:SLR(1)的项目集规范族存在两个冲突。“归约-移进”冲突,“归约-归约”冲突

                “归约-移进”冲突就是在项目集规范族一个状态中一个△在最后,一个△后面是小写字母(终结符)

                “归约-归约”冲突就是在项目集规范族一个状态中两个△在最后

并且冲突要能解决才是SLR(1)文法

“归约-移进”冲突解决方法就是 △后面是终结符的求first(△后面的),△在最后的求follow(->左边的非终结符),然后两者如果没有交集的话,就是冲突可以解决。

“归约-归约”冲突解决方法就是求follow(->左边的非终结符),然后两者如果没有交集的话,就是冲突可以解决。如下图:


 写到这里已经是从图书馆下午3点写到了晚上9点多了,战斗力已经不行了,剩下的三元式,四元式,逆波兰式以及代码优化,等我第二天在写吧!要是本篇文章对大家有一点点帮助的话,给俺点个赞吧,谢谢啦!要是我写的哪些有问题可以评论区告我,我改一改,谢谢大家了。咱们下篇见!

《编译》——复习资料,可适用于课程学习资料、期末复习资料、自主学习资料等等,复习资料共218页,内容丰富,干货十足! 主要内容包括: 一、概述 1 1.1 课程介绍 1 1.2 编译过程 3 1.3 高级语言程序简介 11 二、程序语言概论 14 2.1 程序语言的定义 14 2.2 文法的形式化定义和分类 18 2.3 文法和语言 22 2.4 语法分析树 29 三、词法分析_1 33 3.1 词法分析概述 33 3.2 词法分析程序的设计 38 3.3 正规式与自动机 41 3.3.1 正规式与正规集 41 3.3.2 确定有限自动机(DFA) 44 3.3.3 非确定有限自动机(NFA) 49 3.4 单元测试 51 四、词汇分析_2 52 4.1正则式和有限自动机的等价 52 五、词法分析_3 59 5.1 DFA的化简 59 六、词法分析_4 62 6.1 词法分析器的自动生成 62 6.2 词法分析程序实现实例 64 七、语法分析—自上而下分析_1 71 7.1 词法分析简介 71 7.2 自顶向下分析简介 73 7.3 消除左递归和回溯 76 八、语法分析—自上而下分析_2 80 8.1 LL(1)分析法 80 8.2 FIRST集和FOLLOW集的构造 82 8.3 单元测试 85 九、语法分析—自上而下分析_3 86 9.1 LL(1)分析表的构造 86 9.2 递归子程序的原理 89 9.3 单元测试 95 十、语法分析—自下而上分析_1 96 10.1 自下而上分析方法的基本思想 96 10.2 分析树与规范规约 99 10.3 符号栈的使用 103 10.4 单元测试 105 十一、语法分析—自下而上分析_2 106 11.1 算符优先文法 106 11.2 优先表构造 109 11.3 算符优先分析算法 112 10.4 单元测试 115 十二、语法分析—自下而上分析_3 116 12.1 LR分析器 116 12.2 LR分析过程 119 12.3 单元测试 132 十三、语法分析—自下而上分析_4 133 13.1 构造识别前缀的DFA 133 13.2 LR(0)项目集规范族构造 140 13.3 由DFA构造LR(0)分析表 146 13.4 单元测试 150 十六、属性文法和语法翻译制导 151 16.1 L-属性文法和自顶向下翻译 151 16.2 自下而上计算继承属性 159 十七、语义分析和中间代码产生_1 166 17.1 语义分析的任务 166 17.2 中间代码的生成 168 17.3 算术表达式和赋值语句 175 17.4 单元测试 178 十八、语义分析和中间代码产生_2 179 18.1 布尔表达式的作用和文法描述 179 18.2 做控制用布尔表达式的翻译(回填) 181 18.3 控制流语句的翻译 186 18.4 控制流语句的翻译(回填) 189 十九、代码优化_1 194 19.1 什么是代码优化 194 19.2 基本块及流图 199 19.3 单元测试 202 二十、代码优化_2 203 20.1 基本块的DAG表示及其作用 203 二十一、重要知识点 213 1. 考试内容及分数分布 213 2. 名词解释 214 3. 简答题 215 4. 结语 216
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村口下棋刘师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值