Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Context aware grammar help
Context aware grammar help [message #1793041] Sun, 29 July 2018 15:38 Go to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
Hi,

I'm trying to implement a conditions DSL which would looks something like this:
select <domain specific class> where <property> <condition> <literal> [(AND|OR) <property> <condition> <literal>]*

So in the end it should be something like this:
select person where name == "Mykola" AND address.city == "L'viv"
or this:
select location where title != "Office" OR cooridinates.latitude > 150
etc.

The problem here is to make parsing and autocompletion code aware of the context, which is <domain specific class> - so that it would only allow (and autocomplete) the properties of that domain specific class. Also those properties might be of different types themselves, which are either primitive (string, int, float) or sub-objects.

What would be the simplest/best way to implement this?

Since in the end I'm going to work with Java classes representing DSL classes, I thought that maybe Xbase is the way - but first of all I didn't find how to make it import particular classes into DSL, and then it also seems to have a lot of things that I don't want to end up in my DSL (it should be limited so it would be secure - so that no vulnerabilities like code injection would be possible).

Plus it seems to be rather complex and very hard to wrap one's head around, at least in the beginning.

Re: Context aware grammar help [message #1793080 is a reply to message #1793041] Mon, 30 July 2018 18:55 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
the thing you are looking for is "Scoping"

Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793102 is a reply to message #1793080] Tue, 31 July 2018 08:33 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
Thanks, Christian, for your answer.

However, it's not clear to me how scoping alone can help.
The question is - how can I define a model outside of a DSL to be used inside of a DSL (e.g. classes like person or location with their own properties that may hold instances of different classes etc). The examples of scoping I've seen so far (in official documentation, speech videos, books etc - I've checked a lot of them) are mostly focused on cases when model is defined within DSL, and then it is (cross-)referenced in same DSL.

But how can I define model externally? Should I use Ecore for that? Or can I somehow import POJO classes into DSL to be used? Is it at all possible implement some completion/scoping using reflection on POJO classes, and if it is - where do I even start?
If it is not possible - what are the alternatives? Only Ecore? How would I add an Ecore model to an Xtext project? Seems I have to modify workflow (mwe2) file to generate model from .ecore (or is it .genmodel?) file, but what else has to be done?

I'm sorry for so many questions, but the issue seems quite confusing and much more complex than I've originally anticipated.

[Updated on: Tue, 31 July 2018 08:35]

Report message to a moderator

Re: Context aware grammar help [message #1793103 is a reply to message #1793102] Tue, 31 July 2018 08:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
you did no explain where your domainspecific classses and its properties come from.
can you please give some more context


Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793105 is a reply to message #1793103] Tue, 31 July 2018 08:41 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
I would like to define them statically in source code (so they would not change after build - no need to have any dynamic definitions in runtime). How do I do that - that is actually the question.

The best would be if I could just create a few Java classes to represent the model (e.g. class Address with string property city, class Person with Address property etc), and then somehow make them visible to an Xtext DSL (but only those specific classes).
However, I'm not sure if this is possible. And if it is - how can this be done.

I've found out that an Ecore model seems similar to what I want - I can define these classes with their properties and relations in an Ecore mode (.ecore file).
However, I'm not sure how do I proceed from there. Or should I even do that - or perhaps there is a better alternative.

[Updated on: Tue, 31 July 2018 08:42]

Report message to a moderator

Re: Context aware grammar help [message #1793114 is a reply to message #1793105] Tue, 31 July 2018 10:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
you could either
- have no references at all and simply implement content assist an validation
- reference to EClasses and EAttributes
- reference to a custom metamodel and grammar


Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793118 is a reply to message #1793114] Tue, 31 July 2018 11:05 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
Could you hint me to some detail regarding the first option?
For example DSL code:
1. select person where name == "Mykola" AND address.city == "L'viv"
2. select location where title != "Office" OR cooridinates.latitude > 150
I would need to have autocompletion to select between person and location.
Then I would need context-dependent autocompletion to select between person properties (name/address) and location properties (title, coordinates), and same goes for subproperties (city for address, latitude for coordinate).
Also I would have to check for types of those properties (latitude is int, while city is String etc).
Re: Context aware grammar help [message #1793119 is a reply to message #1793118] Tue, 31 July 2018 11:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
as i said: (1) is doing it completely manually by implementation proposal provider and validator.
you implement the complete methods. have a look at the context object. match that to your metaclasses and propose stuff accordingly


Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793121 is a reply to message #1793119] Tue, 31 July 2018 11:16 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
The problem is that web editor is needed for this DSL, not an Eclipse plugin, so as far as I can tell using Proposal Provider is not an option, as this one only works for Eclipse plugin.
Re: Context aware grammar help [message #1793125 is a reply to message #1793121] Tue, 31 July 2018 11:43 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
P.S. Sorry, found the new API for proposal provider that should be Eclipse plugin independent (thanks to your comment on StackOverflow)
https://github.com/eclipse/xtext-web/blob/e4a9b945f48dc439ddfdd46c62fcd40f1cb51b51/org.eclipse.xtext.web.example.statemachine.ide/src/org/eclipse/xtext/web/example/statemachine/ide/StatemachineWebContentProposalProvider.xtend

Pity it's not documented at all. Will try to figure it out from examples.
Re: Context aware grammar help [message #1793131 is a reply to message #1793125] Tue, 31 July 2018 12:34 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
have created https://github.com/eclipse/xtext/issues/1252
but its unlikely this will come unless somebody steps up and provides a pr


Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793516 is a reply to message #1793131] Thu, 09 August 2018 12:17 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
I've run into a problem with the proposal provider when implementing completion for properties and subproperties of some entity.

Here's the example DSL text of what I'm trying to achieve:
for User as user find @user.name == "Mykola" && @user.address.city == "Lviv"


In my grammar I have a code like this for "fully qualified names":
Rule: 'for' entityRefDef=EntityReferenceDefinition 'find' conditions=Conditions;

FQN:
	'@' entityReference=[EntityReferenceDefinition|EntityReferenceName] ('.' property+=ID)*;

EntityReferenceDefinition:
	entityType=ID 'as' name= EntityReferenceName;

EntityReferenceName:
	ID;

Conditions:
... bunch of logical conditions and comparison related code with left factoring etc


In my content proposal provider I've added something like this:
	@Inject EntityMetadataProvider metaProvider

	override dispatch createProposals(RuleCall ruleCall, ContentAssistContext context,
		IIdeContentProposalAcceptor acceptor) {
		if (context.currentModel instanceof FQN && ruleCall.rule.name == "ID" &&
			ruleCall.eContainer instanceof Assignment && (ruleCall.eContainer as Assignment).feature == "property") {
			val fqn = context.currentModel as FQN;
			if (fqn.entityReference !== null) {
				for (String propertyName : metaProvider.getPropertyNames(fqn.entityReference.entityType, fqn.property)) {
					proposeString(propertyName, acceptor);
				}
			}
		}
	}

	def protected proposeString(String proposalText, IIdeContentProposalAcceptor acceptor) {
		val proposal = new ContentAssistEntry();
		proposal.proposal = proposalText
		acceptor.accept(proposal, proposalPriorities.getDefaultPriority(proposal));
	}

The EntityMetadataProvider provides lists of properties given entity type (e.g. "User") and property path (["name", "address"] for empty property path, ["city", "street", "building", ...] for "address" etc - supporting any arbitrary depth).

It almost works, except for cases when I try to do completion when part of the text is already added.

E.g. for this text
for User as user find @user.name == "Mykola" && @user.address.city == "Lviv"

placing cursor after "@user." should provide completions ["name", "address"]. But it only does so if no property is already written afterwards (e.g. for input like "for User as user find @user." or "for User as user find @user. && @user.address.city == "Lviv"" if cursor is placed after first occurrence of "@user.", the one followed by a space and &&).

If I place cursor after "@user." in text like "... @user.address" I get completions ["city", "street", "building", ...] because (context.currentModel as FQN).property already contains address - even though I moved cursor behind it and I'm trying to replace it.

First of all, I haven't found any way to figure out which of (context.currentModel as FQN).property values are behind the cursor, and which are ahead of it.
Second, I'm not sure if implementing completion this way makes sense at all - or there is a simpler or more correct way to implement the same functionality.
In future I also want to add corresponding validation - so only properties that are appearing in completion are allowed.

So in view of this, is there a better approach for me to implement this completion? Or if there isn't - how can this particular issue be fixed?

[Updated on: Thu, 09 August 2018 12:21]

Report message to a moderator

Re: Context aware grammar help [message #1793528 is a reply to message #1793516] Thu, 09 August 2018 15:11 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 12237
Registered: July 2009
Senior Member
use a debugger to digg into the context object. it has nother stuff like node, prefix etc.

Need professional support for Xtext, Xpand, EMF?
Go to: https://xtext.itemis.com
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Context aware grammar help [message #1793558 is a reply to message #1793528] Fri, 10 August 2018 05:53 Go to previous messageGo to next message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
That's exactly how I wrote what I already have. But I haven't found the way to fix this particular issue.
There are things like last complete node in context etc, but here I have just a ('.' property+=ID)* which does not create new nodes. Would I have to change grammar in order to circumvent the issue then?

Also since I wrote the code using the debugger, I'm very uncertain if it's written in a proper way, and I haven't even started implementing corresponding validation yet.
Re: Context aware grammar help [message #1793565 is a reply to message #1793558] Fri, 10 August 2018 09:28 Go to previous message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 17
Registered: July 2018
Junior Member
P.S. I'm currently working with this option. This allows me to have hierarchy of Property objects, so I could walk up the tree to check parent properties only.
Seems like a viable fix, but I had to rewrite completion code with regard to changes in generated model:
Rule: 'for' entityRefDef=EntityReferenceDefinition 'find' conditions=Conditions;

FQN:
	'@' entityReference=[EntityReferenceDefinition|EntityReferenceName] ('.' property=Property)?;

Property:
	name=ID ('.' property=Property)?

EntityReferenceDefinition:
	entityType=ID 'as' name= EntityReferenceName;

EntityReferenceName:
	ID;

Conditions:
... bunch of logical conditions and comparison related code with left factoring etc

[Updated on: Fri, 10 August 2018 09:29]

Report message to a moderator

Previous Topic:What builds my webxml for my war-file
Next Topic:Problem using XtextServlet in SpringBoot Application
Goto Forum:
  


Current Time: Sat Sep 22 17:38:36 GMT 2018

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

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

Back to the top