解析树上下文节点的生成访问器不符合getProperty()/ isProperty()/ hasProperty()标准。因此,ST无法直接应用于解析树。似乎有3种方法可以将ST应用于生成的解析树:
是否有Antlr4选项生成符合getProperty()/ isProperty()/ hasProperty()标准的解析树上下文节点的访问器?或者是否有ST4选项允许它访问property()而不是查找getProperty()?
简单地使用根上下文节点作为参数实例化ST模板并让ST遍历树是很好的。
答案 0 :(得分:0)
只是想分享一个解决方案,几乎可以避免重复工作,同时使用我的问题中的方法#1。
步骤1:创建一个模型适配器,它使用反射来调用不符合getProperty()/ isProperty()/ hasProperty()标准的方法。
private static class MyModelAdaptor extends ObjectModelAdaptor {
@Override
public synchronized Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName) throws STNoSuchPropertyException {
try {
return super.getProperty(interp, self, o, property, propertyName);
} catch (STNoSuchPropertyException noProperty) {
final Class<?> cls = o.getClass();
try {
return cls.getMethod(propertyName).invoke(o);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw noProperty;
}
}
}
}
步骤2:注册模型适配器
public static STGroup registerAdaptors(STGroup stg) {
final MyModelAdaptor adaptor = new MyModelAdaptor();
for (final Class<?> cls : MyParser.class.getDeclaredClasses()) {
if (isSubclassOf(cls, ParserRuleContext.class)) {
stg.registerModelAdaptor(cls, adaptor);
}
}
return stg;
}
步骤3:实现isSubclassOf()方法,以便registerAdaptors()编译:
private static boolean isSubclassOf(Class<?> cls, Class<?> superCls) {
while (cls != null) {
if (cls == superCls) {
return true;
}
cls = cls.getSuperclass();
}
return false;
}