Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Type var, var, var;(Modifying model during parse.)
Type var, var, var; [message #673245] Mon, 23 May 2011 01:54 Go to next message
Lex  is currently offline Lex Friend
Messages: 4
Registered: May 2011
Junior Member
I would like to be able to parse the following statement:

class Foo {
  int number;
  str var1, var2;
}


Into the following model:

Class {
  name = Foo
  properties = [
    Property { name = number, type = int },
    Property { name = var1, type = str},
    Property { name = var2, type = str}
  ]
}


I'm using the following Xtext (simplified a little for this post):

Class:
  'class' name=ID '{'
    (propertyTypes+=[DataType] properties+=Property (',' properties+=Property)* ';')*
  '}'

Property returns Property: {Property} name=ID;


The 'propertyTypes' above is a throw away, it's just there to make Xtext happy, I only care that there is a match, then when Property matches, I want to back track and get the DataType.

I have the following Extension to add 'type' to Property:

process(xtext::GeneratedMetamodel gm):
	addPropertyAttributes((ecore::EClass) gm.ePackage.getEClassifier('Property'));

addPropertyAttributes(ecore::EClass c):
	c.eStructuralFeatures.add(
		let type = new ecore::EReference :
		type.setName('type') ->
		type.setEType(c.ePackage.getEClassifier('DataType')) ->
		type
	);


The goal from there was to add a Value converter to Property that would back track until it found a DataType and then set that DataType on the Property:

	public Property toValue(String name, INode node) {
		Property p = (Property) node.getGrammarElement();
		INode n;
		while ((n = node.getPreviousSibling()) != null) {
			EObject o = n.getGrammarElement();
			if (o.eClass().getClassifierID()==SorcePackage.DATA_TYPE) {
				p.setType((DataType) o);
				return p;
			}
		}
		throw new ValueConverterException("Unknown type.", node, new Exception());
	}


Unfortunately I discovered that Value converters do not work for EObjects from this post:
[ couldn't post this link because i have less than 5 posts Sad ]

What are my options to make this work? I really want to use Xtext but I can think of a lot of situations where I would want some way to backtrack or possibly even go ahead a little bit to get some context information and set attributes on a particular node (such as the above example illustrates).

Any help would be greatly appreciate.
Re: Type var, var, var; [message #673349 is a reply to message #673245] Mon, 23 May 2011 10:11 Go to previous messageGo to next message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

I don't quite understand what you mean by "parse X into Y". I would use something like the following.

Class:
  'class' name=ID '{'
    propertyTypes+=PropertyType*
  '}'

PropertyType: type=[DataType]  properties+=Property (',' properties+=Property)* ';'

Property returns Property: {Property} name=ID;


When you now reference a Property, you can simply navigate to its container (which is a PropertyType) and ask for its type. In your Class definition you lose the connection between a property and its corresponding propertytype.

With this definition you don't need a meta model post processing.

Alex
Re: Type var, var, var; [message #673390 is a reply to message #673349] Mon, 23 May 2011 13:49 Go to previous messageGo to next message
Lex  is currently offline Lex Friend
Messages: 4
Registered: May 2011
Junior Member
Parsing it as a separate PropertyDeclaration is the way I did it initially but then my model didn't really match the semantics of my language.

int var1;
int var2;


and

int var1, var2;


Should be semantically equivalent and produce the same model. The second is merely a short cut for the first. Anytime I want to get a list of all properties of a class I would have to do some computation, I couldn't just return a list of properties. Also, any tools generated by Xtext wouldn't work as intended when displaying the list of properties in the outline or some other UI code. I would have to add special cases any place where a list of properties should be displayed.

Furthermore, it's my understanding that the point of a model is to represent the semantics of your language, not its syntax. The declaration shortcut is not semantically interesting and I would rather it didn't make it into my model.

I have not completely ruled this out though, depending on how hard it is going to be to make this work the right way I may just go back to having my model represent the syntax instead of the semantics at least for that portion of the language.

I have made some progress doing it the way I described in my original post. Xtext will not let you valueconvert an EObject but surprisingly they let you valueconvert an EJavaObject. I was able to change my code like this:

Model:
  'model' name=ID '{'
    (propertyTypes+=[DataType] properties+=Property (',' properties+=Property)* ';')*
  '}'

Property returns ecore::EJavaObject: ID;


By using ecore::EJavaObject the Value Converter is actually triggered. And has the following code:

	public Object toValue(String name, INode node) {
		Property prop = SorceFactory.eINSTANCE.createProperty();
		DataType type = SorceFactory.eINSTANCE.createDataType();

		EObject o = null;
		INode n = node;
		while ((n = n.getPreviousSibling()) != null) {
			o = n.getGrammarElement();
			if (o instanceof org.eclipse.xtext.impl.CrossReferenceImpl) {
				break;
			}
		}
		type.setName(n.getText());

		prop.setName(name);
		prop.setType(type);

		return prop;
	}


The problem is that I couldn't figure out how to go from a CrossReference to a DataType (I create a new DataType but I don't think that's what I want to do). All I could get is a TypeRef but I don't understand well enough how all of the cross referencing works to be able to navigate from the reference to the actual object being referenced.

So, my questions are:

How can I get the DataType object from a CrossReference?

Are there any downsides to implementing this feature as I have done above?

Are there any benefits or downsides to implementing it as Alex suggested vs the method above?






Btw, here is what Xtext.log() in the unit tests looks like for a sample object:

input:
type Money {}
type Str {}
type Color {}
model Foo {
  Str crackers, cheese;
}


output:
Sorce {
    cref Element elements [
        0: CustomType {
            attr EString name 'Money'
        }
        1: CustomType {
            attr EString name 'Str'
        }
        2: CustomType {
            attr EString name 'Color'
        }
        3: Model {
            attr EString name 'Foo'
            ref DataType propertyTypes [
                0: CustomType@//@elements.1
            ]
            attr EJavaObject properties [
                0: Property {
                    attr EString name 'crackers'
                    ref DataType type ref: DataType@(resource null)
                }
                1: Property {
                    attr EString name 'cheese'
                    ref DataType type ref: DataType@(resource null)
                }
            ]
        }
    ]
}

Re: Type var, var, var; [message #673398 is a reply to message #673390] Mon, 23 May 2011 14:16 Go to previous message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

although the syntactic differences may not matter to you, the parser has to construct the model from the syntax.

int i1, i2, i3, i4;
boolean b1, b2, b3, b4;

is equivalent to
int i1;
boolean b1;
int i2;
...

but it is quite hard to define a grammar that will create the same model from both out of the box. You can adapt the model creation.
I'd rather provide utility methods for querying a class or work with an imported metamodel and add the custom methods to the corresponding classes.

Alex


Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext@itemis.de
Previous Topic:(no subject)
Next Topic:(no subject)
Goto Forum:
  


Current Time: Fri Apr 26 21:45:02 GMT 2024

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

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

Back to the top