今天开始了编译原理的第一课,今天学习的内容是第一章和第二章,感觉书上讲的基本都是原理语法之类的,可以说难,也可以说不难,难就难在有关概念理解性上面没有一个实际的例子去分析,不难也就是在于很多都是原理之类的,可以看懂就过去了。
我看的是电子工业出版的《程序设计语言编译原理》,前两章的内容还可以,能看明白,就是第二章的上下文无关文法叫我反复看了两三遍,也算是理解了吧。回想一下自己以前使用高级语言开发的经历,不管是c语言、vb、c++还是java。好象只关心怎么学习语言的语法,然后在编译器上运行,如果成功了。就ok了。如果不成功了,根据提示的错误信息来调试修改等等。那时候没有考虑过为什么会出现语法错误,而编译器在编译的时候去做的什么样的工作,今天看了编译原理的前两章之后,开始思考了,根据以前编译调试的经验去理解书上所讲的内容,的确看的挺快的。
首先第一章刚开始就是考虑什么叫编译程序,记得使用c、c++、java编译器的时候,他们所做的工作应该是先对源代码进行翻译或解释,如果是翻译则是翻译成汇编或机器语言,如果是解释,则是把代码作为输入,不产生目标程序,边解释边执行代码本身。但是作为一个详细的过程而言,以前就没有考虑了,今天看了第一章的讲解才明白编译程序一般在编译的过程中会执行5个工作阶段:
1、词法分析:输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词。如基本字等等
2、语法分析:在词法分析的基础上,根据语言的语法规则,把单词符号串分解成各类的语法单元(语法范畴),通过语法分析,确定整个输入串是否构成语法上正确的“程序”
3、语义分析与中间代码生成:对语法分析所识别出的各类语法范畴,分析其含义,并进行初步的翻译生成中间代码,首先进行语义正确检查,其次再进行中间代码的翻译,
4、优化:对前段产生的中间代码进行加工变换,产生更高效的目标代码
5、目标代码生成:把中间代码变换成特定机器上的低级语言代码。
在编译过程中的五个工作阶段的同时还需要表格管理和出错处理两部分,首先表格管理是指在编译程序工作过程中需要保持一系列的表格,以登记程序的各类信息和编译各阶段的进展状况,其中最重要的是符号表,是用来登记源程序中出现的每个名字以及名字的各种属性,在编译的各阶段都会有构造、查找或更新有关的表格。其次是出错处理,当在编译的过程中,源程序出现错误的情况下,编译器应该把有关错误报告显示出来。
概念上编译程序划分为编译前端和编译后端。前端主要由与源代码有关,但与目标机无关的部分组成,通常包括语法分析、词法分析、语义分析与中间代码生成,后端包括编译程序中与目标机有关的代码优化和目标代码生成等。通常后端不依赖于源语言而依赖于中间语言。在这一点上,java的平台无关性就可以好理解了,java定义了一种虚拟机代码,只要实际使用的操作平台实现了执行虚拟机的解释器,那么这个平台就可以执行各种java程序。同样.net中也是这个原理,把vb,c#等语言先编译成中间语言,然后仅仅对中间语言进行编译成机器语言也是靠这一点实现。
以上是第一章的内容,第二章主要是概述高级语言的语法规则,这一节最重要的一点就是在于上下文无关文法,所谓的文法就是指描述语言的语法结构的形式规则, 那么上下文无关文法就是说:它所定义的语法范畴是完全独立于这种范畴可能出现的环境的。这样的解释不好理解,网上查到可以用如下的解释去理解:
在计算机科学中,一个形式文法 G = (N, Σ, P, S) 称之为上下文无关的,如果它的产生式规则都取如下的形式:V -> w ,这里 V∈N ,w∈(N∪Σ)* 。上下文无关文法取名为“上下文无关”的原因就是因为字符 V 总可以被字串 w 自由替换,而无需考虑字符 V 出现的上下文。(V:非终结符号,w:终结符号)
终结符号也就是组成语言的基本符号,非终结符号用来表示语法范畴,如算术表达式,过程等等,开始符号是一个特殊的非终结符号,它所代表的语言中我们最感兴趣的语法范畴,是由其他的语法范畴组合起来的。产生式是定义语法范畴的一个书写规则,形式如:A-->a。
上下文无关文法定义一个语言的思想是:从文法的开始符号出发,反复连续使用产生式,对非终结符号施行替换和展开,直至全部为终结符号为止。