一个编译器的结构

编译器主要有两个部分构成的,一个是分析部分,一个是综合部分。

分析部分(analysis)

分析部分吧源程序分解成多个组成要素,并在这些要素之上加上语法结构。其实最主要就是对代码进行检查,看看有没有错。没有错的话就会把各种信息存放在一个叫做符号表(symbol table)的数据结构中,符号表和中间表示形式一起传送给综合部分。

综合部分(synthesis)

这时候综合部分根据符号表和中间表示形式的信息来构造用户期待的目标程序。

一个编译器的步骤

(字节流)->词法分析器->(符号流)->词法分析->(语法树)->语义分析->(语法树)->中间代码生成器->中间表示形式->机器无关代码优化器->(中间表示形式)->代码生成器->(目标机器语言)->机器相关代码生成器->(目标机器语言)

词法分析

词法分析其实就是把高级语言按照放在符号表里面的数据和运算符号重新组织成有意义的词素(lexeme)的序列。
按照这样的形式输出:

<token-name,attribute-value>
就是编译器把这些语句一个一个按照目标语言所需要的形式先拆分好,后面好直接使用。
example:
Position = initial + rate * 60
词法分析这哥们要做的事呢,就是一个个的重新排列下:

  • position 是一个词素,被映射成词法单元<id,1>,其中这个id就是那个符号表里面对应条目为1的。这哥们为了方便,把position,initial,rate都放到一个符号表里,然后每个都标上了号,里面存放对应的名字类型啥的
  • 赋值符号 = 是一个词素,被映射成词法单元<=>,因为=没有属性值啥的,所以这哥们直接忽略了第二个分量。
  • initial 你猜被映射成啥样
    • 同 =
  • rate 你猜
    • 同 =
  • 60 是一个词素,被映射成<60>//本来应该是形如<number,4>酱紫的词法单元,4是60对应的条目,这个放后面再说,嗯,书上是这么说的。

所以上面的例子就被词法分析这哥们整合成下面酱紫:

<id,1><=><id,2><+><id,3><*><60>

一个赋值语句的翻译

语法分析/解析(syntax analysis/parsing)

语法分析这哥们是把上面那哥们分析好的词素创建树形的中间表示。常用的表示方法是语法树,树的每个内部结点表示一个运算,而该节点的子节点表示该运算的分量。
按照上面那个例子理解,这里就是理下运算的优先级,比如rate*60肯定先运算的

语义分析(semantic analyzer)

语义分析就像一个检查员,把语法树和符号表的信息检查,看是否和语言定义的语义一致,顺便呢,收集一些类型信息,放到语法树或者符号表中,方便随后中间代码生成过程总使用。
检查员手动检查工作量太多了,所以这里有个部分就自动化了,程序设计语言可能允许某些类型转换,自动类型转换出现了(coercion).比如一个二元算术运算符可以应用于一对整数或者一对浮点数,如果这个运算符应用于一个浮点数和一个整数,那么编译器可以把介个整数自动转换成一个浮点数,比如那个60

中间代码生成

检查员表示没问题了,然后这里开始为目标语言的生成做准备了,饭都要一口一口吃嘛,不能指望编译器一下子就生成目标语言对吧,这里的中间代码要易于生成而且能被轻松的翻译成目标机器上的语言。

代码优化

中间代码生成之后,可能不够美观和简介,于是这里给它梳妆打扮下

代码生成

Duang~目标代码生成中。。。

编译器构造工具

一些常用的编译器构造工具包括:

  • 语法分析器的生成器
  • 扫描器的生成器
  • 语法制导的翻译引擎
  • 代码生成的生成器
  • 数据流分析引擎
  • 编译器构造工具集

程序设计语言的发展历程

  • 随着20世纪40年代第一台电子计算机的出现,机器语言编程也出现了,由0,1组成。(第一代语言)
  • 后来到了50年代,汇编出现了(第二代语言)
  • 50年代的后五年,用于科学计算的Fortran,商业数据处理的Cobol,用于符号计算的Lisp被开发出来。(第三代语言)
  • 后来C,C++,Java,C#,Ruby,Go,PHP…..(第三代语言-高级程序设计语言)
  • 为特定应用设计的语言,比如用于生成报告的NOMAD,用于数据库查询的SQL……
  • 给予逻辑和约束的语言,比如Prolog和OPS5

语言的一个简单分类

  • 强制式(imperative) 把程序中指明如何完成一个计算任务的语言称为强制式语言,比如C,C++,Java
  • 声明式(declarative) 把程序中指明要进行那些计算的语言称为声明式语言。 比如ML,Haskell,Prolog
  • 面向对象语言 Simula 67, Smalltalk, C++,C#,Java, RUby……
  • 冯诺依曼语言 C, Fortran
  • 脚本语言 Awk, JavaScript, Perl, PHP, Python, Ruby……