创建JVM编程语言

时间:2010-08-01 02:28:09

标签: compiler-construction programming-languages jvm jvm-languages

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

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

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

所以这是我的问题:

  1. 我想要为JVM创建一种语言,必须阅读JVM specification书,你能提出哪些其他书籍(当然除了龙书)?我最关心的是关于如何创建JVM语言的书籍或教程,而不是一般的编译器。
  2. 有许多Java库可以读取,写入和更改.class文件,如jclasslibbcelgnu bytecode等。您会建议哪一个?另外,您是否了解执行相同工作的C库?
  3. 我正在考虑看看另一种针对JVM的语言,如Clojure,Jython或JRuby。但是所有这些语言都非常高级且复杂(为它们创建编译器)。我正在寻找一个更简单的(我不介意它是未知或未使用的)编程语言,它是针对JVM的,它的编译器是开源的。有什么想法吗?

9 个答案:

答案 0 :(得分:58)

我也会推荐ASM,但看看Jasmin,我用它(或者:必须使用它)进行大学项目,它运作得很好,我写了一个lexer / parse /分析器/优化器/生成器组合,用于使用java和jasmin编程语言,因此生成JVM代码。我上传了代码here,有趣的部分应该是source-code itself。在文件夹“bytecode / InsanelyFastByteCodeCreator.java”中,您可以找到一组代码,它将AST树转换为jasmin汇编器的输入格式。很直接。

源语言(由Lexer + Parser + Analyzer转换为AST)是Java的一个子集,称为MiniJava。它缺少一些“复杂”的功能,如继承,构造函数,静态方法,私有字段/方法。这些功能都不难实现,但是编写X86后端还有另外一个任务(所以生成机器组装器),如果你没有处理某些东西的JVM,这些事情往往会变得困难。

如果您想知道奇怪的类名:大学项目的任务是将AST转换为aa SSA图形(这是一个表示输入代码的图形),然后优化图形和然后将图形转换为java字节代码。这大约是项目工作的3/4,而InsanlyFastByteCodeCreator只是测试一切的捷径。

查看Jon Meyer和Troy Downing撰写的“Java虚拟机”一书。本书大量引用了Jasmin-Assembler,它对理解JVM内部结构很有帮助。

答案 1 :(得分:10)

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

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

要输出java字节码,我使用了Scala CAFEBABE library。记录良好,您不必深入了解Java类以了解该做什么。

除了这本书之外,我认为你可以通过我们在课程中所做的labs找到很多信息。

答案 2 :(得分:4)

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

答案 3 :(得分:3)

  

我正想着看看也许吧   另一种针对JVM的语言   像Clojure,Jython或JRuby。但是所有   这些语言水平很高   和复杂(创建一个编译器   他们)。

建议:您可以查看Lua Programming Language,其中有JVM实现,如LuaJ

  

轻量级,快速,以Java为中心的Lua   为J2ME和J2SE编写的解释器,   用于基本的库,字符串,   表,包,数学,io,操作系统,调试   和coroutine包,编译器,   luajava绑定和JSR-233   可插入的脚本引擎绑定。

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

答案 4 :(得分:2)

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

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

  • 语言实施模式。 我讨厌antlr,但这本书看起来非常好。如果你不喜欢antlr,那么解析“解析技术。实用指南”是非常好的。

      

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

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

      
        
    • 10 Building Bytecode口译员      
          
      • 10.1编程字节码解释器。
      •   
      • 10.2定义汇编语言语法
      •   
      • 10.3字节码机器结构。 。 。 。
      •   
      • 10.4从这里开始。 。 。 。 。 。 。 。 。
      •   
      • P.26。字节码汇编程序。 。 。 。 。 。 。 。 。 。
      •   
      • P.27。基于堆栈的字节码解释器。 。
      •   
      • P.28。基于注册的字节码解释器
      •   
           http://pragprog.com/titles/tpdsl/language-implementation-patterns
    •   
    • 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。

您打算将代码上传到任何地方吗?我想看看。

答案 5 :(得分:1)

我建议您首先了解JVM程序集的工作原理,如果您还不知道的话。

许多说明的格式为?name,如果指令适用于整数类型,则?i;如果适用于引用类型,则为a。< / p>

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

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

Here is an instruction reference用于旧版本的JVM,其中可能包含的指令少于新版本。

答案 6 :(得分:1)

开头的最佳资源可能是Ola Bini's presentation。抓住幻灯片。

答案 7 :(得分:0)

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

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

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

答案 8 :(得分:0)

当然曾经可以使用Java编写新语言。使用Java Reflection-API,您可以实现一个llot。如果速度不太重要,我将优先选择Java而不是ASM。在Java (IMHO)中,编程更加容易,而且不易出错。看看RPN语言7th。 它完全用Java编写。