Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Scoping for dot/path expressions
Scoping for dot/path expressions [message #1084909] Mon, 12 August 2013 03:52 Go to next message
Eclipse UserFriend
Hello

I have a grammar with types and members and I want to specify the members using dot/path expressions. Similar to this example.

Only the valid members should be available for choice, i.e. the scope needs to be restricted to those members which are children of the structure specified as type of the parent member.

Grammar and scoping code attached. It does not work unfortunately.
Any help for finding the problem would be appreciated.

Grammar
Model:
	types+=Type*
	members+=Member*
	usages+=Usage*
;

Type:
	Elementary | Structure
;

Elementary:
	"elementary" name=ID
;

Structure:
	"structure" name=ID "{"
		members+=Member*
	"}"
;

Member:
	"member" name=ID ":" type=[Type]
;

Usage:
	"use" ref=DotExpression
;

DotExpression returns Ref:
	MemberRef ({DotExpression.ref=current}  "." tail=[Member])*
;

MemberRef returns Ref:
	{MemberRef} member=[Member]
; 


Scoping code
def IScope scope_DotExpression_tail(DotExpression exp, EReference ref) {
	val head = exp.ref;
	switch (head) {
		MemberRef : Scopes::scopeFor((exp.eContainer as Model).members)
		DotExpression : {
			val type = head.tail.type
			switch (type) {
				Elementary : IScope::NULLSCOPE
				Structure : Scopes::scopeFor(type.members)
				default: IScope::NULLSCOPE
			}
		}
		default: IScope::NULLSCOPE
	}
}



Re: Scoping for dot/path expressions [message #1084948 is a reply to message #1084909] Mon, 12 August 2013 04:48 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

guess it should be somewthing like

class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {

	def IScope scope_DotExpression_tail(DotExpression exp, EReference ref) {
		val head = exp.ref;
		switch (head) {
			MemberRef: {
				val t = head.member.type
				switch (t) {
					Elementary: IScope::NULLSCOPE
					Structure: Scopes::scopeFor(t.members)
					default: IScope::NULLSCOPE
				}
			}
			DotExpression: {
				val type = head.tail.type
				switch (type) {
					Elementary: IScope::NULLSCOPE
					Structure: Scopes::scopeFor(type.members)
					default: IScope::NULLSCOPE
				}
			}
			default:
				IScope::NULLSCOPE
		}
	}

}
Re: Scoping for dot/path expressions [message #1084967 is a reply to message #1084948] Mon, 12 August 2013 05:15 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian
Thanks for helping again.

I tried your code and it unfortunately does not work as desired

Here is the model I'm trying to create
	elementary A
	elementary B
	
	structure C {
		member c1 : A
	}
	
	structure D {
		member d1 : C
		member d2 : B
	}
	
	member p1 : C
	member p2 : D
	
	use p1.c1
	use p2.d1.c1


p1 and p2 are in the scope. But none of their members.

Do you have any ideas what the problem could be? I thought this might be a simpler version of your example. But with features at the beginning, and not entities.


Re: Scoping for dot/path expressions [message #1084971 is a reply to message #1084967] Mon, 12 August 2013 05:16 Go to previous messageGo to next message
Eclipse UserFriend
sorry i actually cannot reproduce this with my version of the (your) scopeprovider

[Updated on: Mon, 12 August 2013 05:16] by Moderator

Re: Scoping for dot/path expressions [message #1085129 is a reply to message #1084971] Mon, 12 August 2013 09:41 Go to previous messageGo to next message
Eclipse UserFriend
Ok, I found the error. I was using an import statement in the scoping code, referencing another type with the same name.

Can I bother you again for some insight?

I'm now facing the problem that the first element of the dot/path expression needs to be chosen from a predefined set.

The grammar changes
Model:
	types+=Type*
	inputs+=Input*
	usages+=Usage*
;

Input:
	"input" name=ID "{"
		members+=Member*
	"}"
;


Below is the new model fragment
input x {
	member p1 : C
	member p2 : D
}

input y {
	member p3 : C
	member p4 : D
}

use p3.c1


Only members from input y must be in the scope for the first element in the dot/path expression.

I tried the following additional scoping code, but it didn't work. I still need more practice with xtend.
def IScope scope_MemberRef_member(MemberRef memberRef, EReference ref) {

	Scopes::scopeFor((memberRef.eContainer.eContainer as Model).inputs.findFirst[i|i.name == "y"].members)
}



Re: Scoping for dot/path expressions [message #1085134 is a reply to message #1085129] Mon, 12 August 2013 09:50 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

this looks good so far, besides when typing the context may be the parent => define the coping method for the parent

def IScope scope_MemberRef_member(Model model, EReference ref) {

Scopes::scopeFor(model.inputs.findFirst[i|i.name == "y"].members)
}
Re: Scoping for dot/path expressions [message #1086445 is a reply to message #1085134] Wed, 14 August 2013 04:03 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian

Just wanted to let you know that it works as you said.

Thanks again

- Richard
Re: Scoping for dot/path expressions [message #1087345 is a reply to message #1085134] Thu, 15 August 2013 10:01 Go to previous messageGo to next message
Eclipse UserFriend
I have one more problem related to this setup

Why can't I rename the member reference from "tail" to "member" in the DotExpression statement?

If I do then scoping does not work anymore. No members can be selected for the first element in the dot/path expression.

There is somehow a conflict between the two rules. Using the same name would considerable simplify the code for scoping, validation, code generation etc.

DotExpression returns Ref:
	MemberRef ({DotExpression.ref=current}  "." member=[Member])*
;

MemberRef returns Ref:
	{MemberRef} member=[Member]
; 


I have these two scoping rules
def IScope scope_MemberRef_member(Model model, EReference ref) {

	Scopes::scopeFor(model.inputs.findFirst[i|i.name == "y"].members)
}

def IScope scope_DotExpression_member(DotExpression exp, EReference ref) {
	
	val type = exp.ref.member.type
	switch (type) {
		Structure: Scopes::scopeFor(type.members)
		default: IScope::NULLSCOPE
	}
}


Is there a way to make this work?

Re: Scoping for dot/path expressions [message #1087359 is a reply to message #1087345] Thu, 15 August 2013 10:21 Go to previous messageGo to next message
Eclipse UserFriend
Hi

the problem is the the scope rule would then be scope_Ref_member and you would have to unite
the both scoping rules. (i dont know if this will work well or if you will get cyclic resolution errors)
Re: Scoping for dot/path expressions [message #1087396 is a reply to message #1087359] Thu, 15 August 2013 11:22 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian

Thanks for your input.

Renaming both scope rules to scope_Ref_member works so far that both are called.
The one for MemberRef is called for the first element in the dot/path expression.

However adding a second element results in an Xtext validation error: Cyclic resolution of lazy links: Ref.member -> Ref.member
So the second scoping rule is called too.

I don't think uniting the scope rules would help here. Is that correct?

I've seen several topics to this kind of error. But no obvious solution I think.
What would be your recommended approach to deal with this?
Re: Scoping for dot/path expressions [message #1087399 is a reply to message #1087396] Thu, 15 August 2013 11:28 Go to previous message
Eclipse UserFriend
Hi I fear you have to switch back to old grammar

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de
Previous Topic:Xtext nature breaking cross references
Next Topic:Missing ecore file with standalone generation
Goto Forum:
  


Current Time: Mon Jul 07 20:41:42 EDT 2025

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

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

Back to the top