Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Can't get scoping to work
Can't get scoping to work [message #1727780] Sun, 27 March 2016 14:16 Go to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I want to achieve this:
int x ; 

{ 
	x = 10; //right
	int a = 10;
	a = x; //right 
}

a = 10; // wrong
int b = a; // wrong


This is my grammar:
grammar org.xtext.Cbb with org.eclipse.xtext.common.Terminals

generate cbb "http://www.xtext.org/Cbb"

Module:
	(statements+=Statement)*;
    
Statement:
	Variable |
	Block |
	IfStatement |
	WhileStatement |
	DoWhileStatement |
	ForStatement |
	SwitchStatement;

IfStatement:
	'if' '(' condition=Expression ')' 
	thenBlock=Block
	('else' 'if' '(' elseifConditions+=Expression ')'
	elseifthenBlocks+=Block)*
	(=>'else' elseBlock=Block)?;
	
WhileStatement:
	'while' '(' condition= Expression ')'
	whileBlock=Block;
	
DoWhileStatement:
	'do'
	doWhileBlock=Block
	'while' '(' condition=Expression ')'';';
	
ForStatement:
	'for''('((init=Variable)|(';'))(condition=Expression)?';'(increment=Expression)?')'
	forBlock=Block;

SwitchStatement:
	'switch' '('expr=Expression')'
	'{'
		('case' values+=integer_value ':'
			(caseStatements+=Statement)*
			('break'';')?
		)*
		('default'':'
			(defaultStatements+=Statement)*
		)?
	'}';

Block:
	{Block} '{' (blockStatements+=Statement)* '}';

Variable:
	VariableDeclaration | VariableAssignment;

VariableDeclaration:
	type=Type name=ID (op='=' expr=Expression)?';' |
	'const' type=Type name=ID op='=' expr=Expression';';

VariableAssignment: 
	assignee=[VariableDeclaration] op=assignment_operator expr=Expression';';

Expression returns Expression:
    BooleanExpression;
BooleanExpression returns Expression:
	Comparison
	({Expression.left=current} op=BooleanOperator right=Comparison)*;

Comparison returns Expression:
	Equal
	({Expression.left=current} op=ComparisonOperator right=Equal)*;

Equal returns Expression:
    Addition 
    ({Expression.left=current} op=EqualityOperator right=Addition)*;
    
Addition returns Expression:
    Multiplication
    ({Expression.left=current} op=AdditionOperator right=Multiplication)*;

Multiplication returns Expression:
    Bitwise 
    ({Expression.left=current} op=MultiplicationOperator right=Bitwise)*;

Bitwise returns Expression:
	Prefixed
	({Expression.left=current} op=BitwiseOperator right=Prefixed)*;

Prefixed returns Expression:
    {BooleanNegation} =>"!" expression=Atomic |
    {BitwiseNot} =>"~" expression=Atomic |
    Atomic;

Atomic returns Expression:
    lp='(' expr=Expression rp=')' |
    {IntegerLiteral} value=integer_value |
    {BooleanLiteral} value=boolean_value |
    {IntegerIncrementDecrement} (increment_decrement_operator ref=[VariableDeclaration]|ref=[VariableDeclaration] increment_decrement_operator) |
    {VariableReference} ref=[VariableDeclaration];

Type:
    {IntegerType} 'int' |
    {BooleanType} 'bool';

AdditionOperator:
	'+' | '-';
MultiplicationOperator:
	'*' | '/' | '%';
BitwiseOperator: 
	'|' | '&' | '^' | '>>' | '<<';
ComparisonOperator:
	'<' | '<=' | '>' | '>=';
EqualityOperator:
	'==' | '!=';
BooleanOperator: 
	'||' | '&&';

boolean_value:
	'true' | 'false';

assignment_operator:
	'=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<='  | '>>=';
	
increment_decrement_operator:
	'++' | '--';

integer_value:
	'-'?INT+;


I tried to follow the smallJava exercise https://github.com/LorenzoBettini/packtpub-xtext-book-examples/blob/master/org.example.smalljava
but with no luck.

My scope provider code is like this:
def dispatch IScope symbolsDefinedBefore(Block b, EObject o) {
		Scopes::scopeFor(b.blockStatements)
	}
Re: Can't get scoping to work [message #1727782 is a reply to message #1727780] Sun, 27 March 2016 15:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
This will work neither with xtext 284 nor with xtext 2.9.x

If you use xtext 284 or change the parent class to AbstractDeclarativeScopeProvider

Then the method Name is scope_<refereceOwner>_<referenceName>

In xtext 29x you have to override getScope(EObject,EReference) and do if else on the parameters


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727783 is a reply to message #1727782] Sun, 27 March 2016 15:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
In xtext 28x scope_RefType works as well

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727784 is a reply to message #1727783] Sun, 27 March 2016 15:11 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I am using 2.9.x
Would you give me a simple example using the
getScope(EObject,EReference)
to make a scope for the "Block" rule?
Re: Can't get scoping to work [message #1727785 is a reply to message #1727784] Sun, 27 March 2016 15:13 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
The block rule needs no scoping. Do you mean variableassignment

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727786 is a reply to message #1727785] Sun, 27 March 2016 15:15 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I mean VariableAssignment and also VariableReference in Expression
Re: Can't get scoping to work [message #1727787 is a reply to message #1727786] Sun, 27 March 2016 15:27 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
just a starting point covering only a few cases, the rest is your job

def IScope getVariableScope(EObject context) {
		if (context == null) {
			return IScope.NULLSCOPE
		}
		// get the block we are inside
		var block = EcoreUtil2.getContainerOfType(context, Block);
		if (block != null) {
			return Scopes.scopeFor(
				// var decls in that block
				block.blockStatements.filter(VariableDeclaration),
				// use name attribute
				QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER),
				// the variable from outer blocks
				getVariableScope(block.eContainer)
			)
		} 
		// get the module we are inside
		var module = EcoreUtil2.getContainerOfType(context, Module)
		if (module != null) {
			return Scopes.scopeFor(module.statements.filter(VariableDeclaration))
		}
		//TODO handle possible other cases, handle order if relevant
		
		return IScope.NULLSCOPE
	}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727788 is a reply to message #1727787] Sun, 27 March 2016 15:37 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
Thanks a lot. I will give it a shot.
Re: Can't get scoping to work [message #1727789 is a reply to message #1727788] Sun, 27 March 2016 15:44 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I have used the code you gave me. But the function itself doesn't get invoked at all. I have set a breakpoint and used debugging mode and it never triggers.
Re: Can't get scoping to work [message #1727790 is a reply to message #1727789] Sun, 27 March 2016 15:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
How does your scope Provider class look like and which xtext Version do you use

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727791 is a reply to message #1727790] Sun, 27 March 2016 15:46 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
guess you missed that one

class MyDslScopeProvider extends AbstractMyDslScopeProvider {
	
	override getScope(EObject context, EReference reference) {
		if (reference == MyDslPackage.Literals.VARIABLE_ASSIGNMENT__ASSIGNEE) {
			return getVariableScope(context)
		}
		super.getScope(context, reference)
	}
	
	def IScope getVariableScope(EObject context) {
		if (context == null) {
			return IScope.NULLSCOPE
		}
		// get the block we are inside
		var block = EcoreUtil2.getContainerOfType(context, Block);
		if (block != null) {
			return Scopes.scopeFor(
				// var decls in that block
				block.blockStatements.filter(VariableDeclaration),
				// use name attribute
				QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER),
				// the variable from outer blocks
				getVariableScope(block.eContainer)
			)
		} 
		// get the module we are inside
		var module = EcoreUtil2.getContainerOfType(context, Module)
		if (module != null) {
			return Scopes.scopeFor(module.statements.filter(VariableDeclaration))
		}
		//TODO handle possible other cases, handle order if relevant
		
		return IScope.NULLSCOPE
	}

}



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727792 is a reply to message #1727791] Sun, 27 March 2016 16:03 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I have added this too
def IScope getVariableReferenceScope(EObject context) {
		if (context == null) {
			return IScope.NULLSCOPE
		}
		// get the block we are inside
		var block = EcoreUtil2.getContainerOfType(context, Block);
		if (block != null) {
			return Scopes.scopeFor(
				// var decls in that block
				block.blockStatements.filter(VariableDeclaration),
				// use name attribute
				QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER),
				// the variable from outer blocks
				getVariableReferenceScope(block.eContainer)
			)
		} 
		// get the module we are inside
		var module = EcoreUtil2.getContainerOfType(context, Module)
		if (module != null) {
			return Scopes.scopeFor(module.statements.filter(VariableDeclaration))
		}
		//TODO handle possible other cases, handle order if relevant
		
		return IScope.NULLSCOPE
	}


I though have an error. I guess it is because the 'NamesAreUniqueValidator'.
int x = 0 ; 

{ 
	x = 10;
	int a = 10;
	a = x;
}

int a = 10; // Duplicate Statement 'a'
int b = a;


How can I make the NamesAreUniqueValidator scope oriented?
Re: Can't get scoping to work [message #1727793 is a reply to message #1727792] Sun, 27 March 2016 16:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
debug the code and have a look what it does. or simply throw it out and implement your own validation

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727794 is a reply to message #1727793] Sun, 27 March 2016 16:13 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I have one question. How can I have a scope for the VariableDeclaration statement although it doesn't have a reference []?
I also don't know where to find the implementation for the NamesAreUniqueValidator, This is why I am asking you if there is a way to make it scope oriented.
Re: Can't get scoping to work [message #1727795 is a reply to message #1727794] Sun, 27 March 2016 16:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
i do not understand this question. please elaborate. scoping and names are unique validation have ZERO in common.

names are unque validation is about things haveing names and thus beeing exported from the file.

you include NamesAreUniqueValidator somewhere in your code. (in the workflow or in the scope provider class)
if you want to know how it works debug it and NamesAreUniqueValidationHelper


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727796 is a reply to message #1727795] Sun, 27 March 2016 16:25 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
I want each of these to be valid. Is this possible?

{
	int a = 10;
}

{
	int a = 10;
}

int a = 10;
Re: Can't get scoping to work [message #1727797 is a reply to message #1727796] Sun, 27 March 2016 16:33 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
i explained you: the names are unique validation checks if names are you unique.
so you would have to remove it, modify it, or make it unique.
you did no post any attempt yet. so why no

import java.util.List
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider
import org.eclipse.xtext.naming.QualifiedName
import org.xtext.example.mydsl.myDsl.Block
import org.xtext.example.mydsl.myDsl.Module

class MyQNP extends DefaultDeclarativeQualifiedNameProvider {

def QualifiedName qualifiedName(Block block) {
//TODO make this more elegant
val index = EcoreUtil2.indexOf(block.eContainer.eGet(block.eContainingFeature) as List, block, 0)
val result = if (block.eContainer instanceof Module) {
QualifiedName.create("_"+index)
} else {
getFullyQualifiedName(block.eContainer).append(QualifiedName.create("_"+index))
}
println(result)
return result
}

}

!?!?!?!?!?!?!?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727799 is a reply to message #1727797] Sun, 27 March 2016 17:25 Go to previous messageGo to next message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
So If I provide the qualified names myself, The NamesAreUniqueValidator will use them automatically?
Re: Can't get scoping to work [message #1727800 is a reply to message #1727799] Sun, 27 March 2016 17:36 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
yes. of course you have to bind the nameprovider. something like

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
	
	override bindIQualifiedNameProvider() {
		MyQNP
	}
	
}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Can't get scoping to work [message #1727801 is a reply to message #1727800] Sun, 27 March 2016 17:46 Go to previous message
ayman salah is currently offline ayman salahFriend
Messages: 131
Registered: June 2015
Senior Member
Thanks a lot.
You are the best.
Previous Topic:Import objects from XMI-based model into my DSL
Next Topic:Xtext Display line numbers
Goto Forum:
  


Current Time: Thu Mar 28 12:15:17 GMT 2024

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

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

Back to the top