ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

编译原理期末复习攻略:把握词法、语法与代码生成核心考点

编译原理期末复习攻略:把握词法、语法与代码生成核心考点 简介这是一份编译原理课程的期末考试真题及答案解析面向计算机、软件工程等专业本科生也适用于考研复习或自学后检验知识掌握程度的人群。整个压缩包内只有1个pdf文档大小约386KB体积小巧便于快速下载阅读。试卷内容覆盖词法分析、语法分析、语义分析与中间代码生成、代码优化、目标代码生成等编译全过程核心章节题型包括填空题、单选题、多选题和解答题并提供对应参考答案与判定思路。内容预览显示试题涉及LL(1)文法改造、FIRST集与FOLLOW集构造、算符优先关系表与优先函数、语法制导翻译及四元式生成、循环语句翻译等高频考点题目设置与常规期末考试风格接近适合考前集中刷题、查漏补缺也有助于理解自顶向下与自底向上分析、属性文法及中间代码生成等难点。目前已有455人浏览学习可作编译原理课程备考的实用参考。1. 期末题不是用来“背答案”的先想清楚这份 PDF 该怎么用期末题和答案这类资料大学里几乎人手一份但真正用对的没几个。大多数人拿到《编译原理期末考试题及答案.pdf》第一反应就是往后翻答案——看到某个构造题能看懂心里觉得“这题我会了”。结果上了考场换一个文法、换一个表达式当场卡住。编译原理的试卷有个显著特点计算题和构造题占大头画 NFA、填预测分析表、写四元式每一步都靠规则推导不是靠记忆复现。对着答案背出来的只是“这题看懂了”的错觉而不是“这类题会做”。这份 PDF 真正的价值是帮你把考点分布、常见题型和评分习惯摊开来看然后从错题反推每一章到底学到位没有。它是批改标准不是背诵素材。适合的人群也很明确期末备考的学生、准备补考的人、考研复试前想快速捡起基础的同学。2. 编译原理期末考什么从题型分布反推核心考点大部分学校的编译原理卷子结构很固定选择填空覆盖全册词法、语法、中间代码各出一道大题符号表和运行环境穿插在小题里。拿到题和答案后不要急着逐题看先把卷子按题型过一遍你会发现考点的权重非常集中。题型覆盖章节常见分值占比高频考点选择填空全册 符号表20%30%文法分类、短语、推导树词法大题词法分析15%20%正则式转 NFA、NFA 转 DFA、DFA 最小化语法大题语法分析30%40%LL(1)、LR(0)、SLR(1) 分析表语义与中间代码语法制导翻译10%15%四元式、属性标注运行环境与优化符号表、代码优化5%10%作用域、基本块划分从分值安排能看出一个规律语法分析是绝对核心词法分析是必拿分的基础中间代码考察动手能力符号表则安静地藏在各种小题里。下面把每个大块的关键考点拆开说。2.1 词法分析与正则表达式小题多但最怕一步错全盘崩词法分析这一章期末卷里通常以两种形态出现选择题考正则式的运算符优先级和闭包性质大题让你写一个正则式对应的 NFA再用子集构造法转 DFA最后做最小化。复习重点放在三个地方正则式的运算符优先级括号高于闭包*连接高于选择|、NFA 转 DFA 的子集构造法、DFA 最小化的划分法。子集构造法的关键不是把表填出来而是每次处理状态集时先求当前集合的ε-闭包再按读入字符求move后再次取闭包。我见过太多同学直接忽略 ε-闭包导致同一个 DFA 状态被拆成两行画出来的图状态数暴增最后和参考答案怎么都对不上。更现实的损失是阅卷扣分NFA 转 DFA 的过程题评分点通常盯在“是否处理 ε-边”上漏了闭包中间步骤分直接丢一半。另一个常被忽略的分数点是 DFA 最小化。题目如果明确写了“构造 DFA 并最小化”你只画完 DFA 不做最小化就会白白丢掉最后一步的分。最小化的操作本身不复杂先把状态分成终态集和非终态集然后反复检查每个集合中状态在同一个输入符号下是否转移到同一个集合不一致就拆分。最后得到的分区就是最小化 DFA 的状态集。这个步骤在卷面上通常值 3 到 4 分性价比很高。2.2 上下文无关文法与 LL(1) 分析推导树和 First/Follow 集必考语法分析占期末卷的比例最高也是最容易拉开差距的地方。LL(1) 分析大题的完整流程是固定的先检查文法是否有左递归有则消除然后算 First 集和 Follow 集再构造预测分析表最后给出一个输入串的预测分析过程。四个环节里翻车率最高的是 First 集和 Follow 集。First 集的计算要顺着产生式右部递归产生式右部的第一个符号是终结符就把该终结符加入第一个符号是非终结符就把它的 First 集内容加进来同时如果这个非终结符能推出空串还要继续看右部的下一个符号。Follow 集则要倒过来看产生式右部中某个非终结符后面跟了什么如果后面是终结符直接加入如果后面是非终结符加入它的 First 集去掉 ε如果后面的符号序列能推出 ε还要加上产生式左部非终结符的 Follow 集。最容易错的就是这里——很多人把 Follow 往“左部”传而不是往“紧跟其后的符号”传。消除左递归也是个固定的拉分点。直接左递归形如A - Aα | β改写为等价的A - βA和A - αA | ε就行。但期末考试有时会故意出间接左递归比如A - B a和B - A b你要先把B的产生式代入A还原出A - A b a后再消。只背直接左递归公式的同学在这里就会卡住。没有左递归的文法才能谈 LL(1)所以做题第一步永远是检查左递归。2.3 LR 分析与算符优先能力分水岭通常在大题里LR 分析是期末卷里最有“含金量”的部分。常见考法是给一个表达式文法要求构造 LR(0) 项目集规范族写出 SLR(1) 分析表然后模拟一个输入串的分析过程。项目集规范族是这部分的核心分两步闭包和转移。闭包的含义是如果项目集中某个项目的圆点后面是一个非终结符就要把这个非终结符的所有产生式都变成新项目加进集合并反复执行直到没有新项目出现。转移则是把圆点向后移动一个符号生成新的项目集。画项目集时最怕重复制造相同的集合生成一个新集后一定要和已有集合逐项比对相同就合并引用而不是另起编号。很多同学画到第四个集合就开始乱根源就是没做“去重”导致分析表里的状态编号对不上。如果题目标明“构造 SLR(1) 分析表”填表规则比 LR(0) 多一步归约项的填写不是在所有输入符号下都归约而是只在左部非终结符的 Follow 集中出现的输入符号下归约。这个区别往往是题目的核心考点答案里也会专门体现。做这类题时先算一遍所有非终结符的 Follow 集再开始填 ACTION 表顺序不能反。2.4 语法制导翻译与中间代码四元式怎么写才给分中间代码部分期末大题通常有两种出法一是给出语法制导定义让你对某条语句标注属性值二是直接让你把表达式或控制流语句翻译成四元式、三元式或三地址码。这里有一个非常现实的评分细节——不同学校对四元式的写法有固定格式要求。四元式的标准形式是(op, arg1, arg2, result)但运算符助记符可能要求写成Add、Sub、Jmp也可能允许写成、-、goto。如果你手里的答案 PDF 来自本校就照答案里的写法模仿如果只找到外校的卷子就先按教材或讲义的格式统一整理再做题。评卷时格式不一致即使逻辑对也可能被扣掉 1 到 2 分。生成四元式时一条硬规则是每个运算都生成一个新的临时变量。表达式a b * c至少要两个临时变量一个存b * c一个存它与a的和。条件语句if x y goto L要生成一个跳转四元式并把目标地址L留到回头再填。这种“回填”操作在语法制导翻译里讲过考试时会要求你在答案里体现出来。复习这部分最好的练习题就是把教材第五章的课后题逐条翻译成四元式然后和答案比对临时变量的编号规则。2.5 符号表与运行环境容易被忽略的得分点符号表内容在卷子里分值不高但出现频率很高。填空题爱问“符号表存放哪些属性”简答题爱问“静态作用域和动态作用域的区别”。两个高频考点符号表的组织方式线性表、散列表、树和符号表在编译各阶段的作用。符号表最容易被混淆的地方是把“关键字表”和“符号表”当成一回事。词法分析识别关键字用的是固定表而编译期维护的符号表存的是标识符的属性如名字、类型、作用域、存储地址含义完全不同。用符号表相关的选择题练一遍这个点能记得很牢。如果用的是王生原《编译原理第 3 版》第三章课后题里有不少符号表的练习它可以补一补期末卷上覆盖不到的部分而且和期末考试题往往考法接近。2.6 代码优化与基本块性价比最高的基础概念题代码优化在期末卷里一般不会出特别难的算法题常考的是基本块划分和几种常见优化方法。基本块划分的规则很容易记住基本块的入口是第一个语句或跳转目标语句入口到下一个入口之间的语句构成一个块如果中间遇到跳转或停机当前块到此结束。大题如果给你一段三地址码要求划分基本块并画程序流图只要按入口规则逐行切分就行这是全卷最好拿的分。简答题常考“优化需要遵循什么原则”只答“提高运行效率”是不够的必须答出“不改变程序语义”或“保持等价性”。这个点今年在不少试卷的简答里反复出现值得单独记一次。3. 用期末题反推复习路径拿到 PDF 后的三步走知道考什么以后接下来就是怎么用这份 PDF 组织复习。很多人把题和答案从头到尾看一遍就算复习完这很低效。我建议按三步走先限时做一遍对答案打标签再把错题映射回教材和实验课。3.1 第一步先限时做一遍不翻答案拿到题和答案后第一件事是把答案部分遮住或单独放一边按考试状态做题。限时不是随便掐个表而是按正式考试时长的 70% 到 80% 来。如果卷面写着 120 分钟就给自己 90 分钟题量大就按 100 分钟。为什么要压缩时间因为真正上考场时审题、犹豫、涂卡都会额外花时间平时比实际更紧考场才不会慌。做题时所有过程都要落在纸上画 DFA、填预测分析表、写 LR 项目集、列出四元式一步都不能只在大脑里过。不要怕错就怕不写。草稿纸上的错误过程是后面最重要的复习素材——它能直接暴露你卡在哪个环节。比如词法那道题你可能 NFA 画对了DFA 转错了草稿上的代码和集合操作会告诉你问题出在“没有取 ε-闭包”而不是“不会子集构造法”。时间分配上也有讲究。选择填空控制在 20 分钟内词法和中间代码各 20 分钟语法大题最多 40 分钟剩下 10 分钟检查。如果某道大题 10 分钟完全没有思路直接跳过先把符号表和基本块的题做掉。那些分值的性价比远高于死磕一道 LR 大题。3.2 第二步对答案时给每个错题打标签对答案不是简单地画勾叉。我的习惯是给每道错题打标签格式是“章节 知识点 错误类型”。错误类型分四类规则不熟、计算失误、题目没读懂、步骤不完整。它们对应的复习策略完全不同。规则不熟的比如“不知道归约时要查 Follow 集”需要回教材重新推导对应算法计算失误的比如 First 集里漏了一个终结符重算两三遍同类型题就能纠正题目没读懂的多半是术语理解有偏差需要先补概念再补题步骤不完整的则是没按标准流程写照着答案的分步结构模仿一遍。标签字段示例章节语法分析知识点SLR(1) 归约条件错误类型规则不熟再练动作重做课后题 3.20再限时重做一次本题打完标签后统计一下哪类错误最多。如果“规则不熟”占了一半说明你复习时看多练少如果“题目没读懂”很多建议先把讲义里的术语表过一遍。这个统计能帮你把有限的复习时间从“平均用力”改成“专攻弱点”。3.3 第三步把错题对应回教材章节和实验课打完标签最后一步是把错题映射回你手头的教材。如果用王生原《编译原理第 3 版》第三章课后题对应 LL(1) 和 LR 分析第五章对应中间代码。找到每道错题的知识点所在章节再从课后题里挑两到三题同类型的做一遍。这样错题就从“一份卷子上的偶然失误”变成了“某个知识点的系统补强”。如果你的课有配套的编译原理实验这一章知识点会理解得更深。很多学校的实验覆盖了词法分析程序、LL(1) 分析程序、表达式求值和符号表管理。实验代码里其实就是期末题的“运行版本”。考前把实验源码快速看一遍比翻 PPT 效率高很多。看过词法分析实验的同学再做 NFA 转 DFA 的大题脑子里会浮现状态集合的迭代过程正确率明显高一些。Java 背景的同学可以额外做一个动作把实验里的表达式求值器扩展成带括号的四则运算翻译器。Java 的类型系统和对象表结构能帮你把语法制导翻译里的“属性”和“作用域”理解得很直观这部分知识在后续考试里经常和中间代码大题结合出题。3.4 复习时间分配的参数一份六天倒推表如果你的复习时间还有六天左右可以按下面的参数倒推天数内容对应卷面题型第 1-2 天词法分析 LL(1)填空、词法大题、语法小题第 3 天LR 项目集与分析表语法大题第 4 天中间代码 符号表语义大题、简答题第 5 天基本块优化 重做错题填空、程序流图题第 6 天整套卷限时重做一遍全卷如果实验课内容扎实词法分析部分可以直接从第 1 天里压缩把时间挪给 LR。反过来如果实验几乎没写词法和 LL(1) 就要多分配半天因为上机写代码本身就是对这两章的理解训练。这张表的目的不是让你照抄而是告诉你任何一份往年题都应该被拆解到六天计划里去而不是“考前一天看一遍答案”。4. 避坑指南做题对答案时的五条血泪经验把往届学生最容易踩的坑集中写在这里。每一条都是“现象 → 原因 → 解决”的三段式看起来琐碎但每一个都对应真实的失分。4.1 First/Follow 集算错导致整张 LL(1) 分析表全崩现象填预测分析表时发现同一个格子出现两个产生式于是判定该文法不是 LL(1)但你自己觉得整个流程都没问题。原因多半是 First 集算到一半遇到A - B C且B能推空串时忘了把C的 First 集并进来或者 Follow 集没把#加入开始符号的 Follow。还有一种是间接左递归没消除就开算结果 Follow 集越算越乱。解决重算时严格按顺序先消除左递归再算 First再算 Follow最后填表。算 First 时遇到可推空的非终结符一定要顺着右部继续往后看。算 Follow 时把所有可推空产生式列在旁边每处理一个右部符号串就检查后面符号的可空性。这个顺序一旦固定正确率会明显上升。4.2 NFA 转 DFA 时漏算 ε-闭包状态数对不上现象画出的 DFA 状态比参考答案多出两三个或者有些读入字符后的转移目标找不到。原因DFA 的每个状态是一个 NFA 状态集合而不是单个 NFA 状态。漏算 ε-闭包等于把“本来应该合并成一个集合的多个状态”拆成了多个不同状态。子集构造法里最常见的错误就是先做 move 再取闭包或者干脆不取闭包。解决强制自己按固定流程写拿到一个状态集先写ε-closure(...)再对每个输入符号求move然后对 move 结果再求一次ε-closure。每一步都写在表格里不要直接画图。最小化时用划分法得到的状态数和参考答案对不上时优先怀疑第二步漏了闭包。4.3 LR 项目集规范族画重了却不自知现象项目集规范族里出现两个内容完全相同的集合后面填表时出现冗余状态分析过程和参考答案对不上。原因生成项目集时只做了“转移”没做去重。每生成一个新项目集都要和已有集合逐项比较内容是相同的就应该引用已有编号而不是重复创建。解决项目集规范族编号按顺序递增每生成一个新集合先和前面所有集合比对项目列表。比对时看“项目内容是否完全一致”包括圆点位置。为了减少比对工作量可以按“圆点后的符号”做分组同一个符号转移出来的集合放在一起比较。另外别忘了对 I0 求闭包时要把所有产生式都展开漏一条也会导致后续连锁错误。4.4 四元式写得太简略被阅卷扣分现象参考答案的四元式有临时变量、有跳转占位自己写的直接操作原变量行数少了一截还觉得自己更简洁。原因没有按照语法制导定义一步一步生成临时变量。表达式a b * c直接写成(, a, b, t1)是错的——必须先算b * c存到t1再算a t1。条件语句如果不写跳转四元式整个控制流就断了后续基本块优化大题也无从下手。解决记住一条规则每个运算都生成新临时变量每个跳转目标都先留空再回填。做题时照答案的格式模仿参考答案里四元式如果写成(Add, a, b, t1)你就别写(, a, b, t1)。格式保持一致至少不会被扣“表达不规范”的分。4.5 符号表术语混用简答题越答越偏现象简答题问“符号表的作用”答成“记录关键字和操作符”。原因把词法分析里的固定表识表和编译期动态维护的符号表搞混了。关键字表在词法阶段就固定不变符号表则是从语法分析阶段开始创建并在语义分析和代码生成阶段不断补充内容。解决把概念分开记。符号表存的是标识符的属性比如名字、类型、作用域、存储地址关键字表只是词法分析器的内部工具。复习符号表这一章时我一般会额外关注两个点符号表的组织方式线性表、哈希表、树和重名标识符的作用域处理。这两个点正好是填空和简答的高频命题位置。4.6 只看答案不动笔最容易自我欺骗的复习方式现象一份 PDF 从头看到尾每个步骤都能看懂关上答案后自己拿空白纸一推导写不出完整的分析表。原因阅读答案时大脑平滑地理解了每一步的“结果”但并没有真正输出。编译原理的考试要的是输出能力填表、画图、生成四元式。只看不做练的是阅读理解不是解题能力。解决把 PDF 分成三次用。第一遍完全不看答案完整做一遍。第二遍对答案时用纸把参考答案抄一遍边抄边在旁边写“这一步是因为什么规则”。第三遍合上答案把错题重做一遍。三轮下来一道题才真正内化。如果时间紧至少保证错题过两轮。5. 把答案用起来给标准答案做二次加工才能变成自己的答案最大的浪费方式是“看懂了就翻页”。标准答案里藏着评卷时的得分点分布也藏着编写者的推导顺序。你需要做的是把答案从“别人写的”加工成“自己会讲的”。5.1 对照批注在每步推导旁边写“为什么”对答案时给每一步都加一条批注。比如预测分析表里某个格子填产生式A - α理由可能是“当前输入符属于 First(α)”四元式里某次跳转目标回填理由是“语句在语法树中的后继还未确定”。批注不需要长几个关键词就行。批注写完你会发现自己对“规则”的理解比“题目”更深一层。题目是具体的规则是通用的。下次遇到另一道语法分析题你不再需要回忆这道题怎么做而是直接用这条规则推。这就是考题和答案的“二次加工”价值。5.2 把简答题答案压缩成口诀卡片编译原理简答题的答案大多有固定套路。比如“消除左递归的步骤”“DFA 最小化的步骤”“基本块划分的规则”。这些内容适合压缩成关键词串做成卡片形式。举个例子DFA 最小化可以压缩成划分 → 分裂 → 合并 → 重命名。LL(1) 分析流程压缩成消左递归 → 算 First → 算 Follow → 填表 → 模拟。每张卡片正面写问题背面写关键词串。考前十分钟翻一遍比看整页答案效率高。注意口诀卡片是帮你“回忆规则”不是让你背答案。真正理解规则的人看到“分裂”这个词能立刻说出来“等价类在某个输入符号下转移到不同类时需要拆分当前集合”没理解的人只能卡在词面上。所以制作卡片的过程本身就是复习——写关键词串的时候你得先想明白每一步到底在做什么。5.3 用符号表和中间代码串起知识网络不把各章当孤岛刷完题你会发现各章其实是一条流水线。词法分析把源程序变成单词序列语法分析把单词序列变成推导树语义分析和符号表给属性赋值中间代码生成把语法树变成四元式最后代码优化和生成在基本块上做文章。编译阶段主要输入主要输出期末对应题型词法分析源程序字符流单词符号正则式、NFA、DFA语法分析单词序列语法树、推导过程LL(1)、LR(0)、SLR(1)语义分析与符号表语法树 符号表属性标注、类型检查语法制导定义中间代码生成语法树四元式、三地址码中间代码大题代码优化与生成中间代码目标代码基本块、程序流图、优化方法把每道错题挂到这个表上能防止一种常见情况词法题错完去补词法语法题错完去补语法结果一段时间后发现之前的错误又犯了。真正的复习是纵向串联——做 LL(1) 分析题时你会用到符号表识别终结符和非终结符写四元式时你又需要知道临时变量的类型信息来自符号表。这张表也是你考前最后一天可用的自查清单。6. 考前一天我不刷题了十分钟“口述法”验证自己会不会考前一天再刷新题的收益很低还容易制造焦虑。我的做法是把错题集翻出来挑三到五道最典型的大题盖住答案做一件事对着空气把解题过程说一遍像给同学讲题一样。每道题十分钟先讲这道题用哪个规则再讲第一步做什么、第二步做什么一边讲一边在纸上写关键步骤。判断标准很简单——如果中间停顿超过二十秒或者讲着讲着说出“这里不太确定”这道题对应的知识点就是你明天早上要翻书确认的地方。口述能通顺讲完的题说明规则已经进入你的工作记忆讲不出来的地方就是你最后的复习抓手。这个习惯我是在实验课上养成的。当时没写代码的同学围着会写的同学问问的人学会了讲的人也更熟了。后来备考编译原理我直接把对着屏幕讲题当成最高效的自测方式。它逼着你在没有参考答案的情况下把推导过程完整走一遍专治“看着答案全会合上答案全忘”的毛病。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进