首页 > 解决方案 > Java - 从 ANTLR 4 访问者实现生成 JVM 字节码

问题描述

我正在开发一种在 ANTLR 4 及其访问者模式的帮助下用 Java 实现的语言。现在我想做的是从访问者模式中实现的代码中,生成以后可以在 Java 虚拟机上执行的 JVM 字节码。

因此,例如,给定以下代码(假设这是我正在创建的语言):

int a = 1;
int b = 2;
int c = 3;
int d = 4;
if (a == b && c == d && a == d) {
    System.out.println("b = c");
} else {
    System.out.println("No!");
}

我在 ANTLR 4 的访问者模式中实现了以下功能,它处理我的语言的不同指令(赋值、if、逻辑和关系比较等):

// ...
void ifStatement(...) {
    // ...
}
// &&, ||, !
void logicalComparison(...) {
    // ...
}
// ==, !=, <=, >=, <, >
void relationalComparison(...) {
    // ...
}
//...

我遇到的问题是,当我为if语句生成代码时,我需要一种方法来记住比较的位置,这样我就可以在生成else语句后返回,放置它的位置,这样如果条件不满足。

生成字节码的最佳方法是什么?

标签: javajvmantlr4bytecodevisitor-pattern

解决方案


您可以将标签与goto字节码一起使用。根据您使用的代码生成工具,它可能是这样的

// Visit your condition so its result is pushed on the stack

// Create three new labels
int iflab   = ++labels; // Label to jump to if the condition was true
int elselab = ++labels; // Label to jump to if the condition was false
int donelab = ++labels; // Label to jump to once done executing either branches

generate("ifne label" + iflab);
generate("goto label" + elselab);

generate("label" + iflab + ":");
// visit the statement needing to be executed if the condition was true
generate("goto label" + donelab);

generate("label" + elselab + ":");
// visit the statement needing to be executed if the condition was false (if there is one)
generate("goto label" + donelab);

println("label" + donelab + ":");
// You are done with this statement, keep visiting the following statements.

这是未优化的(创建和 goto 的标签太多),但应该很清楚。generate 方法只是将字节码写入文件,我在写这个时使用的是Jasmin 。使用ASM或任何其他 JVM 字节码工具应该是类似的。


推荐阅读