如何创建自己的针对JVM的编程语言?

时间:2014-09-23 15:54:13

标签: compiler-construction jvm programming-languages

我想创建自己的针对JVM的编程语言。我不确定该怎么做。我必须创建自己的编译器吗?所有编程语言都有独特的编译器,还是现有的编译器可以适应?

我找到了一些有关定位.NET CLI的信息。

我还在编译器设计中找到了Dragon Book

3 个答案:

答案 0 :(得分:6)

是的,每种语言都有自己的编译器。有几种类型的编译器可以编写,每一种都变得更复杂,并建立在前一个:

  1. 识别器,只回答输入源是否有效语法,
  2. 解析器,创建输入源的内存表示(称为AST - 抽象语法树),
  3. 编译器(生成输入的翻译形式),
  4. 优化编译器,为3,但在生成输出之前优化AST。
  5. 所有这些编译器表单通常都会重用专门用于帮助编译不同阶段的工具。简而言之:

    解析:我建议将parboiled用于Java。较旧的工具曾经是lex和yacc的变种,两个unix工具用于解析的词法和语法阶段。 ANTLR和Javacc是在JVM上运行的两个示例;然而,煮熟的只是很棒。

    AST :我不知道这里有任何工具,可以重用其他JVM语言中的模型,例如javac,但我个人会自己创建。

    输出生成:一种快速的方法是生成Java源代码,这有一些限制,但总体来说是测试水的绝佳方法。当/如果您决定继续生成JVM字节代码时,可以找到一组辅助库here。但是在尝试该路由之前,有很多关于JVM的知识,Oracle的JVM规范/书籍是强制性的读取。

    对于一般知识,llvm tutorial非常好,它非常简短且写得很好。我知道你说你想要定位JVM,但本教程几乎所有内容都将帮助你理解所需的部件。

    我建议遵循本教程,并使用Java重写它。它的步骤非常符合逻辑。基本上,人们会为一种非常简单的语言编写识别器,例如只有'1 + 2'。然后为该语言编写一个解释器。这将是一个非常合理的停止点,许多语言被解释; Java也是这样开始的。可选地,然后可以继续发出目标输出,首先是Java源代码。这个代码相当短,并且比第一次完全写入任何单个图层时更快地给出反馈。如果你走这条路的话,有很多机会消耗你的编码时间。

答案 1 :(得分:4)

Chris K.给出了一个很好的答案,但是,有一点我(作为一个至少已经为非平凡的JVM语言编写了一个可用编译器的人)必须严格不同意:

代码生成器应该在开始时生成Java(或者,如果你喜欢,Scala,Ceylon,Kotlin,Clojure,......无论你喜欢什么)代码,原因如下:

  • 其他任务(lexing,解析,维护编译器状态a.k.a符号表,语义分析等)已经足够了。因此,学习另一个图书馆是过度的,并将大大延迟你的第一个结果。
  • 一旦你拥有了包括代码生成在内的所有内容并编译了你的第一个程序,你就会发现你的编译器充满了错误。更容易看到这些错误表现在非敏感或错误的Java代码中,而不是错误的类文件。您是希望从字节码验证程序中获取一条神秘的消息,还是以文本形式查看生成的代码?)
  • 代码生成应该是一个单独的模块,编译器的其余部分中的任何内容都不依赖于(或应该依赖于)代码生成。因此,一旦你确定你的编译器确实可以理解它的输入(证明哪些是可编译的java代码可以进行某些测试等等),就可以相对容易地替换它。可以肯定的是,只要类文件生成不是100%万无一失,它应该是一个选项,无论是用Java还是二进制生成代码。这样,你可以将测试程序编译成Java和字节代码,并运行带有两种结果的测试。这样可以在案例中进行错误分析生成的类文件突然失败的地方非常容易。)

我个人甚至不会开始生成类文件,直到用你自己的语言编写的编译器可以将自己编译成java,并且生成的程序可以将编译器源编译为完全相同的java代码。

答案 2 :(得分:3)

最简单的方法是使用MPS http://www.jetbrains.com/mps/ +您将获得IDE支持作为奖励