创建JVM编程语言


91

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

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

我看到关于创建JVM语言的问题已经存在 但我认为答案并不十分有用。

所以这是我的问题:

  1. 我想为JVM创建一种语言是必须阅读 JVM规格书,您还能建议其他哪些书(当然,除了Dragon Book)?我最关心的是有关如何创建JVM语言的书籍或教程,而不是一般的编译器。
  2. 有许多Java库可以读取,写入和更改.class文件,例如jclasslibbcel gnu字节码等。您建议使用哪一个?另外,您知道执行相同工作的C库吗?
  3. 我当时正在考虑看看另一种针对JVM的语言,例如Clojure,Jython或JRuby。但是所有这些语言都是非常高级且复杂的(为它们创建编译器)。我一直在寻找一种针对JVM且其编译器是开放源代码的更简单(我不介意它是未知的还是未使用的)编程语言。有任何想法吗?

Answers:


61

我还将推荐ASM,但请看一下Jasmin,我在大学项目中使用了它(或:必须使用它),并且效果很好,我为使用java和jasmin的编程语言,因此生成JVM代码。我在这里上传了代码,有趣的部分应该是源代码本身。在文件夹“ bytecode / InsanelyFastByteCodeCreator.java”中,您可以找到一些将AST Tree转换为jasmin汇编程序输入格式的代码。是相当简单的。

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

如果您想知道奇怪的类名:大学项目的任务是将AST转换为SSA Graph(这样就代表了输入代码的图形),然后对图形进行优化,然后将其转换为Java字节码。那大约是项目工作的3/4,而InsanlyFastByteCodeCreator只是测试所有内容的捷径。

看看Jon Meyer和Troy Downing的“ Java虚拟机”一书。本书大量引用了Jasmin-Assembler,对于理解JVM内部非常有帮助。


感谢您的回答,我将介绍Jasmin。另外,如果您可以上传源代码,我也将很高兴,以便我看看。关于你的建议书,似乎有趣,但它的打印和相当陈旧:(出来。

这本书是非常便宜的二手书。我找到了几美元的副本。
namin 2010年

看看上面的编辑,如果您有任何疑问,我们将很乐意为您提供帮助。
theomega

到“源代码本身”的链接已断开。尽管我认为这将在8年后出现。
Llew Vallis

@LlewVallis,如果我正确解释所有信息,则代码似乎在这里:github.com/replimoc/compiler
U880D

14

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

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

为了输出Java字节码,我使用了Scala CAFEBABE库。有据可查,您无需深入Java类即可了解该怎么做。

除了这本书,我认为您可以通过我们在本课程中完成的实验来找到很多信息。


这听起来很不错。您愿意分享您的注释或代码吗?
Pedro

1
没问题,我将检查备份位置,并在此处发布链接,以便您尽快下载。
卡米

1
整洁的是,我一直在寻找动手实践的编译器课程,该课程针对JVM,并且所有在线材料都可供自学。
namin 2010年


4

我当时正在考虑看看另一种针对JVM的语言,例如Clojure,Jython或JRuby。但是所有这些语言都是非常高级和复杂的(为它们创建编译器)。

建议:您可以看一下Lua编程语言,它有JVM实现,例如LuaJ

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

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


谢谢。我会看一下

3

上周末,我问自己一个问题,将玩具语言移植到JVM。

我只花了几个小时来搜索信息,因此请参考一下。

  • 语言实现模式。我讨厌antlr,但是这本书看起来很好。如果您都不喜欢antlr,那么解析“解析技术:实用指南”会很有帮助。

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

    第10章共分30页(快速介绍IMO)。但是您可能还会对其他章节感兴趣。

    • 10个建筑字节码解释器
      • 10.1编程字节码解释器。。
      • 10.2定义汇编语言语法
      • 10.3字节码机器体系结构。。。。。
      • 10.4从这里去哪里。。。。。。。。。。
      • 第26页。字节码汇编器。。。。。。。。。。。
      • 第27页。基于堆栈的字节码解释器。。。
      • 第28页。基于寄存器的字节码解释器
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • Lua 5.0的实现这是一篇有关基于寄存器的字节码机器的好论文。甚至为了它读一读。

    • Lisp小块。本书教导了如何编写2个可编译为C的schme编译器。从本书中可以学到很多东西。我拥有这本书的副本,对任何感兴趣的人来说,这都是不错的选择,但也许不是您想要的。

      这是对整个Lisp语言族(即Lisp,Scheme和相关方言)的语义和实现的全面说明。它描述了11个解释器和2个编译器...

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

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

关于该主题的邮件列表,jvm-languages。

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


Are you planning to upload the code to anyplace?我不感到自豪的是代码:( ...我也许会重写整个事情反正如果我这样做,我会让你知道非常感谢你的建议。

2

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

许多指令的形式为?name,其中?i如果该指令适用于带有整数类型和a它是否与引用类型的作品。

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

对于我大学的编译器课程,我们使用Jasmin汇编程序。我不知道这是否是最好的方法,但是至少这是一个简单的起点。

这是旧版本JVM 的指令参考,与新版本相比,它可能包含的指令更少。


0

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

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

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


与JVM进行编译相比,编译JVM将使代码的运行范围更加广泛。此外,编译为字节码将使代码有可能做一些Java语言本身无法实现的事情。
supercat

0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.