我在C中创建了一个编译器(使用lex和bison),用于支持循环,函数内部函数声明,递归调用等的动态类型编程语言 . 我还创建了一个运行编译器创建的中间代码的虚拟机 .
我现在正在考虑而不是编译到我自己的中间代码,将其编译为java字节代码 .
我看到有关创建JVM语言的问题已经asked但是我找不到答案非常有用 .
所以这是我的问题:
-
我想要为JVM创建一种语言,必须阅读JVM specification书,你能提出哪些其他书籍(当然除了龙书)?我主要关注如何创建JVM语言的书籍或教程,而不是一般的编译器 .
-
有许多Java库可以读取,写入和更改.class文件,如jclasslib,bcel,gnu bytecode等 . 您会建议哪一个?另外,您是否了解执行相同工作的C库?
-
我正在考虑看一下针对JVM的另一种语言,如Clojure,Jython或JRuby . 但是所有这些语言都非常高级和复杂(为它们创建编译器) . 我正在寻找一种更简单的(我不知道或未使用的)编程语言,它针对JVM而且它的编译器是开源的 . 有任何想法吗?
9 回答
首先,我退出,修改我的编译器以输出实际的Java而不是Java字节代码(这意味着创建更多的翻译器而不是编译器),并使用任何方便的Java环境编译Java输出(这可能会生成更好的目标代码)比我自己的编译器) .
您可以使用相同的技术(例如,编译为C#)来生成CLI字节代码,或者编译为Pascal以生成P代码等 .
目前尚不清楚为什么要考虑Java代码而不是使用自己的VM,但如果是为了性能,那么当然你也应该考虑编译实际的机器代码 .
上周末,我问自己同样的问题,把我的玩具语言移植到JVM上 .
我只花了几个小时搜索信息,所以请参考这些参考文献 .
第10章涵盖了30页(快速IMO)这个主题 . 但是还有其他章节可能你会感兴趣 .
The Implementation of Lua 5.0 这是一篇关于基于寄存器的字节码机的好文章 . 即使是为了它也要读它 .
Lisp in Small Pieces. 本书教授如何编写一个编译为C的2个schme编译器 . 从本书中可以学到很多课程 . 我拥有这本书的副本,这对任何有趣的人来说都是非常好的,但也许不是你的一杯茶 .
http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473
检查Dalvik7 VM,这是一个基于寄存器的VM . DVM对从Java编译器编译的Java类文件转换的字节码进行操作 .
有一个关于这个主题的邮件列表,jvm-languages .
您是否计划将代码上传到任何地方?我想看一看 .
我建议您首先了解JVM组装的工作原理,如果您还不知道的话 .
许多指令的形式为
?name
,其中?
是i
(如果指令使用整数类型)和a
(如果它适用于引用类型) .基本上,JVM是一个没有寄存器的堆栈机器,因此所有指令都直接在堆栈上处理数据 . 您可以使用
?push/?pop
推送/弹出数据,并使用?store/?load
在本地变量(由偏移引用的堆栈位置)和堆栈顶部之间移动数据 . 其他一些重要说明是invoke???
和if_???
.对于my university's compiler course,我们使用Jasmin来组装程序 . 我不知道这是不是最好的方法,但至少它是一个容易开始的地方 .
Here is an instruction reference用于旧版本的JVM,可能包含较少的JVM说明而不是新的 .
Suggestion: 您可以查看Lua Programming Language,它有JVM实现,如LuaJ .
(不要与使用JNI方法的本机库的LuaJava混淆 . )
当然可以使用Java编写一种新语言 . 使用Java reflection-API您可以获得一个llot . 如果速度不重要,我会给Java优先选择而不是ASM . 在Java(恕我直言)中编程更容易,更不容易出错 . 看一下RPN语言7th . 它完全用Java编写 .
上学期我参加了“编译器构建”课程 . 我们的项目正是您想要做的 .
我用来写我的语言的语言是Scala . 它在JVM上运行,但支持Java没有的许多高级功能(仍然与纯Java JVM完全兼容) .
为了输出java字节码,我使用了Scala CAFEBABE library . 记录良好,您不必深入java类来了解该怎么做 .
除了这本书之外,我认为你可以通过我们在课程期间完成的labs找到很多信息 .
我也推荐ASM,但看看Jasmin,我用它(或者:不得不使用它)用于大学项目,它运行得很好,我写了一个lexer / parse / analyzer / optimizer / generator组合使用java和jasmin的编程语言,因此生成JVM代码 . 我上传了代码here,有趣的部分应该是source-code itself . 在文件夹"bytecode/InsanelyFastByteCodeCreator.java"中,您会发现一些代码,它将AST树转换为jasmin汇编程序的输入格式 . 非常直截了当 .
源语言(由Lexer Parser Analyzer转换为AST)是Java的一个子集,称为MiniJava . 它缺少一些“复杂”的功能,如继承,构造函数,静态方法,私有字段/方法 . 这些功能都不难实现,但是编写X86后端还有另外一个任务(所以生成机器 - 汇编程序),如果你没有处理某些东西的JVM,这些事情往往会变得困难 .
如果你想知道奇怪的类名:大学项目的任务是将AST转换为一个SSA Graph(这是一个表示输入代码的图形),然后优化图形,然后将图形转换为java字节代码 . 这大约是项目工作的3/4,而InsanlyFastByteCodeCreator只是测试一切的捷径 .
看看Jon Meyer和Troy Downing的“Java虚拟机”一书 . 本书大量引用了Jasmin-Assembler,它对理解JVM内部结构非常有帮助 .
ASM可以是生成字节码的解决方案 . 首先,检查有关从manual生成元素的主题 .
开头的最佳资源可能是Ola Bini's presentation . grab 幻灯片 .