Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Creating a wildcard reference
Creating a wildcard reference [message #1402895] Fri, 18 July 2014 09:17 Go to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Hello everyone,

I don't know if my title here is quite clear, basically what I'm trying to do is adding a reference to an array that was not defined specifically by the user, but rather is provided by the DSL.

My rule is the following :
Function returns Function:
	'func' name=EString '{'
		'parameters' '(' (parameters+=[Type|EString] ( "," parameters+=[Type|EString])* )? ')'
	'}';

Parameters are references to a Type that are defined by the user, and I would like to be able to specify some kind of wildcard rather than having to reference one that has been defined.
The idea of the field 'parameters' is to specify the types and implicitly the number of parameters of a function.
There are several ways I could do that by modifying my meta-model and adding a wildcard type of parameter that is actually contained by the function rather than being a reference, but by doing so I would probably lose the order of the parameters as they are defined (e.g doing something like parameters(*, specificType, *) ).

So I was wondering if there were ways to have such null references or some kind of cool trick to pull that off.

Thank you, here's to hoping that my question was clear enough =)

Yann
Re: Creating a wildcard reference [message #1402949 is a reply to message #1402895] Fri, 18 July 2014 15:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
'parameters' '(' (parameters+=Param( "," parameters+=Param)* )? ')'

Param: TypeRef | Wildcard;

TypeRef: type[Type|EString];

Wildcard: {Wildcard}'*';


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403826 is a reply to message #1402949] Mon, 28 July 2014 07:45 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
I don't quite understand, this seems to suggest that parameters would have to be a containment reference, but how can it accept references within brackets if that's the case ? Is the "type" you've put in TypeRef: type[Type|EString]; some kind of keyword that instantiates a reference or something ?

Yann

[Updated on: Mon, 28 July 2014 07:46]

Report message to a moderator

Re: Creating a wildcard reference [message #1403839 is a reply to message #1403826] Mon, 28 July 2014 08:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,

i dont get your point.
maybe you can explain your problem one more.

i understand you want to be able to write


*, a, * , *, b, * , c , *

or something like that.

my grammar should allow this.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403850 is a reply to message #1403839] Mon, 28 July 2014 09:38 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Well, when writing :

Param: TypeRef | Wildcard;

TypeRef: type[Type|EString];

Wildcard: {Wildcard}'*';

You're allowing the Param rule to return both a reference to an Object or an Object directly. This doesn't work for me (maybe I'm just missing something), but since parameters is not a containment relation, I can't use a rule such as Wildcard that would return an Object. (And it's not that I wouldn't, it just causes an error ^^ )

The aim of my DSL is to define types, then the prototypes of functions that take those types as parameters. The parameters relation is a simple reference, which allows me to refer to the types that were created just before (e.g type a; type b; type c; parameters(a, b, c); ), however, I would like to add wildcard parameters to the mix (e.g parameters(*, a, * , *, b, * , c , *) ). * has to exist in order to be referenced as a parameter, so I guess one of the options would be to have a rule that returns a reference to a new object rather than an object (returning null would be enough), but I don't know if that's possible.

The other possible way I see would be to make parameters a containment reference. Doing so, having a rule that returns a Wildcard would be very easy, but then I wouldn't be able to add references to a Type to parameters, I would have to instantiate specific types for each function, which I obviously don't want to.

Here's a sample that may help you understand :
type mass {
    frames 2 // These are fields to the type Type, and are of no matter for this problem
    fields(weight) // These are fields to the type Type, and are of no matter for this problem
}
type floor {
    frames 2
    fields(weight)
}
function connect {
    parameters(mass, floor) // This I can do, but it won't cut it, as I want to be able to connect any types together
}
function trueConnect {
    parameters(*, *) // Basically do this
}
function somethingElse {
    parameters(mass, *, floor, *) // I still want to do this though
}


In terms of what I'm trying to achieve, we are still quite abstract, I am only defining function prototypes, so it matters very little if * is just an alias for null, as long as it is still referenced in the parameters relation and I can get the right number of parameters for a prototype. When actually using the functions defined here, my program will only check if types match when a type is actually defined and is not a *, but I guess that's kind of obvious.

I hope this helps, thank you for your help.

Yann

[Updated on: Mon, 28 July 2014 09:47]

Report message to a moderator

Re: Creating a wildcard reference [message #1403910 is a reply to message #1403850] Mon, 28 July 2014 14:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hi,

i dont see your point

you have n containment childs
i of these are wildcards
j of these hold a reference.

sorry i still do not understand your problem.
what is the semantics of * what shall it do, what shall be created in the ast?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Mon, 28 July 2014 14:22]

Report message to a moderator

Re: Creating a wildcard reference [message #1403911 is a reply to message #1402895] Mon, 28 July 2014 14:38 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Well yes, but it doesn't work ^^

The following code (simplified to showcase the error, and also because I am rewriting it from memory) will not work :

Wildcard returns Wildcard :
{Wildcard}'*';

Function returns Function :
'function' name=EString 'parameters' '(' ((parameters+=[Type|EString])|(parameters+=Wildcard)) ')'

If parameters is a simple reference, it will fail on "parameters+=Wildcard" because "parameters is not a containment reference.
If parameters is a containment reference, it will fail on "parameters+=[Type|EString]" because "parameters is a containment reference."
Re: Creating a wildcard reference [message #1403914 is a reply to message #1403911] Mon, 28 July 2014 14:53 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi


you did not what i told ?!?


'function' name=EString 'parameters' ... parameters+=Param ....

Param : Wildcard | ReferenceHolder

ReferenceHolder: parameter=[Type|EString]


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403931 is a reply to message #1403914] Mon, 28 July 2014 15:53 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Well, I don't really understand how that would work better since it is merely hiding the fact that we're trying to put objects in a container that holds references, but I
My DSL is based on a meta-model so I can't use the exact same syntax as you do, and when I try to do something similar to what you said, I still get "No viable alternative at input 'Type'" errors. I am not at work right now so I don't have access to the actual code to pinpoint the errors that are occuring, but these errors are still here.
Re: Creating a wildcard reference [message #1403934 is a reply to message #1403931] Mon, 28 July 2014 16:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hi,

then i don not understand the meaning of *
where should * point to?

does * mean: the system knows where to refer to but the user does not have to specify a name?
the right object then is choosen by scoping? (there is only one possibility)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403935 is a reply to message #1403934] Mon, 28 July 2014 16:09 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
btw it would be nice to have a complete grammar and sample model i can copy and paste

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403945 is a reply to message #1403935] Mon, 28 July 2014 16:38 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
I will send you the complete grammar and models when I get to work tomorrow (I currently live in Japan, so it is 1 am for me at the moment).

I only want * to be a token, I don't want there to be any intelligent behaviour behind it. Think of it as, say I create the following Java method :
void foo(Integer a, Object b);

This allows me to call foo with any kind of object as b, I don't want to check if this object implements any interfaces or extends any class, it is just a wildcard, allowing me to call this function with any parameter.

By saying one of the parameters of a function is *, I basically only want to say that when I call this function, I won't have to check if the type of this parameter matches the type that was defined in the prototype.

By defining :
type mass;
function foo {
    parameters(mass, *)
}

The important thing is to know that foo takes two parameters, the first one is a mass, the second is any of the types that the user defined.
It becomes tricky in the sense that types are user-defined, in the very same file that functions are defined.
This means that the parameters have to be a referencing relation, in order to be able to reference types such as mass that were created just above, but still be able to reference a special type, one that was not created by the user like mass was.
In that sense, adding * to the parameters could mean adding a reference to a special object, one that was not created by the user, and that us developers are aware of. This however (even if it's possible, which I doubt), seems like an unclean way of working things out.

More than ever, thank you for your help, and sorry for the trouble. I'm especially sorry if I'm not very clear with my explanations...

Yann
Re: Creating a wildcard reference [message #1403946 is a reply to message #1403945] Mon, 28 July 2014 16:49 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
ok.

ps: the really interesting part for that is the metamodel and how it handles the * thing


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1403990 is a reply to message #1403946] Tue, 29 July 2014 01:46 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Please find the meta-model, the grammar and a sample model attached.
In this form of the grammar, there is but one error on line 20 of the grammar :
TypeRef returns Type:
[Type|EString];
I'm getting the following errors :
- no viable alternative at input 'EString'
- no viable alternative at input '['
But I sincerely doubt that these are the actual errors.

In the meta-model, I define the abstract supertype Type, three classes inherit it, two of them are actual types, the third one is WildcardType, which is basically all I do for handling *.

Thank you for your help.

[Updated on: Tue, 29 July 2014 02:41]

Report message to a moderator

Re: Creating a wildcard reference [message #1404000 is a reply to message #1403990] Tue, 29 July 2014 06:02 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,

your metamodel actually does not allow that.

functions have only cross refs to variables - not types.
you dont even have a rule for variables.

thus there is no place for the wildcard information to be stored.
of course you could write the wildcards to /dev/null but they would be totally lost in the ast.

so again the question: what would you do if you create a model instance with the ecore tree editor and not with xtext.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1404001 is a reply to message #1404000] Tue, 29 July 2014 06:43 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
FunctionCall is actually not the class to look at in the meta-model. Prototype is the one that defines the types of the parameters of a function. FunctionCall references a Prototype and the Variables with which the function will be called, I then check if the types of the variables match the types of the parameters defined in Prototype. In the case one of the parameters of Prototype is a wildcard, that check is passed automatically.

There are two top elements in this meta-model which can be made as a model instance :
Context defines Types and Prototypes (and is the one that is important for this issue).
Model uses a Context and defines Variables that have a Type defined in the used Context. It also defines FunctionCalls that also reference a Prototype of the Context.

Sorry if the names I've been giving in my earlier explanations were kind of confusing, I didn't want to get too much into the details of my model.

[Updated on: Tue, 29 July 2014 06:48]

Report message to a moderator

Re: Creating a wildcard reference [message #1404004 is a reply to message #1404001] Tue, 29 July 2014 06:54 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
<eClassifiers xsi:type="ecore:EClass" name="Prototype" abstract="true" eSuperTypes="#//NamedElement">
<eStructuralFeatures xsi:type="ecore:EReference" name="parameters" upperBound="-1"
eType="#//Type"/>
</eClassifiers>

there is no containment=true neither


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1404008 is a reply to message #1404004] Tue, 29 July 2014 07:15 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
I tried both ways and neither seem to work for me.
Yann Bondue:
If parameters is a simple reference, it will fail on "parameters+=Wildcard" because "parameters is not a containment reference".
If parameters is a containment reference, it will fail on "parameters+=[Type|EString]" because "parameters is a containment reference."

The aim of parameters is to hold references to a type that was defined by the user, so that we can create various prototypes that use the same types. If I made parameters a containment reference, I would have to recreate an actual instance of type for each prototype that uses it, OR there is a way to put a reference in a containment and that would solve the problem.

The other way around, which seems better the way I see it, is to keep parameters as as simple reference and have some kind of hidden reference to the wildcard type that can be used by the user.

We can look at it this way :
The following code would do the trick, but the reference is created by the user :
type mass {
    // type related definitions
}
type floor {
    // Type related defintions
}
type * {
    // No definitions required, this is the wildcard
}
prototype connect {
    parameters(mass, floor, *, *)
}

Now, if I had a way to simply have the type * exist, without asking the user to define it, I would be able to reference it, and the problem would be solved.
All I'd need is that global reference.

[Updated on: Tue, 29 July 2014 07:16]

Report message to a moderator

Re: Creating a wildcard reference [message #1404019 is a reply to message #1404008] Tue, 29 July 2014 07:49 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
As i said: if you can change the metamodel:

the function thing hold parameters (containment = true)

a Parameter is either a Wildcard or a TypeReference.

a TypeReference has a non containment reference to a type.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1404037 is a reply to message #1404019] Tue, 29 July 2014 09:41 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Well, I'm sorry, I just can't make that work. Do I have to indicate that the TypeRef rule has to return something ?

I have attached the smallest meta-model possible to this post to experience with the problem and I can't get it to compile, I don't know what I should define in the TypeRef rule.

Would you be so kind as to provide me with an actual grammar based on a metamodel that compiles with a rule allowing to put both kind of references in a containment ? Because I am getting desperate here.

Thank you
  • Attachment: test.ecore
    (Size: 1.07KB, Downloaded 149 times)
  • Attachment: MyDsl.xtext
    (Size: 0.80KB, Downloaded 94 times)
Re: Creating a wildcard reference [message #1404045 is a reply to message #1404037] Tue, 29 July 2014 10:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
HI,

i will give you an answer this evening so you can have a look tomorrow


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1404121 is a reply to message #1404045] Tue, 29 July 2014 17:51 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hi,

the problem still is that metamodel and grammar dont fit together.
i dont know what is set in the metamodel and what can be changed.

the TypeRef is not defined in the metamodel for example.
it should contain a cross ref to a type

here are a fixed grammar and metamodel

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

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

Context returns Context:
	{Context}
	'Context'
	'{'
		('types' '{' types+=ActualType ( "," types+=ActualType)* '}' )?
		('prototypes' '{' prototypes+=Prototype ( "," prototypes+=Prototype)* '}' )?
	'}';

	
Param returns Param:
	WildcardType | TypeRef;
	
TypeRef:
	type=[ActualType|ID];

WildcardType returns WildcardType:
	{WildcardType}'*';
	
Prototype returns Prototype:
	{Prototype}
	'Prototype'
	'{'
		('parameters' '{' parameters+=Param ( "," parameters+=Param)* '}' )?
	'}';

ActualType returns ActualType:
	{ActualType}
	name=ID
	;



<?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="test" nsURI="http://www.example.org/test" nsPrefix="test">
  <eClassifiers xsi:type="ecore:EClass" name="Prototype">
    <eStructuralFeatures xsi:type="ecore:EReference" name="parameters" upperBound="-1"
        eType="#//Param" containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="WildcardType" eSuperTypes="#//Param"/>
  <eClassifiers xsi:type="ecore:EClass" name="ActualType">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Context">
    <eStructuralFeatures xsi:type="ecore:EReference" name="prototypes" upperBound="-1"
        eType="#//Prototype" containment="true"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="types" upperBound="-1"
        eType="#//ActualType" containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Param"/>
  <eClassifiers xsi:type="ecore:EClass" name="TypeRef" eSuperTypes="#//Param">
    <eStructuralFeatures xsi:type="ecore:EReference" name="type" eType="#//ActualType"/>
  </eClassifiers>
</ecore:EPackage>



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Creating a wildcard reference [message #1404171 is a reply to message #1404121] Wed, 30 July 2014 08:15 Go to previous messageGo to next message
Yann Bondue is currently offline Yann BondueFriend
Messages: 11
Registered: May 2014
Junior Member
Thanks a bunch for your help.

What I had not understood was that basically TypeRef and Param were actual classes. I am not sure I really like what this implies though, it adds a whole layer and means there are lots of new objects being instantiated, however light they may be. I also don't really like having this kind of classes on my meta-model since they do not have any actual semantics for my application. Overall, it kind of looks unclean to me, but I suppose this works. Is this some kind of situation you encounter often ?

Thanks again for your assistance.
Re: Creating a wildcard reference [message #1404191 is a reply to message #1404171] Wed, 30 July 2014 10:31 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
you unfortuately have to decide for containment or not containment so adding this extra layer is the only chance. ive seen this beeing done multiples times. id not worry about the extra object since xtext creates and deletes object anyway while you are typing in the editor

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:Embeddededitor - Keybinding conflicts occur
Next Topic:Strange he path 'ControlFlow.irl' is unmapped
Goto Forum:
  


Current Time: Thu Mar 28 22:23:47 GMT 2024

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

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

Back to the top