1

我正在尝试为最终用户公开基于 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) 使用点 (.) 支持变量名称,因为点被视为属性表达式。我可以在此阶段将属性表达式保留为变量表达式吗?

2) 另外,对于像 (left(name,1)=='S' && right(name,1)=='n') [name 中的第一个字符是 s,最后一个字符是 n] 这样的表达式 - 我想要相等检查是否为单等号而不是双等号,和/AND 而不是 && 或 .and() 类似 (left(name,1)='S' and right(name,1)='n')

实现此类自定义的最佳方法是什么?

4

1 回答 1

1

最好的方法是使用自定义解析器(因为您不希望您的用户编写任何 groovy),然后使用 groovy 实际实现后端

例如:非常具有指示性,您的实施可能会有所不同

(left(name,1)='S')

对于上面的片段,标记可以是 method:left, args:((var:name),(val:1)), exp:EQUALS, val:'S' 在后面有一个映射,它将你的标记等同于 groovy 等价物

然后,您可以针对 groovy 类触发解析的标记,当然方法和参数不存在,使用一些 groovy 技巧将其转换为您的实际实现1

于 2012-11-29T12:05:19.600 回答