Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Cross reference for multiple identifers
Cross reference for multiple identifers [message #1696470] Tue, 26 May 2015 15:11 Go to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Hi,
I have this sample grammar:
Integer_dec:
'Integer' identifiersList=identifier_list ( '=' val=Ivalues) ';'
;

Float_dec:
'float'  identifiersList=identifier_list ( '=' val=Fvalues) ';'
;

constants_dec:
'constant' name=ID '=' val=Cval ';'
;

identifier_list:
identifer=ID (',' otherIdentifiers=ID)* ;

declarations returns Declarations:
Integer_dec
| Float_dec
| constant_dec
;

expression:
leftOP=[Declarations] (operator=op rightOP=[Declarations])*
;

Model:
initialize+=declarations*
expressions+=expression*
;


-------------------------------------------------------------------------------------------------

The problem is now I want to declare different integers in the same line and be able to cross reference them as the following:

integer int1, int2 , int3;

int2= int1 + int3 * c1

and then I can be able to cross reference int2 and int3 as if it was written
integer int1;
integer int2;
integer int3;

I tried alot but ONLY the first identifer (i.e int1) is cross referenced!!
Any suggestions that I can make in the grammar to solve this?


Re: Cross reference for multiple identifers [message #1696479 is a reply to message #1696470] Tue, 26 May 2015 15:30 Go to previous messageGo to next message
Uli Merkel is currently offline Uli MerkelFriend
Messages: 250
Registered: June 2013
Senior Member
think your trouble lies in the identifer=ID (',' otherIdentifiers=ID)* ;

think it should read like: fields += Field? (',' fields+= Field)*
and: Field: name=ID ;

Re: Cross reference for multiple identifers [message #1696482 is a reply to message #1696479] Tue, 26 May 2015 15:52 Go to previous messageGo to next message
Amr El-Agamy is currently offline Amr El-AgamyFriend
Messages: 1
Registered: February 2015
Junior Member
I tried the above solution but it didnt work.

I did also the below changes in the grammar, but it didn't help as well.

Integer_dec:
'Integer' identifiersList=identifier_list ( '=' val=Ivalues) ';'
;

//Float_dec:
//'float'  identifiersList=identifier_list ( '=' val=Fvalues) ';'
//;

constants_dec:
'constant' name=ID '=' val=Cval ';'
;

identifier_list:
first=identifier (others+=identifier_extra)* ;

identifier:
name=ID
;
identifier_extra:
',' name=ID
;

declarations returns Declarations:
identifier | identifier_extra
//| Float_dec
//| constant_dec
;

expression:
leftOP=[Declarations] (operator=op rightOP=[Declarations])*
;

Model:
initialize+=declarations*
expressions+=expression*
;
Re: Cross reference for multiple identifers [message #1696663 is a reply to message #1696482] Wed, 27 May 2015 17:29 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Thanks Uli and Amr. I tried both suggestions but they didn't work out unfortunately Sad Sad
Re: Cross reference for multiple identifers [message #1696665 is a reply to message #1696663] Wed, 27 May 2015 18:13 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,



this should be quite easy

Model:
initialize+=declarations*
expressions+=expression*
;

Integer_dec:
'Integer' identifiersList=identifier_list ( '=' val=Ivalues) ';'
;

Float_dec:
'float'  identifiersList=identifier_list ( '=' val=Fvalues) ';'
;

constants_dec:
'constant' name=ID '=' val=Cval ';'
;

identifier_list:
identifers+=ID (',' identifers+=ID)* ;

declarations returns Declarations:
Integer_dec
| Float_dec
;

expression:
leftOP=[Declarations] (operator="+" rightOP=[Declarations])*
;

Ivalues: INT;

Fvalues: INT;

Cval: STRING;


for global cross refs you have to adopt the DefaultResourceDescriptionStrategy.

public class MyDslResourceDescriptionStrategy extends
		DefaultResourceDescriptionStrategy {
	
	@Override
	public boolean createEObjectDescriptions(EObject eObject,
			IAcceptor<IEObjectDescription> acceptor) {
		if(eObject instanceof Declarations) {
			identifier_list l = ((Declarations) eObject).getIdentifiersList();
			for (String i : l.getIdentifers()) {
				acceptor.accept(EObjectDescription.create(QualifiedName.create(i), eObject));
			}
		}
		return super.createEObjectDescriptions(eObject, acceptor);
	}

}


for local ones

public class MyDslImportedNamespaceAwareLocalScopeProvider extends
		ImportedNamespaceAwareLocalScopeProvider {
	
	@Override
	protected IScope getLocalElementsScope(IScope parent, EObject context,
			EReference reference) {
		// TODO Auto-generated method stub
		return super.getLocalElementsScope(parent, context, reference);
	}
	
	protected ISelectable internalGetAllDescriptions(final Resource resource) {
		Iterable<EObject> allContents = new Iterable<EObject>(){
			@Override
			public Iterator<EObject> iterator() {
				return EcoreUtil.getAllContents(resource, false);
			}
		}; 
		Iterable<IEObjectDescription> transformed = IterableExtensions.flatten(Iterables.transform(allContents,
				new Function<EObject, List<IEObjectDescription>>() {
					@Override
					public List<IEObjectDescription> apply(EObject from) {
						if (from instanceof Declarations) {
							List<IEObjectDescription> result = new ArrayList<IEObjectDescription>();
							identifier_list l = ((Declarations) from).getIdentifiersList();
							for (String i : l.getIdentifers()) {
								result.add(EObjectDescription.create(QualifiedName.create(i), from));
							}
							return result;
						} else {
							final QualifiedName qualifiedName = getQualifiedNameProvider().apply(from);
							if (qualifiedName != null)
								return Lists.newArrayList(new EObjectDescription(qualifiedName, from, null));
							return Collections.emptyList();
						}
						
						
					}
				}));
		return new MultimapBasedSelectable( Iterables.filter(transformed, Predicates.notNull()));
	}

}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1697998 is a reply to message #1696665] Wed, 10 June 2015 08:45 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Thanks Christian it worked like a charm Smile
Re: Cross reference for multiple identifers [message #1698778 is a reply to message #1697998] Wed, 17 June 2015 18:38 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Hi Christian,

Can you help me in the method getLocalElementsScope? After I override the method internalGetAllDescriptions I found that the identifiers are visible in all the resource. I thought I should be doing anything in getLocalElementsScope to set restrictions on the scope that they should be visible at. I searched for any implementation for getLocalElementsScope but couldn't find. I just want to set a scope for these identifers.

Thanks.
Re: Cross reference for multiple identifers [message #1698779 is a reply to message #1698778] Wed, 17 June 2015 19:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,

i do not understand that question, can you explain by example what you want to achieve


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1699117 is a reply to message #1698779] Sun, 21 June 2015 13:29 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Hi,
Let's say that I have the following:

declaration MyDecl1{
integer in1, in2, in3;
}

declaration MyDecl2{
integer in4, in5, in6;
}
expression for MyDecl1 {
int4 = int1 + int5;
}

--------------------------------------
In the example above, I have cross-referencing for the declarations in the expression ('expression' 'for' dec=[Declaration]). In getScope I added a check if it is expression then getscope(expression.getDec(), reference). I guess by this i added the contents of the declaration in the entity Very Happy but I actually found that all the declarations in both MyDecl1 and MyDecl2 are visible in all the file. How can I add the scope of the declaration to expression's scope
Re: Cross reference for multiple identifers [message #1699118 is a reply to message #1699117] Sun, 21 June 2015 13:58 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
By manual implement the scope provider (YourDslScopeProvider) or by adding the vars under their qualified name to the index and create a implicit import from the expression for thingy (YourDslImportedNamespaceAwareLocalScopeProvider) - using NodeModelUtils to read the text

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

[Updated on: Sun, 21 June 2015 14:14]

Report message to a moderator

Re: Cross reference for multiple identifers [message #1700433 is a reply to message #1699118] Thu, 02 July 2015 14:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
P.S. here are the imports for the example you linked

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.ISelectable;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;
import org.eclipse.xtext.scoping.impl.MultimapBasedSelectable;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1700802 is a reply to message #1700433] Tue, 07 July 2015 10:10 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Hi Christian Smile
Thanks alot for you help Smile
I have been working in the scoping but I have a problem with the list of identifiers as this example:

expressions exp1 {
integer int11, int12, int13 = 10;
float flo11, flo12, flo13 = 5.5;

expressions exp2 {
integer int21, int22, int23 = 5;
int21 = int22 + int11;
}

}
Grammar rule:
expression returns Expressions:
'expressions' name=ID '{'
declarations+=declaration*
expressions={
statements+=statement*
expressions+=expression*
}
'}'
;

declaration returns Declaration:
'integer' identifiers=identifier_list (':' value=INTEGER)?
;
identifier_list returns IdentifierList:
identifierList+=simple (','identifierList+=simple)*
;

simple returns Identifier:
ID=ID
;

The problem:
When I create a scope for the declarations in the expressions, the scope is returned an empty simple scope. I create the scope in the getScope as the following :

IScope myScope= Scopes.scopeFor(((Expressions)context).getDeclarations());

I just want the scopeFor to get the declarations in the given list.
What I tried:
I override internalGetAllDescriptions and created the EObjectDescriptions as
 for (Identifier i : l.getIdentifierList()) {
     result.add(EObjectDescription.create(QualifiedName.create(i.getID()), from));
   }

but this made the EObjectDescription to be created as int21 int22,...etc. without having the parent name concatenated i.e exp1.int11, exp1.int12,...etc. So I created a method that gets the parent's name then pass it to the QualifiedName.create(parent, i.getID()) in creating the EObjectDescription.
Also, I tried overriding the ResourceDescriptionStrategy and added to the acceptor the following:
for(Identifier i : l.getIdentifierList()){
 acceptor.accept(EObjectDescription.create( QualifiedName.create(MyLangEObjectUtils.getContainerName(eObject), i.getID()), eObject));
}
.

and I have my bindings configured correctly in the RuntimeModule Smile
But Still not working Sad any help please

[Updated on: Tue, 07 July 2015 10:22]

Report message to a moderator

Re: Cross reference for multiple identifers [message #1700805 is a reply to message #1700802] Tue, 07 July 2015 10:43 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hi i do not undestand this sentence

When I create a scope for the declarations in the expressions, the scope is returned an empty simple scope. I create the scope in the getScope as the following :


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1700806 is a reply to message #1700805] Tue, 07 July 2015 10:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
btw if you do Scopes.scopeFor(((Expressions)context).getDeclarations()); you completely ignore all adotions you did anywhere else.
have a look what that code does


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1700814 is a reply to message #1700805] Tue, 07 July 2015 11:42 Go to previous messageGo to next message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Hi Christian,

In getScope I have some checks and several levels for the scoping. When I try to add the scope for the expressions as an inner scope with an another importing scope as a parent, I found that the returned (inner) scope is empty.
i.e
SimpleScope[ ] -> importScope[Pack.*]
-------------------------------------------------
if IScope myScope= Scopes.scopeFor(((Expressions)context).getDeclarations()); clears all the other work I have done, How can I solve this issue then?
Re: Cross reference for multiple identifers [message #1700816 is a reply to message #1700814] Tue, 07 July 2015 11:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
i dont know your login,
either you put yout scope manually together as you do it and then you have to care or you do use the default impl and do not write a scope method for your ref.
so have look at scopeFor and do what is does manually adapted to your situation


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference for multiple identifers [message #1700964 is a reply to message #1700816] Wed, 08 July 2015 12:37 Go to previous message
Eleanor Richie is currently offline Eleanor RichieFriend
Messages: 125
Registered: August 2014
Senior Member
Thanks alot Christian it worked Smile I manually created the Scope by new SimpleScope(Parent, declarations) that partially worked for my case Smile

Previous Topic:Left Recursion
Next Topic:Internal*Parser class size
Goto Forum:
  


Current Time: Thu Mar 28 23:27:56 GMT 2024

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

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

Back to the top