我试图为最终用户公开构建在groovy之上的表达式引擎 . 我有一些excel样式关键字,用户可以在这些关键字中使用变量(需要在运行时替换)进行评估 . 例如,静态关键字FIRSTCHAR(varName)将返回字符串的第一个字符 . 我有这个在某种程度上工作 .
当前实现我已经覆盖了groovy类加载器来创建一个带有重写的PrimaryClassNodeOperation的编译单元
class MyGroovyClassLoader extends GroovyClassLoader {
protected CompilationUnit createCompilationUnit(
CompilerConfiguration config, CodeSource source) {
CompilationUnit cu = super.createCompilationUnit(config, source);
cu.addPhaseOperation(new PrimaryClassNodeOperation(){
@Override
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
throws CompilationFailedException {
source.getAST().getStatementBlock().visit(visitor);
}
}, Phases.SEMANTIC_ANALYSIS);
return cu;
}
}
然后访问者识别静态表达式和变量表达式 . 但是,使用这种方法我遇到了困难
1)支持带点( . )的变量名,因为dot被认为是属性表达式 . 我可以在此阶段将属性表达式保留为变量表达式 .
2)此外,对于一个表达式(左(名称,1)=='S'&&右(名称,1)=='n')[名字中的第一个字符是s,最后一个是n] - 我想要等于检查是单个等于而不是双等于,和/而不是&&或.and()所以像(左(名,1)='S'和右(名称,1)='n')
实现此类自定义的最佳方法是什么?
1 回答
最好的方法是使用自定义解析器(因为你不希望你的用户编写任何groovy),然后使用groovy实际实现后端
例如:很有说服力,您的实施可能会有所不同
对于上面的snipet,标记可以是方法:left,args:((var:name),(val:1)),exp:EQUALS,val:'S'在后面有一个映射,它将你的标记等同于groovy等价物
然后,您可以针对groovy类触发解析的标记,当然方法和参数不存在,使用一些groovy技巧将其转换为您的实际实现1