ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

西安交大2022编译原理作业题:考点全覆盖的复习地图

西安交大2022编译原理作业题:考点全覆盖的复习地图 简介2022年西安交通大学编译原理作业考核试题以选择题形式系统覆盖编译器构造各阶段核心考点面向高校计算机专业学生、考研复习者及自学者可用于课程自测、考前串讲和知识点查漏补缺。资源包内含1个docx文档大小约13KB文档内容紧凑便于随时打开练习。试卷具体涉及文法与句子推导、算符优先文法、程序基本块、无二义文法判断、符号表地址分配、Chomsky文法分类、LR(0)分析表动作、三元式中间代码、下推自动机识别上下文无关语言、LR分析活前缀、标记符作用域管理、语义规则定义程序意义、Pascal语言结构特点、静态分派等核心考点并配有逐题知识点解析帮助读者理解每个选项正确的依据与干扰项错因而非机械记忆答案。目前已有214人学习下载是巩固编译原理理论、熟悉高校客观题命题风格的一份实用资料。1. 西安交大2022编译原理作业题一份能当复习地图用的真题集做编译原理复习最怕的不是题目难而是不知道考点到底画在哪条线上。西安交通大学2022年这份作业考核试题共19道选择题覆盖面从文法推导、算符优先文法、无二义性判定一路压到符号表操作、中间代码生成、LR分析栈与目标代码生成几乎把编译原理三轮复习的主干考点全部按顺序串了一遍。对正在备考期末或者打算系统过一遍编译原理的人来说这份题的参考价值不在“标准答案”而在它暴露的命题视角哪些概念喜欢设陷阱哪些环节容易被想当然带偏。更难得的是题目全部带选项解析可以直接用来做自测、做考点归类、做错题复盘比一章章翻教材硬啃效率高很多。下文我按考点模块拆开讲每部分都给出判定思路和踩坑点最后附一份能落地的复习检查单。2. 文法与句子判定左递归候选式怎么选两步推导就能定位2.1 左递归文法判句子从起始符号开始穷举候选式推导链第1题给出文法G[S]S→S1|S0|Sa|Sc|a|b要求判断四个选项中哪个是该文法的句子。这道题命题重心不只在最终答案更在推导过程的起点选择。注意文法的产生式全是左递归形式每个候选项尾部追加一个终结符推导顺序天然就只能从S出发逐步向右扩展。选项C是a0b0a我验证时先取S→S0随后S→Sa再S→Sb最后S→a完整推导链是S⇒S0⇒Sa0⇒Sb a0⇒ab a0简化写成a0b0a正好覆盖所有符号。这道题实际考的是“句子”的定义所有终结符组成、且能由文法起始符号推导出来的符号串。能推出就是句子推不出就不是。判别时防御性做法是从S开始对每个候选式试一遍深度优先展开别看到长得像就选。选项Aab0无论怎么选左部都无法让a、b、0同时作为同一层候选式出现选项Dbc10直接以b开头看似可行但b→后无法再接c因为产生式中没有B或C这样的非终结符展开链中断。这里需要提醒的是左递归文法穷举时的顺序优先尝试与目标串前缀匹配度高的候选式例如目标串中间有连续0时优先走S→S0然后再回推前面剩余部分。手推时建议用表格记下每一步的已匹配前缀和剩余符号串能避免展开一步就忘掉前面推导方向。候选式推导链结论ab0S→Sa?→a?还需0候选式无法产生不是句子a0c01非终结符c无对应产生式链断裂不是句子a0b0aS⇒S0⇒Sa0⇒Sba0⇒aba0是句子bc10b是叶节点后续无产生式可接1不是句子2.2 算符优先文法的终结符对三种关系都成立才叫确定第2题给的是算符优先文法里终结符对a、b的三种可能性若 f(a)g(b) 则 ab、若 f(a)g(b) 则 ab、a~b 都不一定成立、a~b 一定成立。四个选型像绕口令但实质是在考算符优先分析表中终结符对的Even本质两个终结符之间的优先关系只有在能推出特定句型时才存在不是任意两个终结符都天然存在确定关系。终结符对的优先关系判定有一个易被忽略的前提必须存在某个规范句型使这两个终结符相邻出现否则它们之间根本不存在关系判定基础。选项B说“若 f(a)g(b)则 ab”是对的这体现的是算符优先文法中优先关系与移进归约动作的映射规则——栈顶终结符优先级低于当前输入符号时执行移进操作。实操层面构造算符优先表时我习惯先画一张二维表行是栈顶终结符列是当前输入终结符把每个产生式右部的每对相邻终结符包括夹着非终结符的邻接对全部标记出来再按“左优先于右归约右优先于左移进”填表。填完再检查是否每个终结符对至多存在一种优先关系如果出现一个格子同时有两种关系就说明文法不满足算符优先条件。提示处理这类题时先把关系符号、、~映射成移进、归约、错误三种动作再反向印证结论比死记 f(a)g(b) 的数学表达式稳妥。2.3 无二义文法的语法树最左推导和最右推导为什么必然同树第4题核心是“无二义文法的任何句子最左推导与最右推导对应的语法树必然相同”。很多学生初看时容易绕进“最左和最右推导序列都不同语法树怎么可能一样”的误区。实际上推导序列不同不代表语法树不同同一棵语法树既可以通过最左重写非终结符得到也可以通过最右重写非终结符得到区别只有非终结符的展开顺序树的层级和叶子排列完全一致。无二义性的严格定义是“一个句子只有一个最左推导”也等价于“只有一个最右推导”还等价于“只有一棵语法树”。这三个判定条件互相绑定一旦文法无二义任一句子对应的语法树就是唯一的。做题时不要盯着推导序列里的符号顺序而要只看树的结构根节点是起始符号每棵子树的叶子顺序恰好等于句子中的终结符序列若排序唯一则结论成立。验证时我给一个简单的操作建议先把句子的最左推导完整写出来每步只展开最左侧非终结符再写最右推导每步只展开最右侧非终结符。最后把两个推导中非终结符的展开位置对齐到同一棵树上如果树的层级结构一致就判无二义。这道题里B、C、D分别对应“可能不同”“必然不同”“存在两个最左推导但树相同”全部违反无二义文法的必要条件只有A成立。3. LR分析法与基本块分析栈存的是活前缀不是句柄ACTION表有冗余信息3.1 基本块的边界一个入口一个出口的极大顺序程序段第3题考程序基本块正确选项是“一组顺序执行的程序段仅有一个入口和一个出口”。这里注意题干里“顺序执行”这个限定词它说明块内部不允许出现跳转指令或分支入口否则块边界会被切断。基本块是程序流图中最小的分析单元四元式、三元式的优化都以基本块为操作对象。划分基本块的常用做法是先找入口语句程序第一条语句、条件转移或无条件转移的目标语句、紧跟在条件转移之后的语句都是入口。找到入口后从每个入口语句开始向下收集语句直到遇到下一个入口或程序结束。这时候会碰到一个常见误区把“只有一个入口一个出口”理解成“不能有函数调用”。函数调用语句在基本块中是允许的只要调用点是块内顺序执行的普通语句就行因此第3题选项A一种子程序和C一种没有嵌套的程序段都错在边界条件描述不完整。用一页纸就能把这个考点做完整验证拿到任意程序代码先标记入口语句再按入口划分区间统计每个区间内跳转指令的数量。跳转指令数为0的区间就是候选基本块最后检查这些区间合并后是否还能保持单一入口单一出口能则合并为更大基本块。3.2 LR(0) 的ACTION子表一行出现rj时整行应该是什么状态第7题问的是LR(0)分析表的ACTION子表中某一行存在标记“rj”的栏时其他栏的状况。正确项是“该行必然填满rj”。理由是LR(0)分析基于规约项的“归约状态”某个状态对应一个完成的项目集它在任何输入符号下都会执行同一归约动作所以这一整行的ACTION全部是rj表现为全部填满该归约动作的编号。这题容易做错的地方在于混淆LR(0)与SLR(1)。SLR(1)用FOLLOW集消除了部分冲突ACTION表中遇到无效输入符号时填“错误”而LR(0)没有FOLLOW集过滤同一状态下所有符号一律看作用来归约的输入因此才出现“整行全填rj”的现象。理解这个差异对读分析表相当关键。做题时遇到这种题我建议画一张LR(0)项目集规范族草图重点观察每个项目集里是否存在“归约项目”圆点在最右端的项目与其他项目并存。如果并存就出现了移进-归约冲突而没有冲突的归约态在ACTION表里就是清一色的rj。确认“该行是否填满”之前先检查该状态是否只含唯一的归约项这是判断填表是否排他的最直接手段。表LR(0)表格中 ACTION 与 GOTO 的关系状态内容ACTION 表现GOTO 表现对应题目考查点移进项目对特定终结符填 s 状态号无状态栈跳转归约项目对所有终结符填 r 产生式号无本题 rj 栏接受项目对 # 填 acc无分析结束待约项目无对非终结符填状态号活前缀扩展3.3 规范句型活前缀状态栈存的不是句柄是可归约前缀的DFA状态第10题问LR分析栈中寄存的状态是识别规范句型什么的DFA状态正确项是“活前缀”。活前缀被定义为规范句型中不超过句柄右端的任何前缀识别活前缀的DFA每一个状态恰好对应分析栈里的一层状态。这是LR分析最核心的抽象分析栈里存的不是句子符号本身而是符号串映射成的状态序列每个状态代表一个活前缀集合的等价类。这里要区分三个概念句柄是当前应被归约的子串前缀可能包含句柄右端以后的符号活前缀则严格不允许越过句柄右端。分析栈中的状态栈之所以要使用活前缀对应的DFA状态是因为每移进一个符号新状态都携带了“从起始符号出发能推出当前栈内符号串”的全部信息归约时只需查表就能决定动作。如果栈里只存句柄机器无法判断后续符号串是否构成可归约的右部序列。复习这一块我有一个推荐的自测方法取一个简单文法比如E→ET|T从空栈开始手工逐步写出“当前栈内符号输入剩余串”以及每步的ACTION动作连续做10步再和标准LR分析过程对比。做过两遍之后活前缀、句柄、规范句型三者之间的边界就清楚了。3.4 静态层次与作用域编译器靠函数声明层次区分标识符第12题考编译程序用什么区分标识符作用域正确项是静态层次即“标识符所属的过程或函数的静态层次”。这个词容易和动态层次混淆。静态层次由程序文本中的嵌套结构决定过程A在过程B内部声明那么A的静态层次就低于B动态层次则由调用关系决定递归调用时同一个过程会出现在多层动态层次上。现代语言要么靠符号表嵌套、要么靠display表记录当前活跃过程的静态层次链。作用域链的查找顺序是从内层到外层一旦内层声明遮蔽外层同名标识符查找就在内层命中。做题时要记住作用域规则的两大基础是“声明位置决定静态作用域”和“调用现场决定动态作用域”编译期间信息全部来自静态文本因此只能使用静态层次。若选项中出现“动态层次”或“行号”优先排除。4. 中间代码与符号表三元式省的是临时变量登记Chomsky分类对应识别能力4.1 三元式的设计动机避免把临时变量塞进符号表第8题问使用三元式为了什么正确项是“避免把临时变量填入符号表”。三元式结构是(op, arg1, arg2)用三元式表的编号间接引用运算结果这样临时变量不需要名字也不需要占符号表条目。四元式则不同每个运算都有显式结果变量临时变量数量上去后符号表管理开销会明显加大。这道题从设计动机角度切入容易误选“便于代码优化”。实际三元式因为只保存位置引用删除或插入运算时需要同步修改后继引用编号对优化并不友好四元式的结果字段独立优化时替换运算结果更灵活。所以“便于代码优化”恰恰是四元式的优点不是三元式的。对比两种中间代码的存储与优化特性对比维度三元式四元式结果表示以三元式表编号引用显式临时变量名符号表压力小临时变量不入表大每个临时结果占条目代码改动成本高删除插入需改编号引用低结果字段独立替换优化友好性一般较友好做题时若题目同时出现“避免填入符号表”和“便于优化”选前者。后者是四元式要解决的诉求两者不能混为一谈。4.2 符号表四类操作与目标代码生成地址分配才是终点第5题与第14题成对出现都围绕符号表的定位。第5题问目标代码生成阶段符号表用于什么正确项是“地址分配”第14题问整个编译期间对符号表的操作大致有哪些正确项是“查询给定名字”。符号表在编译各阶段作用不同词法分析阶段登记新标识符语法语义分析阶段反复查询和更新类型信息代码生成阶段则根据变量作用域和生命周期分配内存偏移。四类操作——填入新名字、查询给定名字、访问给定名字的信息、更新给定名字的信息——并非每阶段都全部发生。比如词法阶段只做“填入”和“查询是否已登记”语义检查阶段做“访问类型信息”代码生成阶段做“更新地址信息”汇编器与链接器再根据这些地址分配记录生成机器码。题目中把四个操作全部列出选“查询给定名字”是因为这是贯穿所有阶段的公共操作最符合题干“大体均有”的语义。复习这个考点时建议用一棵属性栈或者一张表把每个编译阶段对符号表的读写动作列出来阶段名、读操作、写操作、典型数据。这样再看题目选项时会很清楚哪些操作在某阶段会出现、哪些不会。4.3 Chomsky四种文法与自动机对应正规文法叫3型不是2型第6题和9专门考形式语言分类。Chomsky把文法分成0型短语结构文法、1型上下文有关文法、2型上下文无关文法、3型正规文法。题目中的陷阱在于“ 2型也称正规文法”正规文法正确说法是3型文法2型对应的是上下文无关文法。对应的自动机识别能力逐级递增3型文法产生正则语言被有限自动机DFA/NFA识别2型文法产生上下文无关语言被下推自动机PDA识别1型文法产生上下文有关语言被线性有界自动机识别0型文法产生递归可枚举语言需图灵机识别。第9题选“下推自动机”因为上下文无关语言的识别器就是PDANFA/DFA只够识别正规文法图灵机对应0型文法。背下这张对应表能直接套用所有这类题目文法类型名称产生式约束识别自动机0型短语结构文法无约束图灵机1型上下文有关文法左部长度≤右部长度线性有界自动机2型上下文无关文法左部为单个非终结符下推自动机3型正规文法右部至多一个非终结符有限自动机4.4 静态分配与语言特性Pascal的嵌套定义难点在过程本身第15题和第19题一组考语言特性对编译策略的影响。第15题正确项是Pascal没有分程序构造、过程定义不允许嵌套。这里有个容易翻车的地方——题面最后一个条件写着“允许过程嵌套定义”很多人看到“嵌套”就选C实际正确选项选中的是“过程定义不允许嵌套”“但允许过程嵌套定义”这组矛盾描述中的后者才对应Pascal特性。C语言过程定义不允许嵌套是对的但C允许分程序结构块结构和“没有分程序构造”冲突。Fortran既没有分程序构造过程定义也不允许嵌套但Fortran过程定义位置有严格规定不属于允许嵌套的范畴。“嵌套定义”和“嵌套调用”不是一回事。Pascal允许过程A内嵌套定义过程BB可以调用A这是静态嵌套作用域的典型特征。第19题的静态分配与此配套静态分配允许程序出现静态变量不支持可变体积的数据项目动态数组、变长字符串在编译期无法确定大小和递归过程递归需要动态栈帧分配。配套记忆静态分配存储布局固定编译器在编译期就确定所有变量偏移量动态分配允许递归和可变数据代价是运行期管理活动记录。题目里两个表述绑定出现看到“静态分配允许”后面接“可变体积数据项目”就直接判错。5. 避坑指南这五道题最容易翻车每条都是血泪经验5.1 把2型文法当正规文法Chomsky编号与名称错位现象看到“2型文法也称正规文法”的选项直接判对结果丢分。原因2型对应上下文无关文法正规文法在Chomsky体系里编号是3型。教材常见表格里“上下文无关文法”和“正规文法”上下相邻闭卷默写时很容易把编号与名称错位记忆。解决建立“类型编号—文法名—产生式约束—识别自动机”四列映射表默写时从产生式约束倒推类型编号例如“左部必须单个非终结符”必然对应2型。5.2 三元式“便于代码优化”的想当然现象看见三元式就联想到优化未仔细读选项就选了“便于代码优化处理”。原因日常讨论中间代码优化时四元式更常见结果把四元式优点挂到三元式头上。解决先看选项里是否有“避免把临时变量填入符号表”有则优先选它。复盘时把三元式与四元式的结果表示差异写一遍三元式用编号引用结果四元式用显式临时变量名。5.3 活前缀与规范句型前缀混为一谈现象第10题在“前缀”和“活前缀”两个选项之间犹豫最后凭直觉选错。原因活前缀限定“不超过句柄右端”而“前缀”概念没有这个边界泛泛理解成任何形式前缀就会误选。解决记住一句判定口诀“活前缀止于句柄右端”再看状态栈里每个状态对应的栈符号串是否满足该条件。不满足的就不是活前缀。5.4 LR(0)与SLR(1)的ACTION表混淆现象认为某行存在rj后其他格子可能填错误或移进动作于是选“该行未填满rj”。原因把SLR(1)中FOLLOW集过滤后的填表逻辑套用到LR(0)上忽略了LR(0)无前瞻信息的特点。解决回归定义LR(0)归约项目在遇到任何终结符时都执行归约表中该行自然全填rj。若某行既有rj又有其他动作那叫移进-归约冲突语法已不是LR(0)文法。5.5 Pascal“过程定义不允许嵌套”与“允许嵌套定义”的题干矛盾现象被题干前后两句“不允许”和“允许”绕晕直接选C语言。原因没分清“过程定义”与“过程调用”的嵌套以及C语言还有分程序结构这一事实。解决拆句翻译——没有分程序构造无块结构过程定义不允许嵌套不能在函数体内定义函数允许过程嵌套定义其实是允许嵌套调用。后两项合起来正好锁定Pascal。做题时遇到矛盾描述先写成三行拆分再找哪个语言全部匹配。6. 把真题改成自测表四步定位你的编译原理薄弱点真题的价值不只在做对而在做错之后能快速映射回教材的哪个章节。我建议把19道题按考点重组成一张六列自测表题号、考点主题、对应教材章节、初始答案、错误类型、动作项。列完再按下面四步过一遍比反复刷同一套题有用得多。第一步按错题主题分组统计看错误集中在哪一类。若集中在文法判定类第1、2、4题说明语法分析基础概念有盲区若集中在LR分析类第7、10题说明分析表构造和理解不到位若集中在中间代码与符号表类说明后端流程梳理不够。第二步把每道错题的选项逐条改写成陈述句比如第5题的“符号表用于目标代码生成”改写成“符号表只服务代码生成环节”然后判断陈述句对错——这种处理能逼着你把模糊概念精确化。第三步每个错题补一道教材同类例题用同一种判定流程做两遍第一遍不翻笔记第二遍对照书上的推导步骤找出偏差。第四步把第2、7、10、15题这四道最易错的题当成必考题隔天重做一次连续两次全对再换组。我自己的教训是复习前两周只刷题不归类错的知识点一直是散的做完这张映射表之后发现LR分析栈相关的错因其实集中在一个误解上——总把状态栈当成符号存储后来改造成“状态栈是活前缀DFA状态的序列”这个理解之后相关题再没错过。从那以后我每次复习编译原理都强制走一遍“归类—改写选项—补同类题—隔天重测”的流程也希望帮到你顺着这套流程把编译原理的考点骨架搭起来。本文还有配套的精品资源点击获取
返回列表