Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Content proposal for grammar with syntactically similar rules
Content proposal for grammar with syntactically similar rules [message #1793858] Fri, 17 August 2018 11:34 Go to next message
Daniel Darvas is currently offline Daniel DarvasFriend
Messages: 10
Registered: July 2014
Junior Member
Hello,

TL;DR: having trouble providing content proposals with a grammar where two rules are syntactically very similar and potentially indistinguishable at the moment of providing the proposals.

I'm trying to provide content assist for a language in Xtext (v2.12). Here is a grammar similar to the original one, which is focusing on the current issue:

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

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

Model:
	(declarations+=Declaration)+
	statement=Statement;
	
Namespace: 
	'namespace' name=ID '{'
		(declarations+=Declaration)*
	'}';

Declaration: Namespace | Variable;

Variable:
	'variable' name=ID;
	
Statement:
	ReferenceStatement /*| ConflictingStatement*/;
	
ReferenceStatement:
	'stmt' ref=Reference;
	
/* ConflictingStatement:
	'stmt' name1=[Variable] '.' name2=[Namespace] '(' ')'; */
	
Reference:
	QualifiedReference;
	
QualifiedReference returns Reference:
	DirectReference ({QualifiedReference.prefix=current} '.' ref=DirectReference)*;

DirectReference:
	ref=[Declaration];


Here is an example instance:
namespace a {
	namespace b {
		variable c
		variable d
	}
}
variable x

stmt a.b.c


If the 'ConflictingStatement' rule is not used (commented out as above), everything is fine. I have written custom scoping for the qualified references. With this, the hierarchical references such as 'a.b.c' do work as expected. In the 'MyDslProposalProvider', I have overridden the 'completeQualifiedReference_Ref' method, and this is called with a 'QualifiedReference' instance as model when a proposal is required after 'a.' or 'a.b.'. This way I can access the prefix and provide correct suggestions. This is all as expected and needed.

However, I need the 'ConflictingStatement' rule in my grammar too. (Please discard the fact for a moment that the current 'ConflictingStatement' doesn't make any sense in any reasonable language.) If I include this rule too in the grammar, the 'completeQualifiedReference_Ref' method will be called with a 'Model' instance and I don't find any way to access 'a' when providing proposals after 'a.', other than accessing the tokens directly. I understand that 'stmt a.' can be both a 'ReferenceStatement' with a 'QualifiedReference' as 'ref', or a 'ConflictingStatement', I guess this is causing the problem.

Is there a way to resolve this problem without writing a custom parser for the qualified references? For the 'ConflictingStatement' this would not be an issue, I would be OK with a solution where I need to parse the token used as 'name1' manually. But for the 'ReferenceStatement' this would be rather inconvenient. I would like to avoid also to replace the 'name1' and 'name2' references of the 'ConflictingStatement' with a 'Reference' and restrict the acceptable values by a validator, as it would result in a very ugly AST and the scoping rules would also be different (i.e. a 'Namespace' cannot be within a 'Variable' in a 'QualifiedReference').

If needed, a workspace with the MWE above can be downloaded from https://www.dropbox.com/s/q6y09mu0c8tqan7/xtext-contentassist-debug.zip?dl=1 .

Thanks a lot for any tips,
Daniel
Re: Content proposal for grammar with syntactically similar rules [message #1793862 is a reply to message #1793858] Fri, 17 August 2018 12:31 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
did you consider to unify both rules and handle the restrictions in validation and or scoping?

Model:
	(declarations+=Declaration)+
	statement=Statement;
	
Namespace: 
	'namespace' name=ID '{'
		(declarations+=Declaration)*
	'}';

Declaration: Namespace | Variable;

Variable:
	'variable' name=ID;
	
Statement:
	(
		StatementReference ({ConflictingStatement.target=current}'('')'|{ReferenceStatement.ref=current})
	);

	
StatementReference returns Reference:
	'stmt' DotExpression
;

DotExpression returns Ref:
    DotExpressionStart ({DotExpression.ref=current}  "." tail=[Declaration])*
;
 
DotExpressionStart returns Ref:
    {DotExpressionStart} ref=[Declaration]
; 


class MyDslScopeProvider extends AbstractMyDslScopeProvider {

	override getScope(EObject context, EReference reference) {
		if (reference == MyDslPackage.Literals.DOT_EXPRESSION__TAIL) {
			if (context instanceof DotExpression) {
				val head = context.ref;
				switch (head) {
					DotExpressionStart:
						if (head.ref instanceof Namespace) {
							return Scopes::scopeFor((head.ref as Namespace).declarations)
						} else {
							return IScope.NULLSCOPE
						}
					DotExpression: {
						val tail = head.tail
						switch (tail) {
							Variable: return IScope::NULLSCOPE
							Namespace: return Scopes::scopeFor(tail.declarations)
							default: return IScope::NULLSCOPE
						}
					}
					default:
						return IScope::NULLSCOPE
				}

			}

		}
		super.getScope(context, reference)

	}
}


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

[Updated on: Fri, 17 August 2018 12:54]

Report message to a moderator

Re: Content proposal for grammar with syntactically similar rules [message #1794193 is a reply to message #1793862] Mon, 27 August 2018 08:41 Go to previous message
Daniel Darvas is currently offline Daniel DarvasFriend
Messages: 10
Registered: July 2014
Junior Member
Christian,
thank you for your help. Indeed, the grammar refactoring that you suggested solves the problem in case of the MWE.

Unfortunately it has the side effect that ConflictingStatement and ReferenceStatement cannot be referred directly from other rules. Of course they can be replaced with Statement and have some specific validation, but in our real case unfortunately it causes too many troubles in the grammar, introducing ambiguities and left recursiveness. It looks like the easiest solution will be to manually parse the qualified references to give proper suggestions to the user.
Thanks again for your time to suggest the solution above, it helped a lot to understand the possibilities to improve our grammar.
Previous Topic:How to split Xtext model file
Next Topic:Add Xtext nature during import of projects containing DSLs
Goto Forum:
  


Current Time: Tue Apr 23 14:11:03 GMT 2024

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

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

Back to the top