创建JVM编程语言

我在C中创建了一个编译器(使用lex和bison),用于支持循环,函数内部函数声明,递归调用等的动态类型编程语言 . 我还创建了一个运行编译器创建的中间代码的虚拟机 .

我现在正在考虑而不是编译到我自己的中间代码,将其编译为java字节代码 .

我看到有关创建JVM语言的问题已经asked但是我找不到答案非常有用 .

所以这是我的问题:

  • 我想要为JVM创建一种语言,必须阅读JVM specification书,你能提出哪些其他书籍(当然除了龙书)?我主要关注如何创建JVM语言的书籍或教程,而不是一般的编译器 .

  • 有许多Java库可以读取,写入和更改.class文件,如jclasslibbcelgnu bytecode等 . 您会建议哪一个?另外,您是否了解执行相同工作的C库?

  • 我正在考虑看一下针对JVM的另一种语言,如Clojure,Jython或JRuby . 但是所有这些语言都非常高级和复杂(为它们创建编译器) . 我正在寻找一种更简单的(我不知道或未使用的)编程语言,它针对JVM而且它的编译器是开源的 . 有任何想法吗?

回答(9)

3 years ago

首先,我退出,修改我的编译器以输出实际的Java而不是Java字节代码(这意味着创建更多的翻译器而不是编译器),并使用任何方便的Java环境编译Java输出(这可能会生成更好的目标代码)比我自己的编译器) .

您可以使用相同的技术(例如,编译为C#)来生成CLI字节代码,或者编译为Pascal以生成P代码等 .

目前尚不清楚为什么要考虑Java代码而不是使用自己的VM,但如果是为了性能,那么当然你也应该考虑编译实际的机器代码 .

3 years ago

上周末,我问自己同样的问题,把我的玩具语言移植到JVM上 .

我只花了几个小时搜索信息,所以请参考这些参考文献 .

  • Language Implementation Patterns . 我讨厌antlr,但这本书看起来非常好 . 如果你不喜欢antlr,那么解析"Parsing Techniques. A Practical Guide."非常好

学习构建配置文件读取器,数据读取器,模型驱动的代码生成器,源到源转换器,源分析器和解释器 . 您不需要计算机科学背景 - ANTLR创建者Terence Parr通过将其分解为最常见的设计模式来揭开语言实现的神秘面纱 . 按模式模式,您将学习实现自己的计算机语言所需的关键技能 .

第10章涵盖了30页(快速IMO)这个主题 . 但是还有其他章节可能你会感兴趣 .

10 Building Bytecode Interpreters 10.1 Programming Bytecode Interpreters . . 10.2定义汇编语言语法10.3字节码机器结构 . . . . . 10.4从这里开始 . . . . . . . . . . P.26 . 字节码汇编程序 . . . . . . . . . . . P.27 . 基于堆栈的字节码解释器 . . . P.28 . 基于寄存器的字节码解释器http://pragprog.com/titles/tpdsl/language-implementation-patterns

  • The Implementation of Lua 5.0 这是一篇关于基于寄存器的字节码机的好文章 . 即使是为了它也要读它 .

  • Lisp in Small Pieces. 本书教授如何编写一个编译为C的2个schme编译器 . 从本书中可以学到很多课程 . 我拥有这本书的副本,这对任何有趣的人来说都是非常好的,但也许不是你的一杯茶 .

这是对Lisp,Scheme和相关方言的整个Lisp语言系列的语义和实现的综合描述 . 它描述了11个口译员和2个编译器......

http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473

检查Dalvik7 VM,这是一个基于寄存器的VM . DVM对从Java编译器编译的Java类文件转换的字节码进行操作 .

有一个关于这个主题的邮件列表,jvm-languages .

您是否计划将代码上传到任何地方?我想看一看 .

3 years ago

我建议您首先了解JVM组装的工作原理,如果您还不知道的话 .

许多指令的形式为 ?name ,其中 ?i (如果指令使用整数类型)和 a (如果它适用于引用类型) .

基本上,JVM是一个没有寄存器的堆栈机器,因此所有指令都直接在堆栈上处理数据 . 您可以使用 ?push/?pop 推送/弹出数据,并使用 ?store/?load 在本地变量(由偏移引用的堆栈位置)和堆栈顶部之间移动数据 . 其他一些重要说明是 invoke???if_??? .

对于my university's compiler course,我们使用Jasmin来组装程序 . 我不知道这是不是最好的方法,但至少它是一个容易开始的地方 .

Here is an instruction reference用于旧版本的JVM,可能包含较少的JVM说明而不是新的 .

3 years ago

我想看看可能是另一种针对JVM的语言,如Clojure,Jython或JRuby . 但是所有这些语言都非常高级和复杂(为它们创建编译器) .

Suggestion: 您可以查看Lua Programming Language,它有JVM实现,如LuaJ .

为J2ME和J2SE编写的轻量级,快速,以Java为中心的Lua解释器,包含基本,字符串,表,包,数学,io,os,调试和协同程序包,编译器,luajava绑定和JSR-233可插入脚本的库引擎绑定 .

(不要与使用JNI方法的本机库的LuaJava混淆 . )

3 years ago

当然可以使用Java编写一种新语言 . 使用Java reflection-API您可以获得一个llot . 如果速度不重要,我会给Java优先选择而不是ASM . 在Java(恕我直言)中编程更容易,更不容易出错 . 看一下RPN语言7th . 它完全用Java编写 .

3 years ago

上学期我参加了“编译器构建”课程 . 我们的项目正是您想要做的 .

我用来写我的语言的语言是Scala . 它在JVM上运行,但支持Java没有的许多高级功能(仍然与纯Java JVM完全兼容) .

为了输出java字节码,我使用了Scala CAFEBABE library . 记录良好,您不必深入java类来了解该怎么做 .

除了这本书之外,我认为你可以通过我们在课程期间完成的labs找到很多信息 .

3 years ago

我也推荐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内部结构非常有帮助 .

3 years ago

ASM可以是生成字节码的解决方案 . 首先,检查有关从manual生成元素的主题 .

3 years ago

开头的最佳资源可能是Ola Bini's presentation . grab 幻灯片 .