Java-从Antlr4访问者实现生成JVM字节码

Java-从Antlr4访问者实现生成JVM字节码,java,jvm,antlr4,bytecode,visitor-pattern,Java,Jvm,Antlr4,Bytecode,Visitor Pattern,我正在开发一种语言,该语言在Antlr4及其访问者模式的帮助下用Java实现。现在我要做的是从访问者模式中实现的代码中生成JVM字节码,稍后可以在Java虚拟机上执行 例如,给定以下代码(假设这就是我正在创建的语言): 我在ANTLR 4的访问者模式中实现了以下功能,该模式处理我语言的不同指令(赋值、if、逻辑和关系比较等): /。。。 void ifStatement(…){ // ... } // &&, ||, ! void逻辑比较(…){ // ... } // ==, !=, =,

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

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

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

/。。。
void ifStatement(…){
// ...
}
// &&, ||, !
void逻辑比较(…){
// ...
}
// ==, !=, =, 
无效关系比较(…){
// ...
}
//...
我遇到的问题是,当我为
if
语句生成代码时,我需要一种方法来记住比较的位置,以便在生成
else
语句后返回,以放置其位置,以便在条件未满足时可以跳转


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

您可以将标签与转到字节码一起使用。根据您使用的代码生成工具的不同,它可能是类似的

//访问您的条件,以便将其结果推送到堆栈上
//创建三个新标签
int iflab=++标签;//如果条件为真,则跳转到的标签
int-elselab=++标签;//如果条件为false,则跳转到的标签
int donelab=++标签;//执行任一分支后跳转到的标签
生成(“ifne标签”+iflab);
生成(“转到标签”+elselab);
生成(“标签“+iflab+”:”);
//如果条件为true,请访问需要执行的语句
生成(“转到标签”+donelab);
生成(“标签”+elselab+”:”;
//如果条件为false(如果存在),请访问需要执行的语句
生成(“转到标签”+donelab);
println(“标签“+donelab+”:”);
//如果您已完成此语句,请继续访问以下语句。

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

ASM允许您在通过
visitLabel(…)
定义对象的实际位置之前创建和使用
Label
对象。我不知道细节,但是解析器访问者API应该支持将父构造的上下文信息传递给子表达式。不需要更多。@Holger问题是,在处理逻辑比较语句(&&、| |、!、…)时,我如何知道何时跳转?我需要一些方法来了解if条件中的内容,并以某种方式保存if语句不同部分的标签。如前所述,我不知道ANTLR为上下传递上下文信息提供了哪些选项,但必须有一些选项。通常,编译器首先创建一个表示,请参见,然后处理该表示以生成代码。问题是,在处理逻辑比较语句(&&、| |、!、…)时,如何知道何时跳转?我需要一些方法来了解if条件中的内容,并以某种方式保存if语句不同部分的标签。如果我有嵌套的if语句呢?
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!");
}
// ...
void ifStatement(...) {
    // ...
}
// &&, ||, !
void logicalComparison(...) {
    // ...
}
// ==, !=, <=, >=, <, >
void relationalComparison(...) {
    // ...
}
//...