GEGlobalResearch / DARPA-ASKE-TA1

ANSWER Project to demonstrate knowledge-driven extraction of scientific models from code and texts
Other
7 stars 5 forks source link

how to get the location information of an EObject without leading comments #97

Closed crapo closed 4 years ago

crapo commented 4 years ago

@kittaakos , I have this in a Dialog window:

uri "http://sadl.org/InLineExtraction.dialog" alias ile.

import "http://aske.ge.com/hypersonicsV2".

//Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
//Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
//This equation is shown in the red box on this slide and relates the mass flow rate to the flow area A, total pressure pt and temperature Tt of the flow, the Mach number M, the ratio of specific heats of the gas gam, and the gas constant R. In many applications, we are interested in the weight flow rate, which is the mass flow rate multiplied by the gravitational constant (32.2 ft/sec ^2 in Imperial units, or 9.8 m/sec^2 in Metric units). ".

External foobar(decimal x) returns decimal: "http://some/host/function".

In other words, there are comments before the statement "External foobar....". I can get the text of just the statement with this: NodeModelUtils.getTokenText(NodeModelUtils.getNode(element))

How can I get the starting point of the statement? This NodeModelUtils.getNode(element).getTotalOffset() gives the starting point of the comment before the statement. Ditto for total length and total end offset. For example, NodeModelUtils.getNode(element).getTotalLength() returns 639, hardly the length I'm looking for...

kittaakos commented 4 years ago

I have this in a Dialog window:

Can you please format your DSL? I do not understand your model input. Here is a cheat-sheet for code-blocks. Thank you!

This NodeModelUtils.getNode(element).getTotalOffset() gives the starting point of the comment before the statement.

Have you tried NodeModelUtils.findActualNodeFor(element)?

crapo commented 4 years ago

I edited the original issue to make the code readable. Yes to your question, I was using this:

                INode node = NodeModelUtils.findActualNodeFor(element);
        if (node != null) {
            String txt = node.getText();
            int start = node.getTotalOffset();
            int length = node.getTotalLength();
            int end = node.getTotalEndOffset();
            modelElements.add(new ModelElementInfo(element, txt, start, length, end, false));
        }

Where element is the EObject for the ExternalEquationStatement. This returned the "txt" to be the two comments plus the ExternalEquationStatement text. The "start" was the location of the end of the import statement, the length 639, clearly including the comment, etc.

I was getting the larger text found in this way, and then locating the actual text to adjust the length and start, but that seems a little too tricky and wasn't always working.

kittaakos commented 4 years ago

I edited the original issue to make the code readable.

Thank you!

I was using this:

Just use getOffset and getLength.

Here is a test case demonstrating the differences:

@RunWith(XtextRunner)
@InjectWith(SADLInjectorProvider)
class GH_97 extends AbstractSadlTest {

    static val MODEL = '''
        uri "http://sadl.org/x.sadl".

        /**
         * This is some comment.
         */
        Bar is a class.
        MyBar is a Bar.

        //Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
        //Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
        //This equation is shown in the red box on this slide and relates the mass flow rate to the flow area A, total pressure pt and temperature Tt of the flow, the Mach number M, the ratio of specific heats of the gas gam, and the gas constant R. In many applications, we are interested in the weight flow rate, which is the mass flow rate multiplied by the gravitational constant (32.2 ft/sec ^2 in Imperial units, or 9.8 m/sec^2 in Metric units). ".

        External foobar(decimal x) returns decimal: "http://some/host/function".

        Foo is a class.
        MyFoo is a Foo.
    '''

    @Test
    def void lenghtWithComment() {
        val resource = MODEL.sadl;
        val dsl = resource.parseResult.rootNode.text;
        val model = resource.contents.head as SadlModel;
        val element = model.elements.get(2); // Get External `foobar`
        val node = NodeModelUtils.findActualNodeFor(element);
        assertNotNull(node);

        val offset = node.offset;
        val length = node.length;
        println(dsl.substring(offset, offset + length));

        val totalOffset = node.totalOffset;
        val totalLength = node.totalLength;
        println(dsl.substring(totalOffset, totalOffset + totalLength));
    }
}

This will print

External foobar(decimal x) returns decimal: "http://some/host/function".

//Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
//Extract from "mdot = (A * pt/sqrt[Tt]) * sqrt(gam/R) * M * [1 + .5 * (gam-1) * M^2 ]^-[(gam + 1)/(gam - 1)/2]
//This equation is shown in the red box on this slide and relates the mass flow rate to the flow area A, total pressure pt and temperature Tt of the flow, the Mach number M, the ratio of specific heats of the gas gam, and the gas constant R. In many applications, we are interested in the weight flow rate, which is the mass flow rate multiplied by the gravitational constant (32.2 ft/sec ^2 in Imperial units, or 9.8 m/sec^2 in Metric units). ".

External foobar(decimal x) returns decimal: "http://some/host/function".

With offset you do not care about hidden nodes, such as comments, if you want total, it includes hidden things too.

crapo commented 4 years ago

That was extremely helpful! Don't know how I've missed that for so long. Thank you!