编译原理心得编译原理是计算机及相关专业的一门重要专业课程,在计算机科学中有很重要的地位和作用,已被国内外高校列为计算机专业的主要课程。
它主要介绍了高级程序设计语言编译程序构造的一般原理、基本设计方法、主要实现技术和一些自动构造工具。
通过该课程的学习,对提高学生计算机软件素质,使学生真正认识计算机信息处理实质并综合运用所学的软件设计技术来分析问题等具有很大作用。
该课程理论性与实践性都很强,我们在学习是普遍感到内容非常抽象,不易理解,内容多且繁琐,难以完整、全面地掌握编译原理的有关知识,更不用说灵活运用编译原理知识从事相关设计或应用于其他领域。
虽然只有少数人从事编译方面的工作,但是这门课在理论、技术、方法上都对我们提供了系统而有效的训练,有利于提高软件人员的素质和能力。
采用有用的资助手段增强课堂教学效果。
基于Internet网络和多媒体技能,资助手段有种种千般的情势,可以借用有:讨论学习模式、探索学习模式、提供种种资源库的网上资助教学应用模式。
在Internet上实现讨论学习的要领有多种,最简略实用的是使用现有的电子通告牌体系(BBS),这种体系具有用户管理、讨论管理、文章讨论、实时讨论,用户留言、电子信件等诸多功效。
编译原理在学习历程,门生题目难点不能逐一与老师举行面临面举行,那末议决网络,可以题目果然,老师创建相应的主题,门生可以在自己学习的特定地域发言,门生之间可以举行交换,全部的题目都果然化。
探索学习模式。
这种模式一样平常都是由某些教诲机构设立一些适当特定门生工具的题目,议决Internet向门生公布,要求门生解答;同时提供大量的、与题目相干的信息资源供门生在解决题目历程中查阅。
这种模式彻底转变了传统教学历程中门生被动继承的状态,而使门生处于积极自动的职位地方,因而能有用地引发门生的学习兴趣和创造性。
在我们学习编译原理以前,都认为编译原理只能应用在写程序语言的编译器上,觉得用处不大,学习兴趣不高。
而在后来的学习中,我们逐渐认识到计算机专业的学生,除了要会编写程序语言之外,还应该了解它是如何被计算机所识别,这才是真正并且透彻地学习软件。
另外,编译器中每一个模块的编写,都能对我们的编程能力的提高有很大帮助。
在今后若从事软件工程,这门课程也能够对编写程序有所帮助。
为了能够系统掌握这门专业课,我们把编译原理分为以下几个模块:(1)语言和文法;(2)词法分析;(3)语法分析;(4)语义分析和中间代码生成;(5)代码优化和目标代码生成;(6)关于实践。
在学习的开始,我们需要掌握什么是编译,编译分为哪些阶段,编译程序和解释程序的区别等等。
在做好了这些方面的准备后,开始了系统的学习。
语言和文法语言和文法部分的知识包括文法基本概念及文法的二义性。
基本概念有文法定义、推导、句型、句子等等。
二义性文法是通过画语法树的方法来证明。
词法分析词法分析相对来说比较简单。
可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。
不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。
这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。
词法分析中的重点是有穷自动机DFA的生成以及DFA和正规式与正规文法的关系。
还要熟练掌握NFA转换为DFA的方法及DFA的化简。
词法分析的核心应该是构建DFA,最后维护一个状态转移表。
通过转态转移的结果来识别词性。
DFA的思想和字典树很像。
NFA通过求每个状态的闭包后构造出的自动机与DFA 等价。
正则表达式闭包,连接,或三种操作都有相应的NFA与其等价。
所以正则表达式==NFA==DFA。
DFA状态最小化算法化简DFA。
LL(1)文法主要就是根据FIRST集判断向哪条路径走,来避免回溯;LR(0)文法构造项集闭包构成的自动机,通过有穷自动机的状态转换来判断该规约还是该移进来做出相应的操作并且更改堆栈和Buffer的状态,注意此时有可能发生移进规约冲突,并且如果不运用FOLLOW集的话有些出错状态无法识别,只能当规约处理。
SLR(0)文法是再LR(0)的基础上运用FOLLOW集来判断出错状态SLR(0)文法的无法处理移近规约冲突。
LR(1)文法是在LR(0)文法的基础上构建LR(0)的增广项集,其他与LR(0)相似,通过增广项集可以解决移近规约冲突问题,但无法解决部分规约规约冲突问题。
LALR貌似只是将LR文法中的一些等价状态合并构成一个更小的自动机,有点像DFA 状态最小化方法。
算符优先文法构造语法树的结构找到相应的优先级构成一个优先级表,两个栈,一个用来存OP一个用来存操作数,当两个算符相遇时判断两个算符的优先级,做出相应的操作:进栈或计算。
语法分析语法分析包括自上而下和自下而上分析。
自上而下分析着重掌握LL(1)文法,自下而上分析重点掌握算符优先文法和LR(0)、SLR(1)文法。
语法分析部分就比较麻烦一点了。
现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。
LL算法还好说,到了LR算法的时候,困难就来了。
很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。
其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。
像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。
对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。
当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用Y ACC 工具了,那么你就只有自己来写语法分析器。
等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析到底有什么?”就从编译器的角度来讲,编译器需要把程序员写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是通过词法分析和语法分析的。
其实词法分析并非一开始就被列入编译器的必备部分,只是我们为了简化语法分析的过程,就把词法分析这种繁琐的工作单独提取出来,就成了现在的词法分析部分。
除了编译器部分,在其它地方,词法分析和语法分析也是有用的。
比如我们在DOS,Unix,Linux下输入命令的时候,程序如何分析你输入的命令形式,这也是简单的应用。
总之,这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。
那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特点。
但是Tree这种结构有很强的递归性,也就是说我们可以把Tree的任何结点Node提取出来后,它依旧是一颗完整的Tree。
这一点符合我们现在编译原理分析的形式语言,比如我们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很直观地表示在Tree这种数据结构上。
同样,我们在执行形式语言的程序的时候也是如此的递归性。
在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,我们可以根据分析出来的抽象语法树,很容易,很机械地运用递归遍历抽象语法树就可以生成这种指令代码。
而这种代码其实也被广泛运用在其它的解释型语言中。
像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。
在学习文法时,对文法的组成,用法都较为明了,而在真正做题时却感到十分吃力。
例如给出了一个语言,要求写出它的上下文无关文法,就感到十分棘手,所以今后在这方面要加大练习量,以熟练掌握。
而在之后的词法分析和语法分析中,我感到在看基本原理时十分困难,通常要长时间钻研才能够有所了解,而一旦掌握了基本原理,做题时就感到十分顺畅了。
例如,在刚接触到LR(0)文法时,我用了大量的时间去学习它的原理,掌握之后,在列LR(0)分析表和写分析过程时,只要思路清晰,就会比较顺畅,而且不会犯错。
语义分析和中间代码生成关于语义分析,语法制导翻译,类型检查等等部分,其实都是一种完善前面得到的抽象语法树的过程。
比如说,我们写C语言程序的时候,都知道,如果把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是通过这一步的类型检查。
像C++语言这中支持多态函数的语言,这部分要处理的问题就更多更复杂了。
大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。
因为新的问题总是在发生,旧的办法不见得足够解决。
程序的语义就是它的“意思”,它与语法或结构不同。
程序的语义确定程序的运行,但是大多数的程序设计语言都具有在执行之前被确定而不易由语法表示和由分析程序分析的特征。
这些特征被称作静态语义(static semantic),而语义分析程序的任务就是分析这样的语义(程序的“动态”语义具有只有在程序执行时才能确定的特性,由于编译器不能执行程序,所以它不能由编译器来确定)。
一般的程序设计语言的典型静态语义包括声明和类型检查。
由语义分析程序计算的额外信息(诸如数据类型)被称为属性(attribute),它们通常是作为注释或“装饰”增加到树中(还可将属性添加到符号表中)。
在正运行的C表达式 a [index] = 4 + 2 中,该行分析之前收集的典型类型信息可能是:a是一个整型值的数组,它带有来自整型子范围的下标;index则是一个整型变量。
接着,语义分析程序将用所有的子表达式类型来标注语法树,并检查赋值是否使这些类型有意义了,如若没有,则声明一个类型匹配错误。
在上例中,所有的类型均有意义,有关语法树的语义分析结果可用以下注释了的树来表示。
语义分析重点是其功能,中间代码生成和语法制导翻译定义与方法。
关于中间代码生成,代码生成,代码优化部分的内容就实在不好说了。
国内很多教材到了这部分都会很简单地走马观花讲过去,学生听了也只是作为了解,不知道如何运用。
不过这部分内容的东西如果要认真讲,单独开一学期的课程都讲不完。
在《编译原理及实践》的书上,对于这部分的讲解就恰到好处。
作者主要讲解的还是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很容易模仿,自己下来后就可以写自己的代码生成。
当然,对于其它代码生成技术,代码优化技术的讲解就十分简单了。
如果要仔细研究代码生成技术,其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。
不过这本书我没有把它列为推荐书给大家,毕竟能把龙书的内容搞清楚,在中国已经就算很不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。