Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Scoping on an external EMF Model(Scoping on an external EMF Model)
Scoping on an external EMF Model [message #1782878] Fri, 02 March 2018 23:40 Go to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Hi,

I am trying to do something with Xtext and I couldn't find (or understand) information out there that clearly states if and how it is feasible, hence the request for help :(

I have an existing metamodel in a project A. I import this metamodel in a newly created Xtext project B and I refer to the elements defined in this imported metamodel in my grammar. So the root node of my grammar is a node (non-root) in the imported metamodel. To refine, in A's metamodel, is a node named "Expression" which is the root node of my Xtext's Expression grammar.

The reason I have this structure is because I want to pass the "Expression" at runtime to the Parser generated by Xtext and I want it to return me the parsed model of the expression. That is, I want to pass a string "1 + 2" and Xtext's parser should be able to tell me whther this string is parsabe or not and if it is, I should get a AST/parsed model representation of the string according to the grammar rules defined in my Xtext Grammar file.

This works -- When I pass a string from project A (call a method of the ParseContentHelper which uses the parser generated by Xtext), it is correctly parsed and the ParseContentHelper returns me an instance of the parsed model (the string I passed) where the root node is "Expression" defined in A's Metamodel. Now, I just say that Expression instance in A's memory (the Expression instance in the EMF - parsed model representation) is actually "Expression" instance returned by Xtext (and plug it in at runtime).

Hence, by using this setup, I am able to parse my Expression models which are a subset of the bigger metamodel in A. However, I am stuck when it comes to references. If I pass a string that contains a reference variable, say "1 + foo", then I would like Xtext to be actually able to refer to the "foo" object in A's memory (which is part of the model that EMF parsed for A). In other words, I want to be able to reference the symbol table or the model that is contained in A's memory. According to my understanding, even if you import a metamodel in an Xtext project and your grammar rules refer to this imported metamodel, when you pass a string to the parser and ask it to parse it, it will create a new object(a tree) which will be the CST representation of your Grammar. This object does not know anything about the EMF-parsed model of the imported metamodel itself. They are two separate objects with zero visibility to each other.

Is there some way I can refer to this EMF parsed model when I do my scoping? This is how I run the project -- First, I run the main file of my bigger project A, then after doing some stuff, I do something, say create a sequence diagram where I construct a method call such that the parameter of this method call is an expression. At this point, I call a method in the ParseContentHelper in Xtext project B and pass this expression to it as parameter. This returns to me the parsed Expression and since the metamodel in B is a subset of metamodel A, it works. If I pass "1 + foo" now, I get a parsed model that says foo is a CST Node "Reference" which is part of Metmodel B (hence also A), but I now have a "Reference" object with name "Foo" in A and one in B, yet I would need to manually search for A's Foo and then say its the same as B's Foo to link the two together. I know Xtext does this automatically using Qualified Names via its scoping mechanism, but all examples I looked at so far are such that the whole metamodel is Xtext's grammar basically, so its one parsed model that Xtext is working through.

Long post short, is this possible? If yes, then can someone point me in the right direction as to what I should be looking at?

Thank You.
Re: Scoping on an external EMF Model [message #1782883 is a reply to message #1782878] Sat, 03 March 2018 07:43 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi to be able to refer to non Xtext emf Models you need to provide a resource service provider for you emf metamodel
As described here https://christiandietrich.wordpress.com/2011/07/17/xtext-2-0-and-uml/ or here https://typefox.io/linking-xtext-models-with-other-emf-models



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Scoping on an external EMF Model [message #1782890 is a reply to message #1782883] Sat, 03 March 2018 19:39 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Thanks Christian! I will look at the examples and will probably be back for more questions.

Appreciate your help.
Re: Scoping on an external EMF Model [message #1782974 is a reply to message #1782890] Tue, 06 March 2018 00:13 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
I looked at the articles, particularly at the typefox one which I tried to implement and I am afraid, I can't figure it out :(

After downloading the git example, I do a "run as Eclipse Application" on io.typefox.xtextxmi.xtree.ui. Then I create a new project and two files in it. However, my .tree file is never parsed. What I am missing here? (Attached screenshot)

Sorry, newbie trouble!!


  • Attachment: 1.png
    (Size: 38.24KB, Downloaded 161 times)
  • Attachment: 2.png
    (Size: 35.68KB, Downloaded 166 times)
Re: Scoping on an external EMF Model [message #1782975 is a reply to message #1782974] Tue, 06 March 2018 00:21 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Adding another screenshot of the exception.
  • Attachment: 3.png
    (Size: 46.77KB, Downloaded 91 times)
Re: Scoping on an external EMF Model [message #1782984 is a reply to message #1782975] Tue, 06 March 2018 05:30 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Is tree an xml file or not?
Did you generate the code for dsl and emf metamodel?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 06 March 2018 05:32]

Report message to a moderator

Re: Scoping on an external EMF Model [message #1783099 is a reply to message #1782984] Wed, 07 March 2018 21:39 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Hi Christian,

Thanks for replying. I did not generate any code. I merely cloned the GitHub project and then in the new eclipse instance,created a project and two files -- a .tree file and a .xtree file.
It is working now however, after I create the .tree file via Eclipse support (Instead of File -> New -> File, I create one like: File -> New ->Other -> Tree Model (via Example EMF Model Creation wizards)).
Re: Scoping on an external EMF Model [message #1783103 is a reply to message #1783099] Thu, 08 March 2018 00:12 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Another Question:

I do not need Eclipse support in my project, so as the tutorial said, I only followed Step 1.

Referring to TypeFox

If you want to have the same functionality in a plain Java process, you have to manually create the injector and initialize the EMF registries, as we did in the TreeStandaloneSetup.


So, I only have one Xtext project where I created a TreeStandaloneSetup (same as in the tutorial). I also have another class ParseContentHelper where, using XtreeStandaloneSetup, I was able to get an instance of an injector which I used to do a "injector.getInstance(ParseHelper.class)". Using this ParseHelper instance, I could do parseHelper.parse(MyXtreeModel) and this returned me a CST of my Xtree model ("model" in the code below). Now using another injector "injectorTree" , I have the CST of my Tree Model ("rootObj" in the code below).

So, I have two CSTs - one is for model (for Xtree) and one for rootObj (for Tree). All good so far. Trouble is that I don't understand, how do I tell Xtext when it parses Xtree model that (referring to sample models below) TreeNode in an Xtree model is actually the Node "TreeNode" in Tree's model that it is referring to.
I know it works via Eclipse support, but how do I do it programatically?

To explain it better, I have two cases below -- In Case 1, I pass "Foo ( related Bar children Bar ( related Foo.Bar) )" as arguments to the compile method.
In Case 2, I pass "Foo ( related TreeNode children Bar ( related TreeNode.Baby.Kid ) )"

As you can see in attached screenshots, in case 2, it correctly parsed "TreeNode" as a node but is unable to refer to an existing "TreeNode" in the Tree model.
I could do this by constructing a sort of symbol table on my own but since Xtext is doing it already, I wouldn't want to reinvent the wheel but instead understand how its doing it.


ParseContentHelper Class


public class ParseContentHelper {

/**
* Creates a new instance of the model.
*/
private Node model;

public Node getModel() {
return model;
}

public void setModel(Node model) {
this.model = model;
}

/**
*
* @param args
* String that will be parsed to model
* @return
* parsed model
*/
public Node compile(String args) {

Injector injector = new XtreeStandaloneSetup().createInjectorAndDoEMFRegistration();
Injector injectorTree = new TreeStandaloneSetup().createInjectorAndDoEMFRegistration();

ParseHelper<EObject> parseHelper = injector.getInstance(ParseHelper.class);

File f = new File("/Users/rohit/git/<Random Path>/SomeFile.tree");
URI fileURI = URI.createFileURI(f.getAbsolutePath());
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("tree", new EcoreResourceFactoryImpl ());

XtextResourceSet resourceSet = injectorTree.getInstance(XtextResourceSet.class);
org.eclipse.emf.ecore.resource.Resource resource = resourceSet.getResource(URI.createFileURI(f.getAbsolutePath()), true);

// rootObj gives me access to the parsed Tree Model
EObject rootObj = resource.getContents().get(0);

try {
model = (Node) parseHelper.parse(args);
// CHECKSTYLE:IGNORE IllegalCatch: API (Parsehelper.parse()) throws java.lang.Exception
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// model is the model parsed by Xtext
return model;

}

public static void main(String[] args) {

ParseContentHelper p = new ParseContentHelper();
Node vs = p.compile("Foo ( related TreeNode children Bar ( related TreeNode.Baby.Kid ) )");
}

}


Tree Model


<?xml version="1.0" encoding="UTF-8"?>
<tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.typefox.io/xtextxmi/tree" name="TreeNode">
<children name="Baby"/>
<children name="Baby">
<children name="Kid"/>
</children>
</tree:Node>



Xtree Sample Model

Foo (
related
TreeNode
children
Bar
( related
TreeNode.Baby.Kid
))


Thank You!!
  • Attachment: Case1.jpg
    (Size: 91.94KB, Downloaded 92 times)
  • Attachment: Case2.jpg
    (Size: 87.97KB, Downloaded 88 times)
Re: Scoping on an external EMF Model [message #1783104 is a reply to message #1783103] Thu, 08 March 2018 00:38 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Oops, just realized, I probably need to look at XtreeFragmentProvider. Let me know if my analysis is correct or if I need to look elsewhere.

Thanks!
Re: Scoping on an external EMF Model [message #1783110 is a reply to message #1783104] Thu, 08 March 2018 03:39 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Rohit Verma wrote on Thu, 08 March 2018 00:38
Oops, just realized, I probably need to look at XtreeFragmentProvider. Let me know if my analysis is correct or if I need to look elsewhere.

Thanks!

Looked at this and don't know how to get the same functionality in a StandaloneSetup. Plz help.
Re: Scoping on an external EMF Model [message #1783120 is a reply to message #1783110] Thu, 08 March 2018 06:07 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
i dont understand what is not working for you.
please explain....

i dont understand why you use a parseshelper the way you use it
if all resources are in different resourcesets they wont see each other.


new TreeStandaloneSetup().createInjectorAndDoEMFRegistration();
Injector injector = new XtreeStandaloneSetup().createInjectorAndDoEMFRegistration();
....
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
....
model = (Node) parseHelper.parse(args, resourceSet);


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Scoping on an external EMF Model [message #1783121 is a reply to message #1783120] Thu, 08 March 2018 06:59 Go to previous messageGo to next message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Christian Dietrich wrote on Thu, 08 March 2018 06:07
i dont understand what is not working for you.
please explain....

i dont understand why you use a parseshelper the way you use it
if all resources are in different resourcesets they wont see each other.


new TreeStandaloneSetup().createInjectorAndDoEMFRegistration();
Injector injector = new XtreeStandaloneSetup().createInjectorAndDoEMFRegistration();
....
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
....
model = (Node) parseHelper.parse(args, resourceSet);


Hi Christian,

I am using ParseHelper because I want Xtext to return me the CST of a string (XTree Model) that I will pass as a parameter to the compile method.

This is because the project requirements are such that I will always have a XMI-serialized model saved somewhere (e.g. tree in this example) and a string that I will need to parse ( e.g. xtree model in this example). The root of the CST of the Xtree model will be of the same type as one of the nodes of the CST of the Tree model. So, once have two CSTs, I am required to "plug in" the root of my Xtree's CST at the right location in the Tree's CST. I wanted to see this done automatically through Xtext the same way it works at runtime (using XtreeFragmentProvider). Like how its able to identify that TreeNode.Baby exists in a .tree file when we are editing a .xtree file (so both tree and xtree are linked). In other words, how can I use XtreeFragmentProvider in a standalone manner? As you can see, I have two resources in different resourcesets which don't see each other.

I understand that I might be following an incorrect approach, could you please point me in the right direction?

So far, I have thought about creating my own symbol table (for Tree) and then searching through it to find the a node where the type == type of Xtree CST's Root node and having the same unique identifier of some sort (will add some logic here).

Thanks!


Re: Scoping on an external EMF Model [message #1783126 is a reply to message #1783121] Thu, 08 March 2018 07:55 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
as i said: if you used the SAME resourceset it will work.
unfortunately parsehelper does not make that obviously. this is why i dislike it if people use that.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Scoping on an external EMF Model [message #1790266 is a reply to message #1783126] Thu, 07 June 2018 16:28 Go to previous message
Rohit Verma is currently offline Rohit VermaFriend
Messages: 21
Registered: August 2017
Junior Member
Thanks Christian! Finally got it to work when I used the same resourceset.
Previous Topic:how to unit test of generator
Next Topic:Handling characters that return ecore::EChar and identifiers
Goto Forum:
  


Current Time: Thu Mar 28 08:50:40 GMT 2024

Powered by FUDForum. Page generated in 0.04055 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top