Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Generic Attribute rule
Generic Attribute rule [message #1765118] Tue, 06 June 2017 20:12 Go to next message
Susie Agerholm is currently offline Susie AgerholmFriend
Messages: 54
Registered: April 2017
Member
I am trying to formulate a rule for defining a generic attribute rule (URDFAttr below).

Attribute should be generic in this sense:
Within the context of an Inertia definition, the suggestions for var assignment i URDFAttr should be fetched from InertiaVars enums (wrapped in InertiaVarType to make alternative work)

In the context of an Origin definition, suggestions for var assignment should be fetched from OriginVars...

I can see the Literals from Inertia enum in debugger when getting to the scope def in scope file - but nothing is suggested in editor. I have a hunch it is because I am not forcing instantiation of the OriginVars and InertiaVars objects but xtext only allows me to do that for the Var ref in URDFAttr, and that gives me an error at runtime...


GRAMMAR
grammar org.xtext.example.enumm.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/enumm/MyDsl"

Model:
	links+=Link*;
	
Link:
	'Link' name=ID
	inert+=Inertia*	
	origin+=Origin*
;

Origin:
	'Origin'
	attr+=URDFAttr	
;

Inertia:
	'Inertia' (name=ID)?
	attr+=URDFAttr
;

URDFAttr:
	var=[Var]
	value=MyValueType
; 

Var:
	OriginVarType | InertiaVarType
;

enum OriginVars:
	x='x' | y='y' | z='z' | roll='roll' | pitch='pitch' | yaw='yaw'
;

enum InertiaVars:
    ixx='ixx' | ixy='ixy' | ixz='ixz' | iyy='iyy' | iyz='iyz' | izz='izz' 
; 

MyValueType:
	INT | STRING
;

//Wrapping enum in type for alternative to work...
InertiaVarType:type=InertiaVars;
OriginVarType:type=OriginVars;




SCOPE:

class MyDslScopeProvider extends AbstractMyDslScopeProvider {
	
	override IScope getScope(EObject exp, EReference ref) {
      	if (exp instanceof URDFAttr) {
     		//Generic Attribute: How to make sure only Inertia vars suggested in Inertia context? Origin in Origin, etc
     		val myscope = exp.eContainer
     		if (myscope instanceof Inertia) {
     			val test = MyDslPackage.Literals.INERTIA_VARS.ELiterals
     			
     			Scopes::scopeFor(MyDslPackage.Literals.INERTIA_VARS.ELiterals as Iterable <? extends EObject>)
     		}
     		
     	}
	}
}




MODEL:

Link ll Inertia iii //here i would expect suggestions from the InertiaVars enum (ixx, ixy etc), but nothing...


Re: Generic Attribute rule [message #1765119 is a reply to message #1765118] Tue, 06 June 2017 20:21 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
Hi in your grammar you reference to a var.

So you want to reference to InertiaVarType or OriginVarType

But

- you don't have a place where you define it
- they don't have a Name (you can fix this by customizing IQualifiedNameProvider)

Or you really want to reference to the enum literal
But then you need to change thentype to ecore::EEnumLiteral

But why referencing if you can do

A var=InertiaVars

Instead


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Generic Attribute rule [message #1765170 is a reply to message #1765119] Wed, 07 June 2017 08:30 Go to previous messageGo to next message
Susie Agerholm is currently offline Susie AgerholmFriend
Messages: 54
Registered: April 2017
Member
well the idea of wrapping the enums in a type and doing it as a reference was to be able to switch the 'implementation' of enum depending on the context - in an Inertia context it will be one of the values from InertiaVars and in Origin one from OriginVars. The basic idea was to make one generic attribute class that via scope can change its implementation of var assignment depending on context if that makes sense...so would like to avoid hardcoding var to InertiaVars
Re: Generic Attribute rule [message #1765173 is a reply to message #1765170] Wed, 07 June 2017 08:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
yes but why then not ref=[ecore::EEnumLiteral]

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Generic Attribute rule [message #1766127 is a reply to message #1765173] Fri, 16 June 2017 08:50 Go to previous messageGo to next message
Susie Agerholm is currently offline Susie AgerholmFriend
Messages: 54
Registered: April 2017
Member
Hi again,
I have a solution now, that is working ok if I stick to the grammar. But I need to integrate in my metamodel, so grammar is not enough.

But if I try to roundtrip (roundtrip = generate a metamodel from the grammar, create new project from this metamodel and add the custom grammar), I get the following errors in the parserrules for URDFAttrINT, URDFAttrFLOAT and URDFAttrSTRING:

1. Cannot find compatible feature 'var' in sealed EClass URDFAttrINT (but this feature is supposed to be inherited from abstract class URDFAttr?)

2. The type EEnumLital used in 'var' is inconsistent probably due to unsupported metamodel hierarchy (but this construct compiles just fine in grammar example?)

//MY GRAMMAR AND METAMODEL BELOW:

GRAMMAR:

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

//generate myDsl "http://www.xtext.org/example/roundtrip/RoundTrip"
import "http://www.xtext.org/example/roundtrip/RoundTrip"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore


Model:
	links+=Link*
;
	
Link:
	'Link' name=ID
	inert+=Inertia*	
	origin+=Origin*
;

Origin:
	{Origin} 'Origin' (name=ID)?
	attr+=URDFAttrINT*	
;

Inertia:
	{Inertia} 'Inertia' (name=ID)?
	attr+=URDFAttrINT*
;

URDFAttr:
	URDFAttrINT | URDFAttrFLOAT | URDFAttrSTRING
; 

URDFAttrFLOAT:
	'var' var=[ecore::EEnumLiteral]
	value=FLOAT
;

URDFAttrINT:
	'var' var=[ecore::EEnumLiteral]
	value=INT
;

URDFAttrSTRING:
	'var' var=[ecore::EEnumLiteral]
	value=STRING
;

//SIGNED NUM - also negative
enum DimensionVars:
	x='_x' | y='_y' | z='_z' 
;

enum OrientationVars:
	roll='_roll' | pitch='_pitch' | yaw='_yaw'
;

//SIGNED NUM - also negative
enum InertiaVars:
    ixx='_ixx' | ixy='_ixy' | ixz='_ixz' | iyy='_iyy' | iyz='_iyz' | izz='_izz' 
; 

FLOAT returns ecore::EFloat: 
	INT '.' INT
;



MY METAMODEL:
index.php/fa/29684/0/
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="myDsl" nsURI="http://www.xtext.org/example/roundtrip/RoundTrip"
    nsPrefix="myDsl">
  <eClassifiers xsi:type="ecore:EClass" name="Model">
    <eStructuralFeatures xsi:type="ecore:EReference" name="links" upperBound="-1"
        eType="#//Link" containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Link">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="inert" upperBound="-1"
        eType="#//Inertia" containment="true"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="origin" upperBound="-1"
        eType="#//Origin" containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Origin">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="attr" upperBound="-1" eType="#//URDFAttrINT"
        containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Inertia">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="attr" upperBound="-1" eType="#//URDFAttrINT"
        containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="URDFAttr">
    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EEnumLiteral"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="URDFAttrFLOAT" eSuperTypes="#//URDFAttr">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="URDFAttrINT" eSuperTypes="#//URDFAttr">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="URDFAttrSTRING" eSuperTypes="#//URDFAttr">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EEnum" name="DimensionVars">
    <eLiterals name="x" literal="_x"/>
    <eLiterals name="y" value="1" literal="_y"/>
    <eLiterals name="z" value="2" literal="_z"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EEnum" name="OrientationVars">
    <eLiterals name="roll" literal="_roll"/>
    <eLiterals name="pitch" value="1" literal="_pitch"/>
    <eLiterals name="yaw" value="2" literal="_yaw"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EEnum" name="InertiaVars">
    <eLiterals name="ixx" literal="_ixx"/>
    <eLiterals name="ixy" value="1" literal="_ixy"/>
    <eLiterals name="ixz" value="2" literal="_ixz"/>
    <eLiterals name="iyy" value="3" literal="_iyy"/>
    <eLiterals name="iyz" value="4" literal="_iyz"/>
    <eLiterals name="izz" value="5" literal="_izz"/>
  </eClassifiers>
</ecore:EPackage>


SCOPE:
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
	
	override IScope getScope(EObject exp, EReference ref) {
      	if (exp instanceof URDFAttr) {
     		//Generic Attribute: How to make sure on Inertia vars in Inertia context? Origin in Origin, etc
     		val myscope = exp.eContainer
     		if (myscope instanceof Inertia) {
     			val tt = exp.eContainer.eContainmentFeature
     			
     			Scopes::scopeFor(MyDslPackage.Literals.INERTIA_VARS.ELiterals as Iterable <? extends EObject>)
     			
     		}
     		else if (myscope instanceof Origin) {
     			val tt = exp.eContainer.eContainmentFeature
     			
     			Scopes::scopeFor(MyDslPackage.Literals.DIMENSION_VARS.ELiterals as Iterable <? extends EObject> + 
     				MyDslPackage.Literals.ORIENTATION_VARS.ELiterals as Iterable <? extends EObject> 
     			)
     		}
     		
     	}
	}
}





Re: Generic Attribute rule [message #1766163 is a reply to message #1766127] Fri, 16 June 2017 17:19 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
i am sorry. this seems to be https://github.com/eclipse/xtext-core/issues/41
dont know a solution


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Generic Attribute rule [message #1766194 is a reply to message #1766163] Sat, 17 June 2017 13:05 Go to previous message
Susie Agerholm is currently offline Susie AgerholmFriend
Messages: 54
Registered: April 2017
Member
Ok - thanks :)
Previous Topic:MyDSL Templates
Next Topic:How to use Xtend outside an Xtext project ?
Goto Forum:
  


Current Time: Mon Sep 23 18:46:33 GMT 2024

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

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

Back to the top