我刚刚完成毕业项目,应该持续6个月。 该项目的目标是为一种脚本语言实现.Net编译器。我将编译器构造作为课程的主题,并且知道如何实现编译器的基本步骤,但我们使用Bison和简单的编译器和GCC作为后端,因此我对实现编译器知之甚少在.Net平台上。
在对这个主题进行了一些研究后,我发现了以下代码生成的替代解决方案(我不是在谈论编译器的其他重要部分,比如解析器 - 它超出了范围):
我的项目的主要目标是深入研究.Net的内容,学习编译器构建并为我的工作取得好成绩。第二个目标是提出一个编译器实现,以后可以在许可的开源许可下向社区开放。
那么,这里最有趣,最具教育性,最有趣和最有希望的方法是什么呢?如果我有更多的时间,我肯定会尝试所有这些,但我需要在6个月内提交我的工作以获得积极的成绩......
提前谢谢你, 亚历山大。
答案 0 :(得分:5)
如果您想要更简单的方法并且您的语言可以合理地翻译成C#,我建议您生成C#代码(或类似代码)并进行编译。罗斯林可能是最好的。显然,CCI也可以使用CCI Code来做到这一点,但我从未使用过它。我不推荐CodeDOM,因为it doesn't support features like static classes or extension methods。
如果您想要更多控制,或者想要进入低级别,可以使用Reflection.Emit直接生成CIL。但它会(更多)更多的工作,特别是如果你不熟悉CIL。我认为Cecil可以以相同的方式使用,但它的目的是用于其他东西,我认为它没有提供任何优于Reflection.Emit的优势。
DLR的全称是动态语言。它使用的Expression
可用于代码生成,但我认为它们最适合在运行时生成相对简单的方法。当然,如果您的语言是动态的,DLR本身就非常有用。
答案 1 :(得分:2)
Boo是一种针对CLI的语言/编译器。它似乎是开源的,所以你可以研究它们是如何实现它的。
答案 2 :(得分:2)
当我编写编译器时,我会写汇编语言(即汇编语言源代码),然后我通过系统的汇编程序运行。这样我就可以很容易地看到我正在产生什么。阅读mov ax, bx
(x86汇编)比解码HEX操作码更容易。
如果我不允许在最终产品中使用汇编程序,我使用汇编输出开发了编译器,然后一旦我完成所有工作,我就制作了二进制输出路径。美丽是,我必须改变的是实际的字节输出(操作码和二进制值而不是文本)。
我建议为你的项目做类似的事情。最初开发它以输出可以用ILASM组装的MSIL。这样,您可以通过读取生成的代码轻松验证代码生成器的输出。一旦您确信代码生成器正在运行,请添加将使用Reflection.Emit
或Common Compiler Infrastructure的输出选项。