我有兴趣编写一个非常简约的编译器.
我想写一小段软件(用C/C++),它符合以下标准:
ELF格式的输出(*nix)
input是单个文本文件
类C语法和语法
没有链接器
没有预处理器
非常小(最大1-2 KLOC)
语言特色:
本机数据类型:char,int和float
数组(适用于所有本机数据类型)
变量
控制结构(if-else)
功能
循环(会很好)
简单代数(div,add,sub,mul,布尔表达式,位移等)
内联asm(用于系统调用)
谁能告诉我怎么开始?我不知道编译器包含哪些部分(至少在某种意义上我不能直接启动)以及如何对它们进行编程.谢谢你的想法.
有了您希望完成的所有目标,最具挑战性的要求可能是"非常小(最大1-2 KLOC)".我认为你的第一个要求(生成ELF输出)本身可能需要超过一千行代码.
简化问题的一种方法,至少在开始时,是用汇编语言文本生成代码,然后将其提供给现有的汇编程序(nasm将是一个不错的选择).汇编程序将负责生成实际的机器代码,以及构建实际可运行的可执行文件所需的所有ELF特定代码.然后,您的工作将简化为语言分析和汇编代码生成.当您的项目成熟到要删除对汇编程序的依赖关系时,您可以自己重写此部分并随时将其插入.
如果我是你,我可以从一个汇编程序开始,然后在它上面构建一些部分.最简单的"编译器"可能只使用一些非常简单的语句来使用语言:
print "hello" a = 5 print a
并将其转换为汇编语言.一旦你开始工作,那么你可以构建一个词法分析器和解析器以及抽象语法树和代码生成器,它们是现代块结构化语言所需的大部分部分.
祝好运!
首先,您需要决定是要创建编译器还是解释器.编译器将您的代码转换为可以直接在硬件上,在解释器中运行的代码,或者编译成另一种语言,然后以某种方式进行解释.这两种语言都是完整的,因此它们具有相同的表达能力.我建议您创建一个编译器,将您的代码编译成.net或Java字节码,因为它为您提供了一个非常优化的解释器以及许多标准库.
做出决定后,需要遵循一些常见步骤
语言定义首先,您必须定义语言在语法上的外观.
Lexer第二步是创建代码的关键字,称为令牌.在这里,我们讨论的是非常基本的元素,如数字,加号和字符串.
解析下一步是创建一个与您的令牌列表匹配的语法.您可以使用例如无上下文语法来定义语法.可以使用这些语法之一来提供许多工具,并为您创建解析器.通常,解析的标记被组织成一个解析树.解析树是您的语法表示为可以在其中移动的数据结构.
编译或解释最后一步是在解析树上运行一些逻辑.创建自己的解释器的一种简单方法是创建与树中每个节点类型相关联的逻辑,并从下到上或从上到下遍历树.如果要编译为另一种语言,可以插入如何在节点中转换代码的逻辑.
维基百科非常适合学习更多,您可能想从这里开始.
关于现实世界的阅读材料,我建议由David A Watt和Deryck F Brown编写"JAVA编程语言处理器".我在编译器课程中使用了那本书,通过实例学习在这个领域很棒.