如何以编程方式生成.class文件?

我想为Java的玩具语言编写一个编译器。 我想生成可运行的.class文件。 我想知道什么是可用的最好的库或工具? 我知道我可以学习所有指令的二进制格式并构建我自己的常量池等,但这似乎应该已经完成​​的工作:没有必要重新发明轮子,对吧?

在线搜索我发现了两种不同的Java汇编语言, Jasmin和Jamaica ,但只有Jasmin看起来有些维护。

是否有用于将字节代码写入流的Java库? 这是Apache BCEL的内容吗?

他们的工具是字节码生成的“标准”,就像Antlr用于解析一样吗?


PS-玩具语言是Brainf *** ,我想要一些我可以有一个简单的“语法”的东西,所以我可以专注于生成方面而不是解析部分…将在下一步的后期出现。

ASM和BCEL基本上做类似的事情。 我推荐ASM,因为它支持得更多,更小,并且是最新的JDK。

听起来你正在寻找Apache BCEL :

字节代码工程库(Apache Commons BCEL™)旨在为用户提供分析,创建和操作(二进制)Java类文件(以.class结尾的文件)的便捷方式。

JDK 1.6能够动态编译Java类(请参阅getSystemJavaCompiler )。 这可用于从源代码编译Java而无需字节代码操作或临时文件。 我们这样做是为了提高某些reflectionAPI代码的性能,但它也很容易满足您的目的。

从包含代码的字符串创建Java源文件:

public class JavaSourceFromString extends SimpleJavaFileObject { final String code; JavaSourceFromString(String name, String code) { super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); this.code = code; } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; } } // Use your favorite template language here, like FreeMarker static final String sourceCode = "" + "import org.example.MySomethingObject;" // DynamicStringGetter would define getString as a standard way to get // a String from an object + "public class GetStringDynamic implements DynamicStringGetter {\n" + " public String getString(Object o) {\n" + " MySomethingObject obj = (MySomethingObject) o;\n" + " return o.getSomething();\n" + " }\n" + "}\n"; JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); List files = new ArrayList(); files.add(new JavaSourceFromString("org.example.DynamicClass", sourceCode)); compiler.getTask(null, fileManager, null, null, null, files).call(); 

然后动态加载新创建的类文件。

或者,使用字节代码操作(例如ASM )来动态创建类。

作为另一种选择,有Scala CAFEBABE字节码编译库 。 我没有亲自使用它,但似乎更倾向于创建一个新的JVM语言。

就解析部分而言,Antlr应该服务。

最简单的方法是使用预处理器将您的玩具语言转换为有效的.java源代码,然后使用javac进行编译。 这也是Processing的工作方式。