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

实际上,所谓的源代码,我们可以将其视为一段长长的字符串。所谓字符串,即是字符的有序集。但是,字符本身作为编译器的输入单位,粒度实在太小了,因此,我们往往需要对编译器进行第一层封装,即分割出一个称之为 Tokenizer (词法分析器)的部分。

Tokenizer 的作用即是将字符序列翻译成 Token(单词)的一个过程,这一过程称之为单词化(Tokenization)。很容易理解单词化这一步骤在整个编译过程中的价值,举个例子,如下这么一个英语句子。

It's understandable that we share some common values as we are living in the same world.

实际上,这个句子倘若以字符串的形式存在,即以字符作为最小单位来解析,则看起来形式如下。实际上,我们很难从中提取出有价值的信息。

['I', 't', '\'', 's', ' ', 'u', 'n', 'd', 'e', 'r', 's', 't', 'a', 'n',
 'd', 'a', 'b', 'l', 'e', ' ', 't', 'h', 'a', 't', ' ', 'w', 'e', ' ', 
's', 'h', 'a', 'r', 'e', ' ', 's', 'o', 'm', 'e', ' ', 'c', 'o', 'm', 
'm', 'o', 'n', ' ', 'v', 'a', 'l', 'u', 'e', 's', ' ', 'a', 's', ' ', 
'w', 'e', ' ', 'a', 'r', 'e', ' ', 'l', 'i', 'v', 'i', 'n', 'g', ' ', 
'i', 'n', ' ', 't', 'h', 'e', ' ', 's', 'a', 'm', 'e', ' ', 'w', 'o', 
'r', 'l', 'd' ]

而分词话的作用,则是将上面这段东西,变成(至少)下面这段东西。

["It", "is", "understandable", "that", "we", "share", "some",
 "common", "values", "as", "we", "are", "living", "in", "the",
"same", "world", "."]
看起来是不是更加顺眼了呢?实际上我们都几乎能读出这个单词数组所代表句子的意思了。

词法分析器 Tokenizer 的另一个功能在于,将单词 分类 。考虑源代码中这么一行。

private int index = 27;
会被拆分为如下形式。
["private", " ", "int", " ", "index", " ", "=", " ", "27", ";"]
但仅仅是把源代码的字符分割成段,这些字符串尚不能称之为完整的单词Token,而只能作为单词的 语素 。实际上,词法分析器还对将单词分类。因此,读到的 语素 ,分析出的 类型 ,两者才构成一个完整的单词。

实际上,词法分析器会为这行代码生成如下形式。

每一列代表一个单词Token,而单词包含两个属性,语素、类型。

你可能感兴趣的:(从零开始写个编译器吧 - 单词化简述(Tokenization))