我正在尝试为最终用户公开构建在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'&& right(name,1)=='n')这样的表达式[名字中的第一个字符是s,last是n ] - 我希望等于检查单个等于而不是双等于和/和而不是&&或。和()所以类似(左(名称,1)='S'和右(名称,1)='n')
实现此类自定义的最佳方法是什么?
答案 0 :(得分:1)
最好的方法是使用自定义解析器(因为你不希望你的用户编写任何groovy),然后使用groovy实际实现后端
例如:非常具有指示性,您的实施可能会有所不同
(left(name,1)='S')
对于上面的snipet,标记可以是方法:left,args:((var:name),(val:1)),exp:EQUALS,val:'S' 在后面有一张地图,它将你的代币等同于groovy等价物
然后,您可以针对groovy类触发解析的标记,当然方法和参数不存在,使用一些常规技巧将其转换为您的实际实现1