JDK 1.6 имеет возможность динамически компилировать классы Java (см. getSystemJavaCompiler ).Это может быть использовано для компиляции Java из исходного кода без манипулирования байтовым кодом или временных файлов.Мы делаем это как способ улучшить производительность некоторого кода API отражения, но он также будет легко служить вашим целям.
Создание исходного файла 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<JavaFileObject> files = new ArrayList<JavaFileObject>();
files.add(new JavaSourceFromString("org.example.DynamicClass", sourceCode));
compiler.getTask(null, fileManager, null, null, null, files).call();
Затем вы динамически загружаете вновь созданные файлы классов.
В качестве альтернативы используйте манипулирование байтовым кодом (например, ASM ) для создания классов на лету.
В качестве другой альтернативы есть библиотека компиляции байт-кода Scala CAFEBABE .Я не использовал его лично, но он, похоже, больше ориентирован на создание нового языка JVM.
Что касается части синтаксического анализа, то Antlr должен служить.