初级巅峰
hello world,许多人写的第一行代码,你是否也好奇它背后的原理,一些字符的组合为何能输出想要的结果,像不像魔法?
你也许是会写数十种语言的“hello world”高手,但我想说并不是这一领域的巅峰,因为没有写出自己的"hello world"。
不管你是初学者,还是富有经验的开发者,试着开始着手设计自己的开发语言吧。
先定一个小目标:能够运行下面这些简单的语句。
图1
来龙去脉
如果你曾读过一些编译原理或者相关的书籍,理解代码是被编译器翻译后在机器上执行的。因此我们就按照主流的编译器工作流程,来设计自定义的编程语言。
那么源代码是如何变成变成执行文件的呢?如下图:
在动手之前,你需要大概了解什么是编译器和汇编器,理解它们的作用是什么。我们设计的高级语言符合主流的编程语言如C,当然,如果你想加入一些奇思妙想也未尝不可。除此之外还会有很多细节,在我们后续的构建过程中一一阐述。
大道至简
在借鉴现有高级开发语言的前提下,我们无需再从零开始设计一门语言的表达形式,就像使用类似C的语法一样,来使用设计我们的语言。
我们可以毫不费力的写出了一个简单的样例,如上图1。可是要怎么运行它呢?
终于引出我们的压轴角色——编译器。编译器是整个流程的核心,主要负责解析源程序的语义,生成目标机器代码。一般可分为:词法分析、语法分析、语义分析和代码生成四个阶段。如下图:
一 词法分析
通过词法分析器将源代码中的字符识别成高级语言中定义的各种词法记号,比如标识符、关键字、常量、运算符、终止符等其他符号。
例如语句:
int a = 10;
该语句包含5个词法记号,分别是:“int”、“a”、“=”、“10”和";"。
二 语法分析
语法分析的输入为词法分析的词法记号序列,输出为一种树形数据结构,通常叫做抽象语法树。
例如语句:
int q = z + x * y;
抽象语法树如下图:
构造一颗语法树不仅需要词法序列,还需要知道该高级语言的文法,即语言的书写规则。具体文法相关会在后续文法的章节中讨论。
三 语义分析
语法分析只关心程序语言语法形式的正确性,而不考虑语法模块上下文之间是否合法。例如不允许使用未定义的变量或函数,表达式的各个变量类型是否一致,函数调用的参数是否一致等。
四 代码生成
代码生成将抽象语法树识别的语法模块翻译成目标机器代码,比如汇编语言。不同操作系统的汇编编码有所不同,为了屏蔽底层操作系的差异性,一般会先生成中间代码,再根据中间代码生成目标机器代码。
五 编译优化
直接由源程序翻译的目标机器代码会存在许多性能问题,为了提高生成机器代码的质量,需要对其进行优化。由于中间代码的存在,我们就可以直接优化中间代码。
六 符号表
符号表的作用是组织和记录在整个语法分析过程的符号信息,我们定义的符号主要包括变量和函数。变量符号信息包括变量类型、变量作用域、变量大小、变量值等。函数符号信息包括函数名称、参数列表、返回值类型等。
后续规划
1.一个hello world的诞生
2.词法分析器
3.从自然语言认识文法
4.构造文法
5.语义分析
6.生成中间代码
7.函数的帧栈调用过程
8.汇编
9.编译和链接
10.终于跑起来了
11.多文件编译
12.丰富数据类型
13.流程控制语句
14.编译优化算法
15.文件读取
16.一个线程的实现
17.什么是锁
18.网络编程
19.面向对象
20.其他规划
欢迎关注公共号: