javaeclipseparsingabstract-syntax-treeocl

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


for context - the OCL Expressions will be given alongside an "Ecore" file that holds information regarding the UML that the expression is associated with.

As a part of a research I'm conducting I'm trying to parse an OCL Expression into an Abstract Syntax Tree (AST) which I want to be able to iterate through, see information for each node, and make changes. The problem is that all the software I found that have anything to do with OCL either - aren't supported by modern applications because they are just too out of date or are meant to validate an expression or return a boolean value for the expression given an instance of a certain model.

I did manage to view an AST for a given Expression using Eclipse MDE but that was only through the UI with no option to export it (as far as I noticed).

Screenshot

The closest solution I found was DresdenOCL (https://github.com/dresden-ocl/standalone) which after scouting the code for a long while I found a function that returns a "TreeIterator" Object for a certain "OCLResource" object. The problem is the nodes on the tree are made up of classes that were meant for backend use only - meaning I can't get any real information out of them except for the class name, memory location and sometimes a string value that represents a part of the Expression. The fact that there is no indication of hierarchy except for the order in which it was printed in is also a big issue. I also tried using Reflection on these nodes but from what I saw those classes don't have any useful functions or fields that might help.

I've also provided some photos as an example including input and output. Photos:

Input

Function

Output

My best option at the moment is to painstakingly study these DresdenOCL outputs until I have a good understanding of how they are built and then write a code myself that takes these outputs and builds an AST that I can work with properly, but that might take a long time, which is why I'm bringing the issue here hoping that some beautiful stranger might show up with a better solution.

any advice would be greatly appreciated, thanks in advance.


Solution

  • You might have more luck with USE-OCL (by Uni Bremen, available at sourceforge). It is open-source, and in the package src/main/org/tzi/parser you find an AST representation with its node elements, along with parser/compiler classes to create the AST from a String input. It seems pretty comprehensive and might be suitable for an integration into another tool.

    I have not worked with USE's code myself yet, but I use the tool in lectures. It is reliable, stable and actively maintained.

    Edit: The following snippet transforms an OCL Expression into the compiled internal representation you can find in package org.tzi.use.uml.ocl.expr. Looking at the function compileExpression you can find how to transform into the AST representation of package org.tzi.use.parser.ocl. Whatever suits you better. The used UML model is empty, therefore there is not context to be used in the expression. However, transforming a model into the USE model format might not be too much effort.

        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());
        }