Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » no suggestions for node (xpath)
no suggestions for node (xpath) [message #734132] Thu, 06 October 2011 19:53 Go to next message
gary s thompson is currently offline gary s thompsonFriend
Messages: 75
Registered: July 2009
Member
i am trying to produce an xpath like grammar editor and have the following (there is a bit more but this is the fragment that makes up a path once i implemented a scopeprovider)

RelativeLocationPathHead:
  step=Step (tail=RelativeLocationPathTail)?
  ;

RelativeLocationPathTail:
	operator+=('/'/* |'//'*/) step=Step (tail=RelativeLocationPathTail)?
	
;
Step:
	axis=AxisSpecifier nodeTest=[ecore::EReference] predicates+=Predicate*  
;




AxisName:
    FullAxisName '::'| AttributeAxisName
;

 AttributeAxisName:
	'@'
;

 FullAxisName:
     'ancestor'
  |  'ancestor-or-self'
  |  'attribute'
  |  'child'
  |  'descendant'
  |  'descendant-or-self'
  |  'following'
  |  'following-sibling'
  |  'namespace'
  |  'parent'
  |  'preceding'
  |  'preceding-sibling'
  |  'self'
  ;

AxisSpecifier:
   {AxisSpecifier} axisName=AxisName?
;	


now I can write the following

windle/nmrProjects/experiments[dataSources/peakLists/peaks/peakDims]
windle/nmrProjects/experiments[preceding-sibling::dataSources/peakLists/peaks/peakDims]

and it all works however, I can't get the text editor to suggest AxisSpecifiers such as preceding-sibling::. But, once they are completed they don't result in a syntax error. Does anyone have a suggestion of whats wrong or what I need to do?

regards
gary

for reference here is the complete syntax

// automatically generated by Xtext
grammar uk.ac.leeds.nsxl2.cork.Cork with org.eclipse.xtext.common.Terminals 


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


	

generate cork "http://www.cork.nsxl2.leeds.ac.uk/cork/Cork"

Cork:
	elements+=AbstractElement*;
	



AbstractElement:
	 PathDefinition  | RootRef
;
	 

RootRef:
	Open
;

Open:
	'open' name=ID 'from' file=STRING
;


Expression:
	OrExpr
;

OrExpr  :  
	expr+=AndExpr /* ('or' expr+=AndExpr)* */
;

AndExpr  :  
	expr+=EqualityExpr /* ('and' expr+=EqualityExpr)* */
  ;
  
EqualityExpr
  :  expr+=relationalExpr /* (operator+=('='|'!=') expr+=relationalExpr)* */
  ;

relationalExpr
  :  expr+=AdditiveExpr /* (operator+=('<'|'>'|'<='|'>=') expr+=AdditiveExpr)* */
  ;

AdditiveExpr
  :  expr+=MultiplicativeExpr /*(operator+=('+'|'-') expr+=MultiplicativeExpr)* */
  ;

MultiplicativeExpr:
  rootExpr=UnaryExprNoRoot /* (operator+=('*'|'div'|'mod') expr+=MultiplicativeExpr)?
  |  '/' (operator+=('div'|'mod') expr+=MultiplicativeExpr)? */

;

//Minus:
//	'-'
//;

UnaryExprNoRoot
  :  /*numMinus+=Minus* */ expr=UnionExprNoRoot
  ;
  
UnionExprNoRoot
  :  path=PathExprNoRoot /* ('|' expr+=UnionExprNoRoot)? */
  /* |  '/' '|' expr+=UnionExprNoRoot */
  ;
  
PathExprNoRoot
  :  path=LocationPath /* 
  |  filter=filterExpr (operator+=('/'|'//') path+=relativeLocationPath)?*/
  ;

LocationPath:
  relativePath=RelativeLocationPathHead
  /* |  absoluteLocationPathNoroot */
  ;

RelativeLocationPathHead:
  step=Step (tail=RelativeLocationPathTail)?
  ;

RelativeLocationPathTail:
	operator+=('/'/* |'//'*/) step=Step (tail=RelativeLocationPathTail)?
	
;
Step:
	axis=AxisSpecifier nodeTest=[ecore::EReference]/*NCName*/ predicates+=Predicate*  
 /* |  abbreviatedStep=AbbreviatedStep */
  ;



//NodeTest:
//  NameTest
//  /* |  NodeType '(' ')'
//  |  'processing-instruction' '(' Literal ')'*/
//  ;

//NameTest:
//	/* '*'
//  |  nCName ':' '*'  |*/
//   qName=NCName
//
//	
//;
//
////QName:
////	nCName+=NCName (':' nCName+=NCName)?
////  ;
//
//NCName:
//	 nnCName=[ecore::EStructuralFeature] /* | axis=AxisName */
//  
//;




AxisName:
    FullAxisName '::'| AttributeAxisName
;

 AttributeAxisName:
	'@'
;

 FullAxisName:
     'ancestor'
  |  'ancestor-or-self'
  |  'attribute'
  |  'child'
  |  'descendant'
  |  'descendant-or-self'
  |  'following'
  |  'following-sibling'
  |  'namespace'
  |  'parent'
  |  'preceding'
  |  'preceding-sibling'
  |  'self'
  ;






AxisSpecifier:
   {AxisSpecifier} axisName=AxisName?
;	

//
//
//AbbreviatedStep:
//    abbreviation=('.' |  '..')
//;
  



	


PathDefinition:
   'path' name=ID ':' head=PathHead;


Predicate:
	'[' expression=Expression ']'
;
  

PathHead:
   root=[RootRef] (tail=RelativeLocationPathTail)?;
  

//PathTail:
//   '/' feature=[ecore::EReference] (predicates+=Predicate)* (tail=PathTail)?;


and the scopeprovider

/*
 * generated by Xtext
 */
package uk.ac.leeds.nsxl2.cork.scoping;

import java.util.List;

import memops.ecore_api.Implementation.ImplementationPackage;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider;

import uk.ac.leeds.nsxl2.cork.cork.CorkPackage;
import uk.ac.leeds.nsxl2.cork.cork.PathHead;
import uk.ac.leeds.nsxl2.cork.cork.Predicate;
import uk.ac.leeds.nsxl2.cork.cork.RelativeLocationPathHead;
import uk.ac.leeds.nsxl2.cork.cork.RelativeLocationPathTail;


/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on
 * how and when to use it
 * 
 */
public class CorkScopeProvider extends AbstractDeclarativeScopeProvider {
	private final static Class<?>[] SCOPE_CONTAINER_TYPES = { RelativeLocationPathTail.class,
            RelativeLocationPathHead.class, 
            PathHead.class};

    private final static Class<?>[] PATH_ELEMENT_STEP_CONTAINER_TYPES = { RelativeLocationPathTail.class,
				  RelativeLocationPathHead.class,
				  Predicate.class};


	@Override
	public IScope getScope(EObject context, EReference reference) {
		final CorkPackage CORK_EPACKAGE = CorkPackage.eINSTANCE;
		final EClass STEP_ECLASS = CORK_EPACKAGE.getStep();
		final EClass PATH_HEAD_ECLASS = CORK_EPACKAGE.getPathHead();
		final EClass RELATIVE_LOCATION_PATH_HEAD_ECLASS = CORK_EPACKAGE.getRelativeLocationPathHead();
		final EClass RELATIVE_LOCATION_PATH_TAIL_ECLASS = CORK_EPACKAGE.getRelativeLocationPathTail();

		reportScopeContext(context, reference);

		IScope result = null;
		
		EClass referenceContext = (EClass) reference.eContainer();

		if (referenceContext.equals(STEP_ECLASS)) {
			EObject container = findScopeContainer(context);
			
			if (sameClass(container, PATH_HEAD_ECLASS)) {
				result = getScopeForPathHead();
		    } else if (sameClass(container, RELATIVE_LOCATION_PATH_TAIL_ECLASS)) {
				RelativeLocationPathTail pathTail = (RelativeLocationPathTail) container;
				result=getScopeForRelativeLocationPathTail(pathTail);
			} else if (sameClass(container, RELATIVE_LOCATION_PATH_HEAD_ECLASS)) {
				RelativeLocationPathHead relativeLocationPathHead  = (RelativeLocationPathHead) container;
				result =  getScopeForRelativeLocationPathHead((relativeLocationPathHead));
			}
		}


		if (result == null) {
			result = super.getScope(context, reference);
		}
		
		
		return result;

	}

	private boolean sameClass(EObject container, EClass eClass) {
		return container.eClass().equals(eClass);
	}

	private EObject findScopeContainer(EObject context) {
		EObject stepContainer = findParentByTypesOrdered(context, PATH_ELEMENT_STEP_CONTAINER_TYPES);
		EObject scopeContainer = findParentByTypesOrdered(stepContainer.eContainer(), SCOPE_CONTAINER_TYPES);
		if (scopeContainer !=  null) {
			stepContainer =  scopeContainer;
		}
		return stepContainer;
	}

	
	
	private IScope getScopeForRelativeLocationPathTail(
			RelativeLocationPathTail container) {
		EReference tailReference = (EReference) container.getStep()
				.getNodeTest();
		IScope result = getScopeFromReference(tailReference);
		return result;
	}
	
	private IScope getScopeForRelativeLocationPathHead(RelativeLocationPathHead container) {
		EReference tailReference = (EReference) container.getStep()
				.getNodeTest();
		IScope result = getScopeFromReference(tailReference);
		return result;
	}
	
	private IScope getScopeForPathHead() {
		EClass root = ImplementationPackage.eINSTANCE.getMemopsRoot();
		List<EReference> structuralFeatures = references(root);
		IScope result = Scopes.scopeFor(structuralFeatures);
		return result;
	}


	private void reportScopeContext(EObject context, EReference reference) {
		SimpleLocalScopeProvider delegate = (SimpleLocalScopeProvider) getDelegate();

		EObject parent = context.eContainer();
		
		System.err.println("---------\n");
		System.err.println("containers" + " " + listContainers(context));

		System.err.println("context: " + context);
		EClass refContainer = (EClass) reference.eContainer();
		System.err.println("ref: " + refContainer.getInstanceClassName() + "->"
				+ reference.getName());
		System.err.println("parent: " + parent);
		System.err.println("delegate: " + delegate);
		System.err.println();
	}

	private IScope getScopeFromReference(EReference tailReference) {
		EClassifier tailType = tailReference.getEType();
		IScope result = null;
		if (tailType instanceof EClass) {
			EClass referenceType = (EClass) tailType;
			List<EReference> references = references(referenceType);
			result = Scopes.scopeFor(references);
		}
		return result;
	}


	@SuppressWarnings("unchecked")
	private <T extends EObject> T findParentByTypesOrdered(EObject context,
			Class<?>[] parentTypeList) {
		T result = null;
		EObject parent = context;

		while (parent.eContainer() != null) {
			for (Class<?> clazz : parentTypeList) {
				if (clazz.isAssignableFrom(parent.getClass())) {
					result = (T) parent;
					break;
				}
			}
			if (result != null) {
				break;
			} else {
				parent = parent.eContainer();
			}
		}
		
		return result;
	}

	private String listContainers(EObject parentPath) {
		String result = "";

		EObject parent = parentPath;
		while (parent.eContainer() != null) {
			result = result + " " + parent.eClass().getName();
			parent = parent.eContainer();
		}

		return result;
	}

	private List<EReference> references(EClass target) {
		return org.eclipse.xtext.EcoreUtil2.typeSelect(
				target.getEAllReferences(), EReference.class);
	}
}
Re: no suggestions for node (xpath) [message #734138 is a reply to message #734132] Thu, 06 October 2011 20:10 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6499
Registered: July 2009
Senior Member
Hi,

the "problem" is that you intoduced AxisName as a DataType rule. thus you have to care about autocompletion yourself. the generated method in the Abstract ProposalProvider is empty.

public void complete_AxisName(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		// subclasses may override
	}


alteratively you could change the grammar to produce a real EObject for v

AxisName:
    FullAxisName | AttributeAxisName
;

 AttributeAxisName:
	{AttributeAxisName}'@'
;

 FullAxisName:
     value= ('ancestor'
  |  'ancestor-or-self'
  |  'attribute'
  |  'child'
  |  'descendant'
  |  'descendant-or-self'
  |  'following'
  |  'following-sibling'
  |  'namespace'
  |  'parent'
  |  'preceding'
  |  'preceding-sibling'
  |  'self') '::'
  ;


~Christian
Re: no suggestions for node (xpath) [message #989788 is a reply to message #734132] Fri, 07 December 2012 19:12 Go to previous message
Robert Brodt is currently offline Robert BrodtFriend
Messages: 618
Registered: August 2010
Location: Colorado Springs, CO
Senior Member

Hi Gary,

Were you ever able to finish this project? I would be interested in building on your work for inclusion in the BPEL Designer eclipse project.

Thanks!
Bob
Previous Topic:Embedded editor is missing some functionality
Next Topic:Issue removing whitespace on save
Goto Forum:
  


Current Time: Fri Nov 28 03:17:31 GMT 2014

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

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