在Java中创建自定义解释器:从哪里开始?

3
我们公司使用自己的脚本语言进行编程,但是他们希望创建一个解释器,将这些脚本代码转换为Java。这种脚本语言非常严谨,因此这不是小事。
我被要求完成这项任务,但这似乎并不是一个简单的挑战。在我做任何愚蠢的事情并开始编写数十亿行的解析之前,我应该知道什么?我应该从哪里开始才能做到这一点?
PS:我想将脚本文件转换为.java源代码,而不是直接转换为字节码。

1
有没有特别的原因直接转换为Java,而不是通过Java解释器运行(即使用基于Java的脚本引擎来运行您的脚本语言)? - Charles Goodwin
@Charles 是的,但很难解释。 - Xorty
那么很难回答... - Adriaan Koster
你为什么期望“数十亿行”?一个简单的源到源编译器几乎总是比解释器更简单。 - SK-logic
5个回答

5

如果您想将脚本翻译成Java,那么它不是解释器,而是编译器。如果您只想在读取期间执行脚本,则它是解释器。

但是,您应该查看JavaCCAntlr。它们都适用于编译或解释器任务。您必须指定语言的语法规则,并且必须在Java中编写一些其他逻辑,实现脚本语言的语义。如果您想制作解释器,则编写的Java代码将生成进一步的Java(或任何)代码。如果您想要编译器,则编写的Java代码将直接执行脚本。

还有一个很好的概念需要了解,那就是抽象语法树

这里有一个关于更多词法分析器和语法分析器生成器的综合列表。


将Groovy转换为Java是编译器吗?即使您必须将Java编译为字节码? - Charles Goodwin
是的,它是。根据维基百科:“编译器是一种将用编程语言编写的源代码转换为另一种计算机语言的计算机程序。”“...解释器通常指执行即执行用编程语言编写的指令的计算机程序。” - pcjuzer
@Charles,这个问题有点学术性质。如果你从一种“高级”语言转换到另一种语言,也可以称之为“源到源”的翻译。这意味着它是一种“编译器”,但通常不像真正的编译器那样复杂。例如,如果你从C语言翻译到Java语言,你可以“假设”C源代码在C编译器中编译通过。基于这个假设,你可以省略各种语义检查(例如类型检查),而真正的编译器需要执行这些检查。 - Angel O'Sphere
@Xorty:我怀疑这个!编译器构建技术在过去几十年中取得了巨大的进步!你真的应该看看ANTLR! - Angel O'Sphere
@Xorty,没有一种语言不能表示为树形结构(如果需要循环引用,则使用符号性反向引用)。 - SK-logic
现如今,随着更先进的JavaScript前端技术的兴起,"转译"这个术语开始流行起来,指的是将一种语言转换为另一种在相同抽象层级上的语言。但这并不改变原始答案。 - pcjuzer

3

听起来是一个有趣的任务 :-) 你能描述一下这个脚本语言吗?

我会看看 javax.script 包,可能会有类似的脚本语言(我知道 Scala 用作脚本语言)。此外,我会查看 javax.tools.JavaCompiler。我现在正在构建一个Java源代码生成器(在运行时创建和编译类代理)。生成Java源代码比生成字节码要容易得多。

至于解析,我会首先为您的语言创建一个好的BNF。有一个用于生成HTML铁路图的工具。编写BNF时会犯错误,但是如果查看铁路图,就会发现它们。这将确保您不会制作无法解析的东西。

我知道大多数人会建议使用ANTLR或JavaCC,但我会写自己的递归下降解析器,因为我认为它更容易且更灵活(我已经做过几次并知道我在说什么)。一个示例是Jackrabbit SQL-2解析器


嗨,这是一种过程式脚本语言 - 基本的语言结构(循环,结构,条件)以及许多可调用的函数和过程。没有方法,没有类...它是过程式的,不是面向对象的。 - Xorty
@Xorty,如果该语言中没有反射,没有类似于eval的功能,也没有任何宏,那么你的任务就相当简单了。如果你已经有一个工作的解释器,那么很可能你可以轻松地修改它以发出Java代码而不是执行任何内容。你最大的痛点将是将运行时(库、FFI等)移植到Java中,而不是语言本身。 - SK-logic

2
你可以尝试使用 javacc 解析器。

0
我建议你找一本关于用Java编写编译器/解释器的书籍。有很多选择,比如Writing Compilers and Interpreters
在开始编写词法分析器/语法分析器等之前,最好先了解整个大局。
或者,如果你想直接开始尝试,可以使用ANTLR。

0

我建议你使用 antlr Java 库进行语言识别。它是 JVM 大多数语言都在使用的库。虽然我个人没有使用过,但我知道 Groovy 就是使用这个库构建的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接