将 OCL 表达式解析为 AST(抽象语法树)

Parse an OCL Expression into an AST (Abstract Syntax Tree)

for context - OCL 表达式将与“Ecore”文件一起提供,该文件包含有关与表达式关联的 UML 的信息。

作为我正在进行的研究的一部分,我正在尝试将 OCL 表达式解析为抽象语法树 (AST),我希望能够遍历它,查看每个节点的信息,并使变化。问题是我发现的所有软件都与 OCL 有关—— 现代应用程序不支持它们,因为它们太过时了,或者旨在验证表达式或 return 给定特定模型实例的表达式的布尔值。

我确实设法使用 Eclipse MDE 查看了给定表达式的 AST,但这只是通过 UI 没有导出它的选项(据我所知)。

Screenshot

我找到的最接近的解决方案是 DresdenOCL (https://github.com/dresden-ocl/standalone),在搜索代码很长时间后,我发现一个函数 return 是某个“OCLResource”对象的“TreeIterator”对象.问题是树上的节点由 classes 组成,仅供后端使用——这意味着除了 class 名称、内存位置之外,我无法从中获取任何真实信息有时是表示表达式一部分的字符串值。事实上,除了印刷顺序外,没有任何层次结构的迹象,这也是一个大问题。我也尝试在这些节点上使用反射,但据我所见,这些 classes 没有任何有用的函数或可能有帮助的字段。

我还提供了一些照片作为示例,包括输入和输出。 照片:

Input

Function

Output

目前我最好的选择是认真研究这些 DresdenOCL 输出,直到我很好地理解它们是如何构建的,然后自己编写一个代码来获取这些输出并构建一个我可以正确使用的 AST,但这可能需要很长时间,这就是为什么我把这个问题带到这里希望一些美丽的陌生人可能会出现更好的解决方案。

任何建议将不胜感激,提前致谢。

使用 USE-OCL(由 Uni Bremen 开发,可在 sourceforge 获取)可能会更幸运。它是开源的,在 src/main/org/tzi/parser 包中,您可以找到一个带有节点元素的 AST 表示,以及 parser/compiler 类 从字符串输入创建 AST。它看起来非常全面,可能适合集成到另一个工具中。

我自己还没有使用过 USE 的代码,但我在讲座中使用过该工具。它可靠、稳定且维护积极。

编辑:以下代码片段将 OCL 表达式转换为您可以在包 org.tzi.use.uml.ocl.expr 中找到的已编译内部表示。查看函数 compileExpression,您可以找到如何转换为包 org.tzi.use.parser.ocl 的 AST 表示。什么更适合你。使用的 UML 模型是空的,因此表达式中没有要使用的上下文。但是,将模型转换为 USE 模型格式可能并不费力。

    public static void main(String args[]) {
        
        ModelFactory mFactory = new ModelFactory();
        MModel mModel = mFactory.createModel("unnamed");
        MSystem system = new MSystem(mModel);
        
        String input = "Set{1,2,3} ->collect(i|i*2)";
        
        PrintWriter errorPrinter = new PrintWriter(new StringWriter(), true);
        
        Expression expr = OCLCompiler.compileExpression(mModel, input,
                "USE Api", errorPrinter, system.varBindings());
        
        System.out.println(expr.toString());
    }

使用 Eclipse OCL 中的 Complete OCL 编辑器,您可以使用 OCL -> Save Abstract Syntax 上下文菜单操作,或者实际上是 Save Concrete (Xtext) Syntax。如果您需要编程保存,基础功能是 Java 可调用的。

您应该知道,OMG OCL 规范定义的 AST 有许多不足之处,基于 Pivot 的 Eclipse OCL 原型解决方案。