celloworldNavigate back to the homepage

编译器设计:what is compiler?

hidaris
March 26th, 2019 · 1 min read

Compilers are percieved to be magical artifacts, carefully crafted by the wizards, and unfathomable by the mere mortals.

什么是编译

我们知道计算机可以直接理解的语言是二进制,但是它对人类并不友好,我们也不希望直接工作在二进制层面,所以需要有一个转换程序来帮助我们将一个人类可读的语言变为机器语言。

一般而言, 有两种方式:

  1. 我们可以写一个程序(解释器),实时接收程序的源码并解释它,这种方法的缺点在于当我们想跑一个程序的时候,必须同时具备源码和解释器。
  2. 我们可以写一个程序将我们的代码直接翻译成机器语言, 一旦翻译这一步完成,我们将不再需要程序源码或者执行翻译的程序,我们可以直接执行它。

定义

换句话说,编译器是一个将输入的字符串映射成输出字符串的程序:

1compiler : String -> String

考虑到输入输出的字符串是不同语言的程序:

1compiler : SourceProgram -> TargetProgram

举一些比较常见的编译器的例子:

1gcc, clang : C -> Binary (* a.out, .exe *)
2ghc : Haskell -> Binary
3javac : Java -> JvmByteCode (* .class *)
4scalac : Scala -> JvmByteCode
5ocamlc : Ocaml -> OcamlByteCode (* .cmo *)
6ocamlopt : Ocaml -> Binary
7gwt : Java -> JavaScript (* .js *)
8v8 : JavaScript -> Binary
9nasm : X86 -> Binary
10pdftex : LaTeX -> PDF
11pandoc : Markdown -> PDF or Html or Doc

编译阶段

编译通常分为以下阶段:

  • Parse: 将源程序转变为一个叫抽象语法树(Abstract Syntax Tree)的结构
  • Check: 确保AST是类型安全的(well-formed and well-typed)
  • Simplify: 将AST简化为一些更简便的中间表示
  • Optimize: 将代码转为语义相同,但是更高效的形式
  • Generate: 生成X86汇编
  • Link: 在运行时将代码链接起来

在后面的文章里,我们将会关注一些编译器构造的核心原则:

  • 对堆栈的管理
  • 类型检查
  • 中间表示
  • 优化

参考

cs4410 Lecture 1: Introduction

An Incremental Approach to Compiler Construction

More articles from hidaris

分布式系统笔记:RPC

RPC ideally makes net communication look just like fn call

March 16th, 2019 · 1 min read

分布式系统笔记:CAP定理

分布式系统中各个节点的状态如何同步是一个难题,CAP 定理是这个问题相关的定理,也是很多分布式系统设计的理论基础

March 8th, 2019 · 2 min read
© 2016–2020 hidaris
Link to $https://twitter.com/zuodadaLink to $https://github.com/hidarisLink to $https://instagram.com/hidaris128