动手写一个C语言编译器
作者:网络转载 发布时间:[ 2014/9/29 10:20:07 ] 推荐标签:C++ 编译器
动手编写一个编译器,学习一下较为底层的编程方式,是一种学习计算机到底是如何工作的非常有效方法。
编译器通常被看作是十分复杂的工程。事实上,编写一个产品级的编译器也确实是一个庞大的任务。但是写一个小巧可用的编译器却不是这么困难。
秘诀是首先去找到一个小的可用工程,然后把你想要的特性添加进去。这个方法也是Abdulaziz Ghuloum在他那篇的论文“一种构造编译器的捷径”里所提到的办法。不过这个办法确实可行。你只需要按照这篇论文中的第一步来操作,可以得到一个真正可用的编译器!当然,它只能编译程序语言中的非常小的子集,但是它确实是一个真实可用的编译器。你可以随意的扩展这个编译器,然后从中学到更多更深的知识。
受到这篇文章的鼓舞,我写了一个C编译器。从某种意义上来说这比写一个scheme的编译器要困难一些(因为你必须去解析C那复杂的语法),但是在某些方面又很便利(你不需要去处理运行时类型)。要写这样一个编译器,你只需要从你那个可用的小的编译器开始。
对于我写的编译器来说,我把它叫 babyc,我选了这段代码来作为我需要运行的第一个程序:
int main() {
return 2;
}
没有变量,没有函数调用,没有额外的依赖,甚至连if语句,循环语句都没有,一切看起来是那么简单。
我们首先需要解析这段代码。我们将使用 Flex 和 Bison 来做到这点。这里有怎么用的例子可以参考,幸好我们的语法是如此简单,下面是词法分析器:
"{" { return '{'; }
"}" { return '}'; }
"(" { return '('; }
")" { return ')'; }
";" { return ';'; }
[0-9]+ { return NUMBER; }
"return" { return RETURN; }
"int" { return TYPE; }
"main" { return IDENTIFIER; }
这里是语法分析器:
function:
TYPE IDENTIFIER '(' ')' '{' expression '}'
;
expression:
RETURN NUMBER ';'
;
终,我们需要生成一些汇编代码。我们将使用32位的X86汇编,因为它非常的通用而且可以很容易的运行在你的机器上。这里有X86汇编的相关网站。
下面是我们需要生成的汇编代码:
.text
.global _start # Tell the loader we want to start at _start.
_start:
movl $2,%ebx # The argument to our system call.
movl $1,%eax # The system call number of sys_exit is 1.
int $0x80 # Send an interrupt
然后加上上面的词法语法分析代码,把这段汇编代码写进一个文件里。恭喜你!你已经是一个编译器的编写者了!
Babyc 是这样诞生的,你可以在这里看到它开始的样子。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11