Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Ambiguous alternatives
Ambiguous alternatives [message #802098] Sun, 19 February 2012 11:56 Go to next message
Uli B is currently offline Uli BFriend
Messages: 36
Registered: January 2012
Member
The following rule Object always takes the first alternative (OK, both start with name=ID), and eventually leads to a "Couldn't resolve reference to ..." error.

Object:
  reference=[Assignment] | ((name=ID '=')? value=Expression);

Assignment:
  {Object} name=ID '=' value=Expression;



Is there any way to achieve "If the reference can be resolved, take it. Otherwise, take the alternative"?

Best Regards
Uli

[Updated on: Sun, 19 February 2012 12:25]

Report message to a moderator

Re: Ambiguous alternatives [message #802117 is a reply to message #802098] Sun, 19 February 2012 12:38 Go to previous messageGo to next message
Phil R is currently offline Phil RFriend
Messages: 99
Registered: September 2011
Member
Hi,

Try with syntactic predicates:

Object:
  (=> reference=[Assignment]) | ((name=ID '=')? value=Expression);

Assignment:
  {Object} name=ID '=' value=Expression;

haven't tested it
Re: Ambiguous alternatives [message #802130 is a reply to message #802117] Sun, 19 February 2012 13:07 Go to previous messageGo to next message
Uli B is currently offline Uli BFriend
Messages: 36
Registered: January 2012
Member
Hi Phil, thanks for your reply. I already tried syntactic predicates. Doesn't help. And I think the parser cannot do anything here (isn't it the linker which finds the reference or not?). So if at all, it must be at a later stage, where this is to be tweaked. But I have no clue. I could at some extra keyword (like a leading '$' for references), but since this is not necessary for later processing, I didn't really want that.

[Updated on: Sun, 19 February 2012 13:08]

Report message to a moderator

Re: Ambiguous alternatives [message #802305 is a reply to message #802130] Sun, 19 February 2012 19:25 Go to previous messageGo to next message
Phil R is currently offline Phil RFriend
Messages: 99
Registered: September 2011
Member
Hi,

Sorry my mistake.

As the 2 options are the same a solution I have in mind now is to only use the second alternative and making a content proposal etc for the name attribute to already declared "Assignment"'s

Regards,
Phil
Re: Ambiguous alternatives [message #802485 is a reply to message #802130] Mon, 20 February 2012 02:26 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 2012-19-02 14:07, Uli B wrote:
> Hi Phil, thanks for your reply. I already tried syntactic predicates.
> Doesn't help. And I think the parser cannot do anything here (isn't it
> the linker which finds the reference or not?). So if at all, it must be
> at a later stage, where this is to be tweaked. But I have no clue. I
> could at some extra keyword (like a leading '$' for references, but
> since this is not necessary for later processing, I didn't really want
> that.

I have implemented a grammar for a language where this type of construct
is common (i.e. it is either a reference or something else - and in my
case is is worse, because what it may link to is determined by context).

In my case, I wrote my own linking.

What you could try is to do the following:
- have one rule that assigns the ID, use a predicate so this is always
choosen, and place it first of the two) as the serializer picks the
first rule if there is an ambiguity.

i.e. something like

MyRule returns MyObj: ((=> someValue = ID)|(someLink = [SomeType|ID])) ;

- Perform the extra linking by implementing your own linker class
derived from LazyLinker - implement the method afterModelLinked. Bind
your linker in the runtime module as a replacement for the currently
used linker.

- In the afterModelLinked method - perform the extra linking step by
iterating the model to find all MyObj instances, and if they have
"someValue" set to an ID that is found in the index, get the reference
and set it as "someLink".

There are a couple of additional responsibilities when it comes to
linking as the environment needs to find information to construct "build
order", and to know changes that may require a rebuild. For the built in
support for links this is done automatically. Using a solution like the
above may be covered by the default implementation. If not, you need to
record names you resolved/could not resolve/ambiguous resolved (so that
if one of those names appear or disappear in the index, you will get a
rebuild/relink). You also need to record the references you are adding.
Finally, all the recorded material is being asked for when the resource
is "described"; this is done in a ResourceDescriptionStrategy - where
you can pick up the recorded information and return it mixed in whit the
default provided information, and in ResourceDescription where the set
of imported names is produced. (If you need any of these things, you can
look at my code in cloudsmith/geppetto at github).

I have not tried the solution I am proposing. My implementation does not
have the reference as a feature; instead I use an adapter to associate
the resulting reference from the custom linking with the object
functioning as a reference.

- You may have to deal with serialization too; if the value is found
both as an ID, and as a reference the serilizer is facing an ambiguity
(the grammar states one or the other). Don't know if it is enough to
make the reference transient (but then it may be skipped by the default
support for references...).

You have to experiment and see what works for you.

One of the Xtext gurus may have some other advice that makes this easier.

As you already pointed out, the easiest solution is to use a syntactic
marker that differentiates between plain ID and a reference (e.g. using
a '$' prefix or similar) - then it all works out of the box.

Regards
- henrik
Re: Ambiguous alternatives [message #807513 is a reply to message #802485] Sun, 26 February 2012 16:00 Go to previous messageGo to next message
Uli B is currently offline Uli BFriend
Messages: 36
Registered: January 2012
Member
Thank you so much Henrik for your detailed comment. For the extra linking, I'm trying to use afterModelLinked. Here is what I have so far:

  @Override
  protected void afterModelLinked(EObject model, IDiagnosticConsumer diagnosticsConsumer) {
		IResourceDescriptions index = resourceDescriptionsProvider.getResourceDescriptions(model.eResource());
		IResourceDescription resDesc = index.getResourceDescription(model.eResource().getURI());
		if (resDesc != null) {
			Iterable<IEObjectDescription> exportedObjects = resDesc.getExportedObjectsByType(MyDslPackage.Literals.OBJECT);
			Iterator<EObject> iter = model.eAllContents();
	  	while (iter.hasNext()) {
				EObject o = iter.next();
				if (o instanceof Object) {
					// (name, value): if ("name", "value"): assigned, if (null, "value"): unassigned, (if (null, null): reference, n/a), if (null, "name" (from index)): unresolved
					String n = ((Object) o).getName();
					String v = ((Object) o).getValue();
					Iterator<IEObjectDescription> itex = exportedObjects.iterator();
				  while (itex.hasNext()) {
					  IEObjectDescription od = itex.next();
					  if ((n == null) && (v.equals(od.getName().getLastSegment()))) { // name is null and value is the name of an exported Object
					  	// Found it. But now: How to link o to od?
						  break;
					  }
				  }
				} 		  
			}
		}
  }


The code checks for each instance of an "Object" o if it has a value that can be found as a name of an object od in the index. If so, o cross references od. Now, how can I perform the actual link? I had a look at what the LazyLinker does, but that didn't make things clearer to me ...

Any suggestions?

Best Regards
Uli
Re: Ambiguous alternatives [message #807556 is a reply to message #807513] Sun, 26 February 2012 17:28 Go to previous messageGo to next message
Meinte Boersma is currently offline Meinte BoersmaFriend
Messages: 434
Registered: July 2009
Location: Leiden, Netherlands
Senior Member
You can do these kinds of things by using good'ole scoping: http://dslmeinte.wordpress.com/2010/12/08/getting-alternative-cross-references-to-work-with-existing-epackages/
The blog takes a different motivation but the trick is the same.


Re: Ambiguous alternatives [message #809392 is a reply to message #807556] Tue, 28 February 2012 20:35 Go to previous messageGo to next message
Uli B is currently offline Uli BFriend
Messages: 36
Registered: January 2012
Member
Hm, in my case one of the two alternatives is not a reference. How can I fit this to the example in the blog?
Re: Ambiguous alternatives [message #809904 is a reply to message #809392] Wed, 29 February 2012 12:26 Go to previous message
Meinte Boersma is currently offline Meinte BoersmaFriend
Messages: 434
Registered: July 2009
Location: Leiden, Netherlands
Senior Member
Uli, you're right: my example is all-references-only. There is a parallel thread with the same problem, btw (I just posted in that).

Previous Topic:[Xtext] Enabling user customization for formatting
Next Topic:Collect attributes from parser rules
Goto Forum:
  


Current Time: Sun Mar 29 18:51:14 GMT 2020

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

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

Back to the top