Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Nested Struct with Qualified Name
Nested Struct with Qualified Name [message #1074230] Fri, 26 July 2013 10:24 Go to next message
kamo cuvao is currently offline kamo cuvaoFriend
Messages: 11
Registered: July 2013
Junior Member
Hello!

I'm trying to make C-like structs with xtext, but I face a problem with qualified names:
The struct IS a type, and a type can have another type as its type. (that sounds weird ^^)

So now i want to create a qualified name that looks something like this:

variable.substruct.subsubstruct.variable
x.struct1.struct2.y //for example


Example:
TYPE
	koords : STRUCT
		x : INT;
		y : INT;
		z : INT;
	END_STRUCT;
	
	koords2 : STRUCT
		x : koords;
		y : koords;
		z : koords;
	END_STRUCT;
END_TYPE

VAR PRIVATE
	myWorld : koords;
	myOtherWorld: koords2;
END_VAR

ROUTINE main
	//Should not work
	myWorld.koords.integer := 5;
	myWorld.koords2.koords := 5;
	
	
	//Should work
//	myWorld.x :=5;
//	myOtherWorld.x.x := 5;
END_ROUTINE


Grammar:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "..."

Model:
	(elements+=AbstractElement)*
;
	
AbstractElement:
	types += TypeBlock | routines += RoutineBlock | variables += VariableBlock
;

TypeBlock: {TypeBlock}
	'TYPE'
		(types+=Type)*
	'END_TYPE'
;
Type: name=ID ':' (type=SimpleType | struct=Struct | typeRef=[Type]) ';';
	
Struct: {Struct}
	'STRUCT'
		(variables+=Variable)*
	'END_STRUCT'
;

VariableBlock: {VariableBlock}
	'VAR' (isGlobal?='GLOBAL' |  isPrivate?='PRIVATE')
		(variables+=Variable)*
	'END_VAR'
;
Variable: name=ID ':' (typeRef=[Type] | type=SimpleType) ';';
	
RoutineBlock:
	'ROUTINE' name=ID
		(statements+=Statement)*
	'END_ROUTINE'
;
Statement: DotExpression;


DotExpression returns Ref:
    VariableRef ({DotExpression.ref=current}  "." tail=[SuperRef])* ':=' INT ';'
;
 
VariableRef returns Ref:
    {EntityRef} entity=[Variable]
; 

SuperRef: Variable|Type;

//Allocation:
//	ref=[SuperRef | QualifiedName] ':=' INT ';'
//;
//SuperRef: variable=Variable|type=Type;
//QualifiedName:
//	ID ('.' ID)*
//;

SimpleType:
	(IntType | BoolType | RealType)
;

IntType:  {IntType}  "INT";
BoolType: {BoolType} "BOOL";
RealType: {RealType} "REAL";


I tried it with [xxx | QualifiedName] and left factoring, but i just cant figure it out.

Thanks for your help!
Re: Nested Struct with Qualified Name [message #1074301 is a reply to message #1074230] Fri, 26 July 2013 13:01 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
Hi did you have a look at
http://christiandietrich.wordpress.com/2013/05/18/xtext-and-dot-express
ions/

--
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


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1074695 is a reply to message #1074301] Sat, 27 July 2013 13:44 Go to previous messageGo to next message
kamo cuvao is currently offline kamo cuvaoFriend
Messages: 11
Registered: July 2013
Junior Member
Yes, I have. The problem I have is that i dont have the same entity in a row, but i have a variable which can have a type which has other variables in it. (type of struct)

so its not "entity.entity.entity"

its "variable.variable"
or "variable.substruct.variable"
or "variable.substruct.subsubstruct.variable"
Re: Nested Struct with Qualified Name [message #1074699 is a reply to message #1074695] Sat, 27 July 2013 13:54 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
Hi i dont get this Point. An entity ref is the Same as a vAr

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707560 is a reply to message #1074699] Mon, 07 September 2015 11:29 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Hi,
have you solved your problem? I have the same issue and I would be glad if you can provide your solution!
Thanks a lot!
Re: Nested Struct with Qualified Name [message #1707661 is a reply to message #1707560] Tue, 08 September 2015 12:11 Go to previous messageGo to next message
Moussa Amrani is currently offline Moussa AmraniFriend
Messages: 2
Registered: August 2015
Junior Member
Hi,

Making your example work required a bit of extra work to make things fit with Xtext workflow.

First, I simplified your grammar in order to keep only the minimal things necessary. I also refactored some elements so that it will simplify further explanations. Here is the grammar. One of the main things was to separate the "component" declarations inside a structure from variable declaration (as an AbstractElement). You can still merge them if necessary, since they parse the same.

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "..."

Model:
	(elements+=AbstractElement)*
;
	
AbstractElement:
	types += TypeBlock | routines += RoutineBlock | variables += VariableBlock
;

TypeBlock: {TypeBlock}
	'TYPE'
		(types+=Structure)*
	'END_TYPE'
;

Structure:
	name=ID ':' 'STRUCT' (components+=StructureComponent)+ 'END_STRUCT'
;

StructureComponent:
	name=ID ':' type=[Structure] |
	name=ID ':' simple=PrimitiveType
;


VariableBlock: {VariableBlock}
	'VAR' (isGlobal?='GLOBAL' |  isPrivate?='PRIVATE')
		(variables+=Variable)*
	'END_VAR'
;
Variable: name=ID ':' type=[Structure] ';';
	
RoutineBlock:
	'ROUTINE' name=ID
		(statements+=Statement)*
	'END_ROUTINE'
;
Statement: DotExpression;


DotExpression returns Expression:
    VariableRef ({DotExpression.receiver=current}  "." tail=[StructureComponent])* ':=' INT ';'
;
 
VariableRef returns Expression:
    {VariableRef} ref=[Variable]
; 

PrimitiveType:
	{IntType}  "INT"  |
	{BoolType} "BOOL" //|
//	{RealType} "REAL"
;


The main point is to have a name for each relevant element (component of a structure, variable, etc.) so that we can rely on Xtext scoping/naming conventions.


Next, in order to enable your dot-based notation, we need to provide the proper scope for an expression like "var.x". The principle is based on retrieving the potential elements that can appear after the "." based on the type of the receiver var: if a "." is possible, then it means that var is a structure with a component named x.

So first, we need to type expressions. To make things simple, I just consider structures as types (you can extend that with SimpleType or more complicated things, once you get it, it's easier). So I created a MyDSLTypeProvider in the proper package (see package declaration in the code) that computes the type of an expression:

  • The type of a VariableRef is the reference's declared type;
  • The type of a DotExpression is the type of the tail, i.e. the type of the structure's component.


package org.xtext.example.mydsl.typing

import org.xtext.example.mydsl.myDsl.BoolType
import org.xtext.example.mydsl.myDsl.DotExpression
import org.xtext.example.mydsl.myDsl.Expression
import org.xtext.example.mydsl.myDsl.IntType
import org.xtext.example.mydsl.myDsl.MyDslFactory
import org.xtext.example.mydsl.myDsl.PrimitiveType
import org.xtext.example.mydsl.myDsl.Structure
import org.xtext.example.mydsl.myDsl.StructureComponent
import org.xtext.example.mydsl.myDsl.VariableRef

class MyDSLTypeProvider {

	public static val integerType = MyDslFactory::eINSTANCE.createStructure => [name = "Integer"]
	public static val booleanType = MyDslFactory::eINSTANCE.createStructure => [name = "Boolean"]
	public static val nullType = MyDslFactory::eINSTANCE.createStructure => [name = "Null"]

	def Structure typeFor(Expression e) {
		switch (e) {
			VariableRef: e.ref.type
			DotExpression: e.tail.typeOf
		}
	}

	def static typeOf(StructureComponent c){
		if(c.type != null)
			return c.type
		else
			return c.simple.typeOf
	}
	
	def static typeOf(PrimitiveType ptype){
		switch(ptype){
			IntType: integerType
			BoolType: booleanType
		}
	}

	// returns true if fakely created
	// as a static value
	def isPrimitive(Structure c) {
		c.eResource == null
	}

}


Note that we need "fake" structure types because your langage allows so-called PrimitiveType-s: I created one such "fake" structure for each necessary type (feel free to extend it in the future).

Now that we can type expressions, we can compute the scopes: we need to indicate to Xtext how to resolve the reference [StructureComponent] in a DotExpression like var.x. The component x has to be found between the components available for the type of var. In your example, since myWorld is declared as a koords, we indicate that the tail x should be among the structure components of koords. We create an Xtend class MyDslScopeProvider with a dedicated scope function to scope this particular component. We need to respect the Xtext convention for the name of the function: scope_DotExpression_tail.
Here is the corresponding code with all you need to make it work (please respect the correct package, the correct class extends clause, and so on):

package org.xtext.example.mydsl.scoping

import com.google.inject.Inject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
import org.xtext.example.mydsl.myDsl.DotExpression
import org.xtext.example.mydsl.myDsl.Structure
import org.xtext.example.mydsl.typing.MyDSLTypeProvider

class MyDslScopeProvider extends AbstractDeclarativeScopeProvider{
	
	@Inject extension MyDSLTypeProvider
	
	def scope_DotExpression_tail(DotExpression e, EReference ref){
		val nullScope = IScope::NULLSCOPE
		val type = e.receiver.typeFor
		if(type == null || type.isPrimitive)
			return nullScope
		if(type instanceof Structure)
			return Scopes::scopeFor((type as Structure).components, nullScope)
	}
}


With that, everything should work correctly: it parses, and it becomes clickable thanks to the proper scopes.

However, you should add some checks to ensure e.g. that components in the same structure (as well as structure/variable declarations) have different names, otherwise the clickable reference would become ambiguous.

Re: Nested Struct with Qualified Name [message #1707698 is a reply to message #1707661] Tue, 08 September 2015 14:24 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Thank you for your reply. I tried to implement your code for my grammar. Unfortunately it didn't work.
I am trying to figure out the error for 2 weeks. I would be glad if you can find the error!
Thanks a lot!

The Grammar:
grammar org.xtext.robotic.airl.AIRL with org.eclipse.xtext.common.Terminals

generate aIRL "http://www.xtext.org/robotic/airl/AIRL"

import "http://www.eclipse.org/emf/2002/Ecore" as ecore

Model:
	programs+=Program*;

Program:
	(
	programHead=ProgramHead
	(programDecPart+=ProgramDeclarationPart)*
	("BEGIN" statement=StatementBlock)?
	"ENDPROGRAM" (";")?
	)	
;

ProgramHead:
	"PROGRAM" name=ID ";" (compDir=CompilerDirective)?
;

CompilerDirective:
	{CompilerDirective}("DECLON" ";" | "DECLOFF" ";")
;
	

ProgramDeclarationPart:
	
		decPart=DeclarationPart |
		importDecPart=ImportDeclarationPart
	
;

ImportDeclarationPart:
	{ImportDeclarationPart} "FROM" name=ID "IMPORT" ("ALL" | importIdList=ImportIdList) ";"
;

ImportIdList:
	imp+=ID ("," imp+=ID)
;



DeclarationPart:
		{DeclarationPart}(
		("CONST" | "VAR") (varDec+=VariableDeclaration)* |
		("TYPE" (type+=TypeDeclaration)*)
		) 
;


ConstDefinition:
	("TEACH" type=PredefinedType | ("PERMANENT")? type=Type) ":" name=Identifier (":=" expr?=Expression)? ";"
	//PermanentConstantDefinition | UsualConstantDefinition
;

UsualConstantDefinition:
	type=Type ":" name=Identifier ":=" expr=Expression ";"
;

PermanentConstantDefinition:
	("TEACH" type=PredefinedType | "PERMANENT" type=Type) ":" name=Identifier ";"
;

TypeDeclaration:
	structTypeDec=StructuredTypeDeclaration |
	teachTypeDec=TeachTypeDeclaration	
;

TeachTypeDeclaration:
	"TEACH" type=PredefinedType ":" name=Identifier
;

StructuredTypeDeclaration:
	recordTypeDescription=RecordTypeDescription
;

RecordTypeDescription:
	"RECORD" (compList+=ComponentList+) "ENDRECORD" "=" name=ID ";"
;

ComponentList:
	(typename=Type |  type=[RecordTypeDescription]) ":" name=ID ";"
;

VariableDefinition:
	VariableDeclaration | RecordTypeDescription
;

VariableDeclaration:
	("TEACH" type=PredefinedType | ("SHARED" | "PERMANENT")? type=Type) ":" name=ID (":=" expr=Expression)? ";"
 ;
StatementBlock:
	{StatementBlock}(labelID+=ID ":" | statement+=Statement ";")*
;

Statement:
	Expression | ProgramflowStatement		
;

ProgramflowStatement:
	ConditionalBranchStatement
;

ConditionalBranchStatement:
	"IF" expression=Expression 
	"THEN" statementBlock=StatementBlock
	(=> "ELSE" elseStatementBlock=StatementBlock)?
	"ENDIF"
;

Expression:
	Assignment  // ({Object.receiver=current} "." compList=[ComponentList])*
;

Assignment returns Expression:
	SelectionExpression ({Assignment.left=current} ":=" right=Expression)?
;

SelectionExpression returns Expression:
	TerminalExpression ({SelectionExpression.receiver=current} '.' member=[ComponentList])*
;

TerminalExpression returns Expression:
	{StringConstant} value=STRING |
	{IntConstant} value=INT |
	{RealConstant} value=REAL |
	{BoolConstant} value=('true' | 'false') |
	{VariableRef} variable=[VariableDefinition]|
	"(" Expression ")"
;

//Object:
//	RecordComponent ({Object.left=current} "." right=[ComponentList])*
//;
//
//RecordComponent:
//	name=[StructuredTypeDeclaration]
//;


Type:
	PredefinedType  //| type=[RecordTypeDescription] | typename=RecordTypeDescription
;

PredefinedType:
	SimpleType | StandardType // | SystemType
;

SystemType:
	typename=(
	'MAIN_JOINT' | 
	'ADD_JOINT' | 
	'JOINT' | 
	'ROBTARGET' | 
	'D_SPEC_TYPE' | 
	'R_SPEC_TYPE'
	)
;

StandardType:
	 
	 {StringType} name='string' | 
	 {TextType} name='TEXT' | 
	 {PositionType} name='POSITION' | 
	 {OrientationType} name='ORIENTATION' | 
	 {PoseType} name='POSE'
	 
; 

SimpleType:
	  {IntType} name='int' | {BoolType} name='bool' | {CharType} name='char'| {RealType} name='real'
;

RecordElementIdentifier:
	ID
;

RecordIdentifier:
	Identifier
;

Identifier:
	ID | 'e' | 'E'
;

REAL returns ecore::EFloat hidden(): ( INT '.' (EXP_INT | INT) | '.' (EXP_INT | INT) ) ;

terminal EXP_INT returns ecore::ELong : INT ('e'|'E')('-'|'+')? INT;
 
//REAL returns ecore::EFloat hidden(): ('-'? INT)? '.'INT (('e'|'E') ('-'|'+')? INT)?;


The TypeProvider
package org.xtext.robotics.airl.typing

import org.xtext.robotic.airl.aIRL.StringConstant
import org.xtext.robotic.airl.aIRL.IntConstant
import org.xtext.robotic.airl.aIRL.Expression
import org.xtext.robotic.airl.aIRL.AIRLFactory
import org.xtext.robotic.airl.aIRL.BoolConstant
import org.xtext.robotic.airl.aIRL.VariableRef
import org.xtext.robotic.airl.aIRL.AIRLPackage
import org.xtext.robotic.airl.aIRL.VariableDeclaration
import org.xtext.robotic.airl.aIRL.Assignment
import org.xtext.robotic.airl.aIRL.ConditionalBranchStatement
import org.xtext.robotic.airl.aIRL.TypeDeclaration
import org.xtext.robotic.airl.aIRL.DeclarationPart
import org.xtext.robotic.airl.aIRL.RealConstant
import org.xtext.robotic.airl.aIRL.SelectionExpression
import org.xtext.robotic.airl.aIRL.ComponentList
import org.xtext.robotic.airl.aIRL.Type
import org.xtext.robotic.airl.aIRL.IntType
import org.xtext.robotic.airl.aIRL.BoolType
import org.xtext.robotic.airl.aIRL.StringType
import org.xtext.robotic.airl.aIRL.RealType
import org.xtext.robotic.airl.aIRL.RecordTypeDescription

class AIRLTypeProvider {
	
	val ep = AIRLPackage::eINSTANCE
	
	public static val stringType = AIRLFactory::eINSTANCE.createStringType => [name='string']
	public static val intType = AIRLFactory::eINSTANCE.createIntType => [name='int']
	public static val boolType = AIRLFactory::eINSTANCE.createBoolType => [name='bool']
	public static val realType = AIRLFactory::eINSTANCE.createRealType => [name='real']
	
	def typeFor(Expression e) {
		switch(e) {
			StringConstant: stringType
			IntConstant: intType
			BoolConstant: boolType
			RealConstant: realType
			VariableRef: {
				if(e.variable.eClass.name.equals("VariableDeclaration"))
					(e.variable as VariableDeclaration).type
				else
					null
				}
			SelectionExpression: {
				e.member.typeOf
				}
		}
	}
	
	def static typeOf(ComponentList c) {
		if(c.type != null)
			return c.type
		else
			return c.typename.typeOf
	}
	
	def static typeOf(Type type) {
		switch(type) {
			IntType : intType
			BoolType: boolType
			StringType: stringType
			RealType: realType
		}
	}
	
	def expectedType(Expression e) {
		val c = e.eContainer
		val f = e.eContainingFeature
		
		switch(c) {
			VariableDeclaration case f == ep.variableDeclaration_Expr : c.type
			Assignment case f == ep.assignment_Right : {
				c.left.typeFor
				}
			case f == ep.conditionalBranchStatement_Expression : boolType
			default : null
		}
		
	}
	
	def isPrimitive(RecordTypeDescription r) {
		r.eResource == null
	}
	
}


And the ScopeProvider:
/*
 * generated by Xtext
 */
package org.xtext.robotic.airl.scoping

import com.google.inject.Inject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
import org.xtext.robotic.airl.aIRL.AIRLPackage
import org.xtext.robotic.airl.aIRL.RecordTypeDescription
import org.xtext.robotic.airl.aIRL.SelectionExpression
import org.xtext.robotics.airl.typing.AIRLTypeProvider

/**
 * This class contains custom scoping description.
 * 
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
 * on how and when to use it.
 *
 */
class AIRLScopeProvider extends AbstractDeclarativeScopeProvider {
	
	@Inject extension AIRLTypeProvider

		
	def IScope scope_SelelectionExpression_member(SelectionExpression exp, EReference ref) {
		val nullScope = IScope::NULLSCOPE
		val type = exp.receiver.typeFor
		if(type==null)
			return nullScope
		if(type instanceof RecordTypeDescription)
			return Scopes::scopeFor((type as RecordTypeDescription).compList, nullScope)
	}
	
}
  

Re: Nested Struct with Qualified Name [message #1707704 is a reply to message #1707698] Tue, 08 September 2015 15:15 Go to previous messageGo to next message
Moussa Amrani is currently offline Moussa AmraniFriend
Messages: 2
Registered: August 2015
Junior Member
Hi,

You have a wrong qualified name for the scope provider: package org.xtext.robotics.airl.typing instead of package org.xtext.robotic.airl.typing (without the "s" at the end).

Concerning the error, I cannot do anything. The least you can do, out of respect, is to give more information about the errors, like pointing the errors' locations, because the UI crashes without properly launching so I cannot test anything.
You should go step by step and add things only when the previous ones work. At least, the editor should launch but fail at parsing some parts...

M.A
Re: Nested Struct with Qualified Name [message #1707710 is a reply to message #1707704] Tue, 08 September 2015 16:11 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
alternatively you could share a unit test as well

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707772 is a reply to message #1707710] Wed, 09 September 2015 09:45 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Hi,

unfortunately the members of Record Type couldn't be resolved. Maybe you find the error in the project below. I would be very happy.

A .irl project could like this:
PROGRAM testPrg;

VAR
	bool : a;
	int : b := 3;
	real : c := 3.9;
	
TYPE
	RECORD
		bool: ra;
		int: rb;
		real : rc;
	ENDRECORD = rec;

BEGIN

	a := true;
	rec.ra := false;
	
	IF a THEN
		b := 3;
	ENDIF;
	
ENDPROGRAM
  • Attachment: IRL.zip
    (Size: 716.28KB, Downloaded 17 times)
Re: Nested Struct with Qualified Name [message #1707779 is a reply to message #1707772] Wed, 09 September 2015 10:40 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
your scoping method is wrongly named.

def IScope scope_SelectionExpression_member(SelectionExpression exp, EReference ref) {

and the type provider is not completely implemented

VariableRef: {
if(e.variable instanceof RecordTypeDescription) {
e.variable
}
else if(e.variable instanceof VariableDeclaration) {
(e.variable as VariableDeclaration).type
} else {
null
}

}


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707786 is a reply to message #1707779] Wed, 09 September 2015 11:18 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
THANK YOU very much! It worked!
Re: Nested Struct with Qualified Name [message #1707800 is a reply to message #1707786] Wed, 09 September 2015 12:41 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Hi,

I have another question Smile :

Let's say I want to declare a Variable as "Position":
VAR
    POSITION: p;


where POSITION should be internally declared as a RECORD:
TYPE
    RECORD 
          REAL: X;
          REAL: Y;
          REAL: Z;
    ENDRECORD = POSITION;


in a way that I can assign values in form of:
BEGIN
     p.X := 3.1
     p.Y := 2.0
     p.Z := 3.4
...


I am not sure how to implement that. Should I do this in the Grammar or in the TypeProvider? How does it work...

Thank you in advance!

[Updated on: Wed, 09 September 2015 12:42]

Report message to a moderator

Re: Nested Struct with Qualified Name [message #1707802 is a reply to message #1707800] Wed, 09 September 2015 12:59 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
usually The validator uses the typesystem to make sure that within an assignment left and righthandside have matching types (if this is your question)

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707804 is a reply to message #1707802] Wed, 09 September 2015 13:11 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
At first I want to declare a variable of type POSITION
 POSITION := p; 
, without an assignment, thats why there is no validation.
When defined, every variable of type POSITION should internally create a RECORD type in such a form:
  
RECORD REAL X,Y,Z; ENDRECORD = p

In a further step the values should be assigned like:
 p.X := 2.9 

But I am not sure if this should be done in the grammar or somewhere else.

Thanks

Re: Nested Struct with Qualified Name [message #1707807 is a reply to message #1707804] Wed, 09 September 2015 13:27 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
I dont get that point. Idont unsterstand what you mean by "this"
A language usisally is a combination of concrete and abstract syntax (grammar) visibility (scoping) and semantics ( typesystem and validation) so it depends what you actually want to solve to give further advice


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707811 is a reply to message #1707807] Wed, 09 September 2015 13:46 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
I assume you have access to my grammar. There you can see that a Type can be declared as follows:
Type:
	PredefinedType  //| type=[RecordTypeDescription] | typename=RecordTypeDescription
;

PredefinedType:
	SimpleType | StandardType // | SystemType
;

StandardType:
	 {StringType} name='string' | 
	 {TextType} name='TEXT' | 
	 {PositionType} name='POSITION' | 
	 {OrientationType} name='ORIENTATION' | 
	 {PoseType} name='POSE'
; 

SimpleType:
	  {IntType} name='int' | {BoolType} name='bool' | {CharType} name='char'| {RealType} name='real'

What I want to have is : In case a variable is declared as POSITION, that variable shall have the structure of a RECORD type with 3 members X,Y,Z of type REAL. That's all.

At the end I want to have something like:
PROGRAM test;
VAR 
	POSITION : pos;
BEGIN
	pos.X := 3.9;
	pos.Y := 2.5;
	pos.Z := 1.4;
ENDPROGRAM
Re: Nested Struct with Qualified Name [message #1707814 is a reply to message #1707811] Wed, 09 September 2015 13:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
And where and how is POSITION defined?

Maybe a type can be a RecordTypeDescriptionReference:ref=[RecordTypeDescription ]
As well


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707815 is a reply to message #1707814] Wed, 09 September 2015 13:54 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
It isn't defined yet. I want to define it but I don't know how. Every Position Type shall have the same structure.
Re: Nested Struct with Qualified Name [message #1707818 is a reply to message #1707815] Wed, 09 September 2015 14:01 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
Yes but why do you know it is xyz and not abc or p1p2p3
Or is this kind a srd lib? If so why not shipping std lib models


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707819 is a reply to message #1707818] Wed, 09 September 2015 14:07 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Since it is supposed to be a robot language, a POSITION type should represent coordinates X,Y,Z.
I am not familiar with std lib models. How does it work?
Re: Nested Struct with Qualified Name [message #1707820 is a reply to message #1707819] Wed, 09 September 2015 14:09 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
The grammar is not finished yet ... I want to proceed step by step
Re: Nested Struct with Qualified Name [message #1707822 is a reply to message #1707820] Wed, 09 September 2015 14:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
asume the project the user models in is a java project (may be the case if the target runtime is java)
then create a libary jar that contains the libary models and put these to the classpath of that java project

asume the project the uses model in i a pure project then simpy copy and paste the libary models to that project

or ... or ...

or adapt global scope provider and put the libary onto scope there

or ... or ....

(beginning with the first or this requires deeper xtext knowlege and more than trivial customizatiions)


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707823 is a reply to message #1707822] Wed, 09 September 2015 14:23 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Since I am rather new to Xtext and EMF it seems quite complicated for me. Is there another (more simple) approach?
Re: Nested Struct with Qualified Name [message #1707825 is a reply to message #1707823] Wed, 09 September 2015 14:41 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
the first two will work out of the box. i dont know any other easy solution

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707828 is a reply to message #1707825] Wed, 09 September 2015 14:53 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
I can't see your code
Re: Nested Struct with Qualified Name [message #1707830 is a reply to message #1707828] Wed, 09 September 2015 14:56 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
i dont have code

simply consider you could write in your code

LIBARY;

TYPE
    RECORD 
          REAL: X;
          REAL: Y;
          REAL: Z;
    ENDRECORD = POSITION;


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707831 is a reply to message #1707830] Wed, 09 September 2015 15:00 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
I am sorry but I don't get the point
Re: Nested Struct with Qualified Name [message #1707833 is a reply to message #1707831] Wed, 09 September 2015 15:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
this is how the user project looks like

myproject
- src
  - mystuff.mydsl
- lib
  - stdlib.jar
    - stdlib.mydsl



or

myproject
- stdlib.mydsl
- mystuff.mydsl



Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707837 is a reply to message #1707833] Wed, 09 September 2015 15:34 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Ahhhh OK thank you. You are right... through global scoping it works out of the box if I allow a Type to be ref=[RecordTypeDescription].
PROGRAM LIBRARY;

TYPE 
	RECORD 
		real : X;
		real : Y;
		real : Z;
	ENDRECORD = position;
ENDPROGRAM

PROGRAM testPrg;

VAR
	position : p;

BEGIN
	p.X := 4.0;
ENDPROGRAM

However the member X couldn't be resolved. There is no content assist. How do I have to change the ScopeProvider that it works?

[Updated on: Wed, 09 September 2015 15:38]

Report message to a moderator

Re: Nested Struct with Qualified Name [message #1707840 is a reply to message #1707837] Wed, 09 September 2015 15:56 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
global scoping works by default but names are built like

parentname.childname.grandchildname

=>

(1) you can allow this in your syntax ref=[RecordTypeDescription|FQN]. with FQN: ID ("." ID)*; then you would write libary.position instead of position
(2) adapt the i qualified name provider to give the RecordTypeDescription its simple name
(3) adapt ImportedNamespaceAwareLocalScopeProvider and add an import for LIBRARY.* (org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.getImplicitImports(boolean))


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1707875 is a reply to message #1707840] Thu, 10 September 2015 07:28 Go to previous messageGo to next message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Thank you very very much! I will try that out
Re: Nested Struct with Qualified Name [message #1707876 is a reply to message #1707875] Thu, 10 September 2015 07:39 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 8306
Registered: July 2009
Senior Member
(you should try 3 since the programs should be isolated from each other)

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: Nested Struct with Qualified Name [message #1708173 is a reply to message #1707876] Mon, 14 September 2015 11:37 Go to previous message
tam ay is currently offline tam ayFriend
Messages: 44
Registered: May 2015
Member
Hi Christian,

could you have a look for that problem https://www.eclipse.org/forums/index.php?t=msg&th=1070269&goto=1708165&?

Thanks a lot
Previous Topic:Howto xtext rcp4?
Next Topic:IllegalArgumentException from converter initialization since 2.8.4 (bug 469805)
Goto Forum:
  


Current Time: Sun Feb 14 03:54:52 GMT 2016

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

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