编译原理学习导论

编译原理学习导论 php

 

大学课程为何要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,彷佛和计算机的基础领域不沾边,可是编译原理却一直做为大学本科的必修课程,同一时候也成为了研究生入学考试的必考内容。编译原理及技术从本质上来说就是一个算法问题而已,固然由于这个问题十分复杂,其解决算法也相对复杂。咱们学的数据结构与算法分析也是讲算法的,只是讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比較专一解决一种的算法了。在20世纪50年代,编译器的编写一直被以为是十分困难的事情,第一Fortran的编译器听说花了18年的时间才完毕。在人们尝试编写编译器的同一时候,诞生了不少跟编译相关的理论和技术,而这些理论和技术比一个实际的编译器自己价值更大。就宛如数学家们在解决著名的哥德巴赫猜测同样,尽管没有终于解决这个问题,可是其间诞生很多名著的相关数论。算法

 

推荐參考书 数据结构

尽管编译理论发展到今天,已经有了比較成熟的部分,但是做为一个大学生来讲,要本身写出一个像Turboc C,Java那样的编译器来讲仍是太难了。不只写编译器困难,学习编译原理这门课程也比較困难。函数

正是因为编译原理学习相对困难,那么就要求有好的教师和好的教材。教师方面不是咱们能本身更改的,而在教材方面咱们却可以按本身的意愿来阅读。我如下推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材,因为在国内的教材中,确实还没发现什么让人惬意的。工具

 

第一本书的原名叫《Compilers Principles,Techniques,and Tools,另一个响亮的名字就是龙书。缘由是这本书的封面上有条红色的龙,也因为这本书在编译原理基础领域确实太有名气了,因此很是多国外的学者都直接取名为龙书。近期机械工业出版社已经出版了此书的中文版,名字就叫《编译原理》。该书出的比較早,大概是在8586年编写完毕的,做者之中的一个仍是著名的贝尔实验室的科学家。里面解说的核心编译原理至今都没有变过,因此一直到今天,它的价值都非凡。这本书最大的特色就是一開始就经过一个实际的小样例,把编译原理的大体内容罗列出来,让很是多编译原理的刚開始学习的人很是快内心有了个底,也知道为何会有这些理论,怎么运用这些理论。而这一点是我感受国内的教材缺少的东西,因此国内的教材都不是写给愿意自学的读者,总之让人看了半天,殊不知道里面的东西有什么用。学习

第二本书的原名叫《Modern Compiler Design,中文名字叫作《现代编译程序设计》。该书由人民邮电出版社所出。此书比較关注的是编译原理的实践,书中给出了很多的实际程序代码,还有很是多实际的编译技术问题等等。此书另一个特色就是其“现代”而字。在传统的编译原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这种解释运行语言是在近几年才流行起来的东西。假设你想深刻学习编译原理的理论知识,那么你确定得看前面那本龙书,假设你想本身动手作一个先进的编译器,那么你得看这本《现代编译程序设计》。flex

第三本书就是很是多国内的编译原理学者都推荐的那本《编译原理及实践》。也许是这本书引入国内比較早吧,我记得我是在高中就买了这本书,只是也是在前段时间才把整本书看完。此书做为新手教程也的确是个不错的选择。书中给出的编译原理解说也至关仔细,尽管不如前面的龙书那么深刻,但是很是多地方都是点到为止,做为大学本科教学已是十分深刻了。该书的特色就是注重实践,只是感受还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点仍是在原理上的实践,而非前面那本那样的技术实践。《编译原理及实践》在解说编译原理的各个部分的同一时候,也在逐步实践一个现代的编译器Tiny C.等你把整本书看完,差点儿相同本身也可以写一个Tiny C了。做者还对LexYacc这两个常用的编译相关的工具进行了很是具体的说明,这一点也是很是难在国内的教材中看到的。优化

 

推荐了这三本教材,都有英文版和中文版的。很是多英文好的同窗仅仅喜欢看原版的书,不个人感受是这三本书的翻译都很是不错,没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。spa

 

编译原理的实质 操作系统

前面已经说过,学习编译原理事实上也就是学习算法而已,没什么特别的。仅仅只是这些算法的产生已经造成了一套理论。如下我来看看编译原理里面究竟有什么高深的理论吧。

 

差点儿每本编译原理的教材都是分红词法分析,语法分析(LL算法,递归降低算法,LR算法),语义分析,执行时环境,中间代码,代码生成,代码优化这些部分。事实上现在很是多编译原理的教材都是依照85,86出版的那本龙书来安排教学内容的,因此那本龙书的内容格式差点儿成了现在编译原理教材的定式,包含国内的教材也是如此。通常来讲,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比較偏重于前面几个部分。像代码优化那部分东西,就像个无底洞同样,假设要认真讲,就是单独开一个学期的课也不可能讲得清楚。因此,通常对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。

 

词法分析相对来讲比較简单。多是词法分析程序自己实现起来很是easy吧,很是多没有学过编译原理的人也相同可以写出各类各样的词法分析程序。只是编译原理在解说词法分析的时候,重点把正則表達式和本身主动机原理加了进来,而后以一种十分标准的方式来解说词法分析程序的产生。这种作法道理很是明显,就是要让词法分析从程序上升到理论的地步。

 

语法分析部分就比較麻烦一点了。现在通常有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很是多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。事实上这些东西都是仅仅要你们理解就可以了,又不是像词法分析那样非得本身写出来才算真正的会。像LR算法的语法分析器,通常都是用工具Yacc来生成,实践中全然没有比較本身来实现。对于LL算法中特殊的递归降低算法,因为事实上践十分简单,那么就应该要求每个学生都能本身写。固然,现在也有很多好的LL算法的语法分析器,只是要是换在非C平台,比方Java,Delphi,你不能运用YACC工具了,那么你就仅仅有本身来写语法分析器。

 

等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析究竟有什么?”就从编译器的角度来说,编译器需要把程序猿写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是经过词法分析和语法分析的。事实上词法分析并非一開始就被列入编译器的必备部分,仅仅是咱们为了简化语法分析的过程,就把词法分析这样的繁琐的工做单独提取出来,就成了现在的词法分析部分。除了编译器部分,在其余地方,词法分析和语法分析也是实用的。比方咱们在DOS,Unix,Linux下输入命令的时候,程序怎样分析你输入的命令形式,这也是简单的应用。总之,这两部分的工做就是把不“规则”的文本信息转换成一种比較好分析优势理的数据结构。那么为何编译原理的教程都终于把要分析的源分析转换成“树”这样的数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特色。但是Tree这样的结构有很是强的递归性,也就是说咱们可以把Tree的不论什么结点Node提取出来后,它依然是一颗完整的Tree。这一点符合咱们现在编译原理分析的形式语言,比方咱们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很是直观地表示在Tree这样的数据结构上。相同,咱们在运行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,咱们可以依据分析出来的抽象语法树,很是easy,很是机械地运用递归遍历抽象语法树就可以生成这样的指令代码。而这样的代码事实上也被普遍运用在其余的解释型语言中。像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。

 

关于语义分析,语法制导翻译,类型检查等等部分,事实上都是一种无缺前面获得的抽象语法树的过程。比方说,咱们写C语言程序的时候,都知道,假设把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是经过这一步的类型检查。像C++语言这中支持多态函数的语言,这部分要处理的问题就不少其它更复杂了。大部编译原理的教材在这部分都是解说一些比較好的处理策略而已。因为新的问题老是在发生,旧的办法不见得足够解决。

 

原本说,做为一个编译器,起做用的部分就是用户输入的源程序到终于的代码生成。但是在解说终于代码生成的时候,又不得不解说机器执行环境等内容。因为假设你不知道机器是怎么执行终于代码的,那么你固然没法知道怎样生成合适的终于代码。这部份内容我自我感受其意义甚至超过了编译原理自己。因为它会把一个计算机的程序的执行过程都统统排在你面前,你未来可能不会从事编译器的开发工做,但是仅仅要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。执行时环境的解说会让你更清楚一个计算机程序是怎么存储,怎么装载,怎么执行的。关于部分的内容,我强烈建议你们看看龙书上的解说,做者从最主要的存储组织,存储分配策略,非局部名字的訪问,參数传递,符号表到动态存储分配(malloc,new)都做了十分具体的说明。这些东西都是咱们编写寻常程序的时候经常要作的事情,但是咱们却少去探求其内部是怎样完毕。

 

关于中间代码生成,代码生成,代码优化部分的内容就实在很差说了。国内很是多教材到了这部分都会很是简单地蜻蜓点水讲过去,学生听了也仅仅是做为了解,不知道怎样运用。只是这部份内容的东西假设要认真讲,单独开一学期的课程都讲不完。在《编译原理及实践》的书上,对于这部分的解说就恰到优势。做者主要解说的仍是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很是easy模仿,本身下来后就可以写本身的代码生成。固然,对于其余代码生成技术,代码优化技术的解说就十分简单了。假设要细致研究代码生成技术,事实上另外还有本叫作《Advance Compiler Desgin and Implement,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。只是这本书我没有把它列为推荐书给你们,毕竟能把龙书的内容搞清楚,在中国已经就算很是不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中仍是一个不过重要的部分,就是算是实践过程当中,相信你们也不太运用获得。毕竟,本身作的编译器能正确生成运行代码已经很是不错了,还谈什么优化呢?

 

关于实践

编译原理的课程毕竟还仅仅是解说原理的课程,不是专门的编译技术课程。这两门课程是有很是大的差异的。编译技术更关注实际的编写编译器过程当中运用到的技术,而原理的课关注解说其基本理论。但是计算机科学自己就是一门实践性很是强的课程,假设能够学以至用,那才叫真正的学会。李阳在解说疯狂英语的时候就说到,仅仅要当你会实际中运用一个单词一个词组的时候你才干叫学会了这个单词或者词组,而不是仅仅是知道了它的拼写和意思。事实上不论什么学习都是同样的,假设缺乏了实践的结合,你不能算学会。

 

编译原理的课程主要就是解说编译器产生的理论和原理,那么很是easy,本身写个编译器就是最好的实践过程了。只是你得当心,编译系统多是所有软件系统中最复杂的系统之中的一个,否则为何大学里面还会把编译器的编写开成一门叫作编译原理的课程来说?我很是佩服那些学了操做系统原理就開始本身写操做系统,学了编译原理就開始本身写编译器的人们,确实,在中国,敢这么作的学生太少了。且不管你这样作能不能作成功,至少有了这个尝试,会让你的程序设计,系统规划安排的功底增进很多。我如下给出一些关于实践过程当中可能会遇到的困难,但愿能够在你陷入困境的前帮你一把。

 

1.       LexYacc. 这两工具是做为词法分析很是语法分析的工具。假设你本身写一个编译器,我十分不建议你连词法分析这样的事情都亲手来写。LexYacc应该是做为每本编译原理的教材的必备内容,可是在国内的教材中缺很是少看到。这两个工具是Unix系统下的小东西,假设你要在Windows中运用,那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东,里面就包括了flex.exebison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(事实上unix 下的很是多十分实用的工具都是这样), 只是在《编译原理与实践》这本书上对于这两个工具的解说十分具体,还列举了很多实际的样例。

2.       作解释型语言比作生成机器代码的编译器简单。尽管说,作解释型的编译器,像Java那样的,你还得本身去写解释器,只是这样你就没必要去查找机器代码的资料了。假设你作生成的终于机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过,假设你生成的是以堆栈为基础的代码,那么其代码生成过程十分简单,需要考虑的东西也很少,假设你考虑终于的机器代码生成的话,你必须考虑机器的寄存器怎样分配等麻烦的问题。

3.       考虑用别人已经生成的语法文件,尽可能不要本身动手写词法文件和语法文件.之前一个朋友之前说过,写出一个好的程序语言的语法定义,就差点儿完毕了一个编译器的一半.确实是这样,语法文件的编写是个很是难的事情.现在网上处处都可以找到比方C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你全然可以本身下下来来用.

 

在《编译原理及实践》的书中,做者给出了一个Tiny C的全部代码.我自我感受做者的这个编译器作得很是不错,相对于其余php,perl等语言的源码来讲,简单得多,easy看懂,而且很是清晰地展示了一个完毕的编译系统的实现过程.其源码可以在做者的站点上下载.

 

后话

编译原理的学习可能算是一个困难的历程,特别是对于那些不正确编译系统感兴趣的同窗来讲.既然它已经做为了大学本科的必修课程,那么就说明的它引伸出来的一套理论在整个计算机科学领域仍是占有相对重要的地位.

假设咱们考究一下历史,就会发现很是多被称为程序设计大师的人都是编译领域的高手.写出第一个微型机上执行的Basic语言的比尔盖茨,设计出DelphiBorland世界上最厉害的程序猿”, SunJAVA之父, 贝尔实验室的C++之父

相关文章
相关标签/搜索