从零开始写个编译器吧系列——将在 GitBook 上以在线电子书的形式继续连载

2016-07-30
阅读 1 分钟
3.5k
各位抱歉了,这个系列在多个平台的专栏上连载。每发一个新章节,都要同步到各个专栏上,于是可能漏掉 Segmentfault 的博客。汗,其实 Segmentfault 这边已经落后很久了。

我们把 iOS 的 Cocoa Touch 移植到了 Android

2016-04-03
阅读 2 分钟
15.5k
这是我最近一年在做的项目,用我们老大的话说,就是“能不能弄一个东西,让我的 iOS 程序一行代码不用改,却能运行在 Android 上”。为了这个目标,我们最后弄出了个这样的东西。

从零开始写个编译器吧 - tao 语言的文法定义(下)

2016-02-26
阅读 2 分钟
2.9k
目前为止我们创建的文件列表: {代码...} 上一章中我们提到了 4 个方法: node token or sign 它们可以用来描述非终结符和展开式的形式,那么它们又是如何工作的呢? {代码...} 可以看出,这些方法只是稍微封装了一下,具体还要继续追踪 TerminalSymbol.java 和 NotTerminalySymbol.java。 先看看 TerminalSymbol.java ...

从零开始写个编译器吧 - tao 语言的文法定义(上)

2016-02-25
阅读 3 分钟
4.9k
各位久等了,本系列在新一年的连载中,形式会加入少许变化。首先,我会将 tao 语言编译器(以及运行环境)的全部内容贴在 GitHub 上,在阅读本系列的时候,需要对照 GitHub 上的内容。以取代之前一段一段贴代码的这种形式。此外,本系列也不会像之前那样贴出每一行代码,并对其进行讲解,取而待之,仅仅对核心代码和有代...

从零开始写个编译器吧 - TerminalSymbol.java 与 NonTerminalSymbol.java

2016-02-24
阅读 5 分钟
3.6k
首先是 TerminalSymbol.java 即终结符。 {代码...} 对于 Parser 而言,终结符 Terminal Symbol 与 Tokenizer 的 Token 是对应的。特别的,对于以上代码: {代码...} 这里非终结符的类型(Type)我就直接用了 Token.java 中定义的内部枚举类啦。 特别的, {代码...} 这里将 Keyword、Sign 这两种类型归于 careValueType。...

从零开始写个编译器吧 - 数量词符号

2016-02-21
阅读 1 分钟
2.7k
式子中的符号,我还允许使用数量词来修饰。考虑一个非终结符 A,如果对于另一个符号 α,存在如下产生式。 α → αA | ε 则对于 α 而言,它可以表示非终结符 A 重复 0 、1、多次的各种形式。 现在稍稍改变这个式子,使之变成: α → αA | A 这时,α 不再可能产生空,此时它只能表示非终结符 A 重复 1次或多次。当然还有这个...

从零开始写个编译器吧 - 分析非终结符

2016-02-20
阅读 2 分钟
4.4k
tao 语言的 Parser 的语法分析是不带回溯的,自顶向下的。文法选用 LL(1),这种文法虽然略显薄弱,但还尚可用。 回顾上一章提到的 LL(1) 的定义,可以得出如下结论。 在不考虑 ε 时,对于一个非终结符,它的每一个产生式都有一个FIRST 集与之对应。而这些 FIRST 集彼此不相交。 这个特征很有用,因为这个特征很容易得出...

从零开始写个编译器吧 - 程序流控制

2016-02-19
阅读 4 分钟
3.4k
其中 StartChunk 是我们展开式的所有起点,每一个 tao 语言的源代码文件都从 StartChunk 开始展开。这里我简单的将其展开为 Chunk。

从零开始写个编译器吧 - LL(1)

2015-02-20
阅读 1 分钟
6.4k
上一章中,我说 Parser 的工作就是依据文法定义,找到一个与源代码匹配的展开方案就可以了。听起来我们只要先给出一个 tao 语言的文法定义,然后写一个找匹配方案的的程序就可以了。 然而事情情况并非如此简单。因为假如我们不对文法定义的形式加诸任何限制的话,让 Parser 找到匹配方案并非很轻易的事情。

从零开始写个编译器吧 - 文法简介

2015-02-20
阅读 2 分钟
3.9k
如何充分定义这个赋值语句的形式呢?若用自然语言描述,我可以说,赋值语句最左边是一个标示符,然后紧接一个“=”符号,然后再接一个表达式。满足这个条件的,即是赋值语句啦。

从零开始写个编译器吧 - Parser 语法分析器

2015-02-20
阅读 2 分钟
9.3k
Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些。当然,本系列旨在“写出”一个编译器,所以理论方面只会简单介绍 tao 语言所涉及的部分。 之前的几章中,我纯手写了tao 语言的 Tokenizer。但如果我准备也纯手写一个 Parser,那将是非常麻烦且繁琐的一件...

从零开始写个编译器吧 - 开始写词法分析器(3)

2015-02-20
阅读 2 分钟
4k
上周周末旅游去了,就没更新了,虽然回到海拔0m的地区,不过目前似乎还在缺氧,所以本次就少更点吧。 这章将结束词法分析的部分。 在之前的章节(第7章从零开始写个编译器吧 - 开始写词法分析器(1))中我有说,我将 readChar(char c) 函数设计成主动调用的形式,而 read() 则是被动调用的形式。 那好,现在让我们来填...

从零开始写个编译器吧 - 符号分析,编写 SignParser.java 文件

2015-02-20
阅读 5 分钟
3.6k
相对于 String 字符串啊、Identifier 标示符之类的可以通过字符本身来划分开端和结尾的类型,Sign 运算符运算符类型却只能以既定形式来划分开端和结尾。

从零开始写个编译器吧 - 开始写词法分析器(2)

2015-01-11
阅读 10 分钟
4.4k
在上一章中,我已经写好了从 Normal 状态跳转到各个其他状态的代码,这一章中,我将写完所有非 Normal 状态下对字符的处理代码,以及跳回 Normal 状态代码。

从零开始写个编译器吧 - 开始写词法分析器(1)

2015-01-11
阅读 4 分钟
6.1k
于是我又添加了一点代码。可以看到,我放着 readChar() 函数的 TODO 不管,又添加了一个 readChar(char c) 的函数。因为我有这么一个考虑:对于readChar()方法而言,这个是一个被动调用的函数,外部调用一下,就读到一个Token。这样设计,今后写 Parser 时读取 Token 会要简单许多。而readChar(char c)是一个主动调用的...

从零开始写个编译器吧 - 词法分析器是一个状态机

2015-01-11
阅读 2 分钟
7.9k
词法分析器 Tokenizer 本身就是一个状态机,生成这个状态机有很多种方法,而我打算采取手写的方式。因为 tao 语言的词法还是相对比较简单的,手写不成问题。 先新建一个LexicalAnalysis.java 于 src/com/taozeyu/taolan/analysis之中。

从零开始写个编译器吧 - Token.java 文件的编写

2015-01-11
阅读 2 分钟
6.6k
现在,让我们来动手写编译器的第一个个java文件吧。本章要写的类,是Token类。如其名字所示,这个类实例化的对象用于表示词法分析器 Tokenizer 的产物。同时,也作为下一阶段的语法分析器 Parser 的原料。

从零开始写个编译器吧 - tao语言的词法分析器(Tokenizer)的类型定义

2015-01-11
阅读 2 分钟
5.7k
要为 tao 语言设计词法分析器,首先得知道 tao 语言是一种什么样的语言。不过呢,我脑海里还没有 tao 语言具体形象。我还是先贴一段 tao 语言的代码,大概展示下这是怎么回事吧。

从零开始写个编译器吧 - 单词化简述(Tokenization)

2015-01-11
阅读 2 分钟
5.8k
实际上,所谓的源代码,我们可以将其视为一段长长的字符串。所谓字符串,即是字符的有序集。但是,字符本身作为编译器的输入单位,粒度实在太小了,因此,我们往往需要对编译器进行第一层封装,即分割出一个称之为 Tokenizer (词法分析器)的部分。 Tokenizer 的作用即是将字符序列翻译成 Token(单词)的一个过程,这...

从零开始写个编译器吧 - 编译器的结构

2015-01-11
阅读 1 分钟
6.6k
自然,我们还是先从 tao 语言的编译器下手吧。在动手写编译器之前,得容我将编译器的结构进行进一步的划分。编译器可视为一个黑盒,从其一端输入源代码,另一端产出目标代码。此过程进一步拆分便有了如下形式。

从零开始写个编译器吧 - 从何处下手

2015-01-11
阅读 1 分钟
7.1k
作为本系列的第一章,将考虑从何开始下手。既然写的是编译器,那在此得明确编译器长什么样子,进一步,编译器由哪几部分构成,其工作原理大概是怎样的。了解了这些,才好下手。

从零开始写个编译器吧系列

2015-01-11
阅读 1 分钟
12.6k
是的,这个系列将呈现一个完整的编译器从无到有的过程。当然,为了保证该系列内容的简洁(也为了降低难度),仅仅保证编译器的最低要求,即仅能用。但在写这个编译器的过程中,我可不会偷工减料,该有的一定会写上的。