XTEXT Scoping Issue [message #1853496] |
Tue, 05 July 2022 13:49 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
Example of Grammar that doesnt Work:
grammar org.xtext.EcuCValues_Extend with org.eclipse.xtext.common.Terminals
generate ecuCValues_Extend "http://www.xtext.org/EcuCValues_Extend"
Model:
(lines+=Line)*
;
Line:
(rule = Rule)
;
Rule:
("ForEach" anchor=AnchorValue);
AnchorValue:
(ARClass = TAG_NO_DOT ".class") | (arpath=AbsoluteARPathContainer);
AbsoluteARPathContainer:
"/" path = ARPathContainer_With_Relative
;
ARPathContainer_With_Relative:
path+=(ARPathElement)+;
ARPathElement:
//(move=TAG_NO_DOT_RULE | move_rel=RELATIVE_MOVEMENT) "/"
(move=[TAG_NO_DOT_FUNC] | move_rel=RELATIVE_MOVEMENT) "/"
;
TAG_NO_DOT_FUNC:
name = TAG_NO_DOT
;
QualifiedName:
TAG_NO_DOT
;
enum RELATIVE_MOVEMENT:
ONEBACK=".." | HERE=".";
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
Example of Grammar that does work:
grammar org.xtext.EcuCValues_Extend with org.eclipse.xtext.common.Terminals
generate ecuCValues_Extend "http://www.xtext.org/EcuCValues_Extend"
Model:
(lines+=Line)*
;
Line:
(rule = Rule)
;
Rule:
("ForEach" anchor=AnchorValue);
AnchorValue:
(ARClass = TAG_NO_DOT ".class") | (arpath=AbsoluteARPathContainer);
AbsoluteARPathContainer:
"/" path = ARPathContainer_With_Relative
;
ARPathContainer_With_Relative:
path+=(ARPathElement)+;
ARPathElement:
//(move=TAG_NO_DOT_RULE | move_rel=RELATIVE_MOVEMENT) "/"
(move=TAG_NO_DOT_FUNC | move_rel=RELATIVE_MOVEMENT) "/"
;
TAG_NO_DOT_FUNC:
name = TAG_NO_DOT
;
QualifiedName:
TAG_NO_DOT
;
enum RELATIVE_MOVEMENT:
ONEBACK=".." | HERE=".";
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
Line of Syntax I want it to parse:
ForEach /Com/ComConfig/ComSignalGroup/
for the XTEXT that doesnt work I get:
required (...)+ loop did not match anything at input
The only difference between the two XTEXT files is the introduction of Scoping. Why does the Scoping break my Grammar? I dont understand and its hard to google for the solution.
[Updated on: Wed, 06 July 2022 09:00] Report message to a moderator
|
|
|
|
|
|
|
|
Re: XTEXT Scoping Issue [message #1853520 is a reply to message #1853518] |
Wed, 06 July 2022 12:50 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
Thank you for your useful input Christian. You have found the spot where my Understanding of XTEXT is lacking.
I thought the declaration of TAG_NO_DOT_FUNC is:
TAG_NO_DOT_FUNC:
name = TAG_NO_DOT
;
apparently for you this is just a reference.
> xtext can only resolved things that have a name.
As you can see TAG_NO_DOT_FUNC does have an element called name. So why can it not be resolved by default?
> TAG_NO_DOT_FUNC is uncalled
What does uncalled mean? How can I call it?
[Updated on: Wed, 06 July 2022 13:20] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
Re: XTEXT Scoping Issue [message #1853552 is a reply to message #1853549] |
Thu, 07 July 2022 14:53 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
I did add this entry to my Model:
grammar org.xtext.EcuCValues_Extend with org.eclipse.xtext.common.Terminals
generate ecuCValues_Extend "http://www.xtext.org/EcuCValues_Extend"
Model:
(stuff+=TAG_NO_DOT_FUNC)*
(lines+=Line)*
;
Line:
(rule = Rule)
;
Rule:
("ForEach" anchor=AnchorValue);
AnchorValue:
(ARClass = TAG_NO_DOT ".class") | (arpath=AbsoluteARPathContainer);
AbsoluteARPathContainer:
"/" path = ARPathContainer_With_Relative
;
ARPathContainer_With_Relative:
path+=(ARPathElement)+;
ARPathElement:
(name=[TAG_NO_DOT_FUNC|QualifiedName] | move_rel=RELATIVE_MOVEMENT) "/"
;
TAG_NO_DOT_FUNC:
name = ID
;
QualifiedName:
ID('.' ID)*
;
enum RELATIVE_MOVEMENT:
ONEBACK=".." | HERE=".";
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
I still get "required (...)+ loop did not match anything at input 'Com'".
for
ForEach /Com/CanTpConfig/CanTpChannel/CanTpTxNSdu/
[Updated on: Thu, 07 July 2022 15:04] Report message to a moderator
|
|
|
|
|
|
Re: XTEXT Scoping Issue [message #1853609 is a reply to message #1853568] |
Mon, 11 July 2022 07:41 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
Hello Christian,
I am not progressing much with my issue. I am reading a lot about Scoping in XTEXT in parallel to better understand. It seems to be the most difficult aspect of XTEXT and my knowledge is still too fuzzy.
Could you please help me once more?
Here is my Grammar:
grammar org.xtext.EcuCValues_Extend with org.eclipse.xtext.common.Terminals
generate ecuCValues_Extend "http://www.xtext.org/EcuCValues_Extend"
Model:
(tagnodots+=TAG_NO_DOT_FUNC)*
(lines+=Line)*
;
Line:
(rule = Rule)
;
Rule:
("ForEach" anchor=AnchorValue);
AnchorValue:
(ARClass = TAG_NO_DOT ".class") | (arpath=AbsoluteARPathContainer);
AbsoluteARPathContainer:
"/" path = ARPathContainer_With_Relative
;
ARPathContainer_With_Relative:
name=(ARPathElement);
ARPathElement:
name=[TAG_NO_DOT_FUNC|QualifiedName] "/"
;
TAG_NO_DOT_FUNC:
name = ID
;
QualifiedName:
ID('.'ID)*
;
enum RELATIVE_MOVEMENT:
ONEBACK=".." | HERE=".";
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
I tried to follow your advice so far but its not helping. For Model:
ForEach /CanTpdsConfig/CanTpChannel/CanTpTxNSdu/
I get the Error:
Couldn't resolve reference to TAG_NO_DOT_FUNC 'canTpdsConfig'.
I am trying to Debug the Parser Code. I can see where it goes wrong but I can not understand what goes wrong because the Parser code is not that "human readable".
I can see that he gets a eRecognitionException in function:
// InternalEcuCValues_Extend.g:422:1: ruleQualifiedName returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] : (this_ID_0= RULE_ID (kw= '.' this_ID_2= RULE_ID )* ) ;
public final AntlrDatatypeRuleToken ruleQualifiedName() throws RecognitionException {
AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken();
Token this_ID_0=null;
Token kw=null;
Token this_ID_2=null;
enterRule();
try {
// InternalEcuCValues_Extend.g:428:2: ( (this_ID_0= RULE_ID (kw= '.' this_ID_2= RULE_ID )* ) )
// InternalEcuCValues_Extend.g:429:2: (this_ID_0= RULE_ID (kw= '.' this_ID_2= RULE_ID )* )
{
// InternalEcuCValues_Extend.g:429:2: (this_ID_0= RULE_ID (kw= '.' this_ID_2= RULE_ID )* )
// InternalEcuCValues_Extend.g:430:3: this_ID_0= RULE_ID (kw= '.' this_ID_2= RULE_ID )*
{
this_ID_0=(Token)match(input,RULE_ID,FOLLOW_9);
current.merge(this_ID_0);
newLeafNode(this_ID_0, grammarAccess.getQualifiedNameAccess().getIDTerminalRuleCall_0());
// InternalEcuCValues_Extend.g:437:3: (kw= '.' this_ID_2= RULE_ID )*
loop4:
do {
int alt4=2;
int LA4_0 = input.LA(1);
if ( (LA4_0==15) ) {
alt4=1;
}
switch (alt4) {
case 1 :
// InternalEcuCValues_Extend.g:438:4: kw= '.' this_ID_2= RULE_ID
{
kw=(Token)match(input,15,FOLLOW_7);
current.merge(kw);
newLeafNode(kw, grammarAccess.getQualifiedNameAccess().getFullStopKeyword_1_0());
this_ID_2=(Token)match(input,RULE_ID,FOLLOW_9);
current.merge(this_ID_2);
newLeafNode(this_ID_2, grammarAccess.getQualifiedNameAccess().getIDTerminalRuleCall_1_1());
}
break;
default :
break loop4;
}
} while (true);
}
}
leaveRule();
}
catch (RecognitionException re) {
recover(input,re);
appendSkippedTokens();
}
finally {
}
return current;
}
// $ANTLR end "ruleQualifiedName"
in line: this_ID_0=(Token)match(input,RULE_ID,FOLLOW_9);
Is my problem in my Code or is it in my grammar? I would prefer to fix it in the grammar as there is less room for error here..
|
|
|
Re: XTEXT Scoping Issue [message #1853610 is a reply to message #1853609] |
Mon, 11 July 2022 07:51 |
|
where do you have canTpdsConfig defined
your snippet shows only the use, not the define
// define it
CanTpdsConfig
// use it
ForEach /CanTpdsConfig/CanTpChannel/CanTpTxNSdu/
i also dont understand why you always switch between parsing problems and scoping problems.
which one are we looking at now
also again
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
and the ID conflict
and the lexer is context free
so you have to either drop TAG_NO_DOT and use ID everywhere
or dont use ID at all
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
|
|
|
Re: XTEXT Scoping Issue [message #1853616 is a reply to message #1853610] |
Mon, 11 July 2022 13:45 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
Hi Christian, thank you for your patience with me.
>where do you have canTpdsConfig defined
>your snippet shows only the use, not the define
I do not want it to be defined. My goal is for my my getscope implementation to fetch me a list of entries for my context menu for ctrl+space. This I have already successfully implemented. My Problem is that the result that is fetched is not recognized as valid by the Xtext parser. The Canditates that I provide in my IScope shall not be defined previously!
I have replaced ID with TAG_NO_DOT everywhere.
grammar org.xtext.EcuCValues_Extend with org.eclipse.xtext.common.Terminals
generate ecuCValues_Extend "http://www.xtext.org/EcuCValues_Extend"
Model:
(tagnodots+=TAG_NO_DOT_FUNC)*
(lines+=Line)*
;
Line:
(rule = Rule)
;
Rule:
("ForEach" anchor=AnchorValue);
AnchorValue:
(ARClass = TAG_NO_DOT ".class") | (arpath=AbsoluteARPathContainer);
AbsoluteARPathContainer:
"/" path = ARPathContainer_With_Relative
;
ARPathContainer_With_Relative:
name=(ARPathElement);
ARPathElement:
name=[TAG_NO_DOT_FUNC|QualifiedName] "/"
;
TAG_NO_DOT_FUNC:
name = TAG_NO_DOT
;
QualifiedName:
TAG_NO_DOT('.'TAG_NO_DOT)*
;
enum RELATIVE_MOVEMENT:
ONEBACK=".." | HERE=".";
terminal TAG_NO_DOT:
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')+
;
This doesn't change the Error I am getting from the Editor:
Couldn't resolve reference to TAG_NO_DOT_FUNC 'cdsanTpdsConfig'.
How can I tell my grammar to accept the Strings that my IScope fetches?
[Updated on: Mon, 11 July 2022 13:49] Report message to a moderator
|
|
|
|
|
|
|
Re: XTEXT Scoping Issue [message #1853645 is a reply to message #1853640] |
Tue, 12 July 2022 09:47 |
Marc Kaiser Messages: 16 Registered: July 2022 |
Junior Member |
|
|
>then you need to load a reference into autosar resources into scoping
did you mean that I need to load the AUTOSAR resources into my scoping? I did load the AUTOSAR objects into my IScope. I created a wrapper class Scope_Object for loading the AR Objects into my IScope. I looks like this:
/*
* Copyright (c) Robert Bosch GmbH. All rights reserved.
*/
package org.xtext.scoping;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
/**
* @author AMK2ABT
*/
public class Scope_Object implements EObject, IEObjectDescription {
public QualifiedName QualifiedName;
public Object obj;
public Scope_Object(final String name, final EObject eo) {
setName(name);
setObject(eo);
}
/**
* {@inheritDoc}
*/
@Override
public EList<Adapter> eAdapters() {
EObject eo = (EObject) this.obj;
return eo.eAdapters();
}
/**
* {@inheritDoc}
*/
@Override
public boolean eDeliver() {
EObject eo = (EObject) this.obj;
return eo.eDeliver();
}
/**
* {@inheritDoc}
*/
@Override
public void eSetDeliver(final boolean deliver) {
EObject eo = (EObject) this.obj;
eo.eSetDeliver(deliver);
}
/**
* {@inheritDoc}
*/
@Override
public void eNotify(final Notification notification) {
EObject eo = (EObject) this.obj;
eo.eNotify(notification);
}
public void setName(final String name) {
this.QualifiedName = org.eclipse.xtext.naming.QualifiedName.create(name);
return;
}
/**
* {@inheritDoc}
*/
public void setQualifiedName(final String name) {
this.QualifiedName = org.eclipse.xtext.naming.QualifiedName.create(name);
return;
}
public void setObject(final EObject eo) {
this.obj = eo;
}
public Object getObject() {
return this.obj;
}
/**
* {@inheritDoc}
*/
@Override
public QualifiedName getName() {
return this.QualifiedName;
}
/**
* {@inheritDoc}
*/
@Override
public QualifiedName getQualifiedName() {
return this.QualifiedName;
}
/**
* {@inheritDoc}
*/
@Override
public EObject getEObjectOrProxy() {
return (EObject) this.obj;
}
/**
* {@inheritDoc}
*/
@Override
public URI getEObjectURI() {
EObject eo = (EObject) this.obj;
return EcoreUtil.getURI(eo);
}
/**
* {@inheritDoc}
*/
@Override
public EClass getEClass() {
EObject eo = (EObject) this.obj;
EClass ec = eo.eClass();
return ec;
}
/**
* {@inheritDoc}
*/
@Override
public String getUserData(final String key) {
String str = "";
for (String string : this.QualifiedName.getSegments()) {
str += string;
}
return str;
}
/**
* {@inheritDoc}
*/
@Override
public String[] getUserDataKeys() {
String[] str_arr = (String[]) this.QualifiedName.getSegments().toArray();
return str_arr;
}
/**
* {@inheritDoc}
*/
@Override
public EClass eClass() {
EObject eo = (EObject) this.obj;
EClass ec = eo.eClass();
return ec;
}
/**
* {@inheritDoc}
*/
@Override
public Resource eResource() {
EObject eo = (EObject) this.obj;
Resource er = eo.eResource();
return er;
}
/**
* {@inheritDoc}
*/
@Override
public EObject eContainer() {
EObject eo = (EObject) this.obj;
EObject ec = eo.eContainer();
return ec;
}
/**
* {@inheritDoc}
*/
@Override
public EStructuralFeature eContainingFeature() {
EObject eo = (EObject) this.obj;
EStructuralFeature esf = eo.eContainingFeature();
return esf;
}
/**
* {@inheritDoc}
*/
@Override
public EReference eContainmentFeature() {
EObject eo = (EObject) this.obj;
EReference er = eo.eContainmentFeature();
return er;
}
/**
* {@inheritDoc}
*/
@Override
public EList<EObject> eContents() {
EObject eo = (EObject) this.obj;
EList<EObject> eo_lst = eo.eContents();
return eo_lst;
}
/**
* {@inheritDoc}
*/
@Override
public TreeIterator<EObject> eAllContents() {
EObject eo = (EObject) this.obj;
return null;
}
/**
* {@inheritDoc}
*/
@Override
public boolean eIsProxy() {
EObject eo = (EObject) this.obj;
return eo.eIsProxy();
}
/**
* {@inheritDoc}
*/
@Override
public EList<EObject> eCrossReferences() {
EObject eo = (EObject) this.obj;
return eo.eCrossReferences();
}
/**
* {@inheritDoc}
*/
@Override
public Object eGet(final EStructuralFeature feature) {
EObject eo = (EObject) this.obj;
return eo.eGet(feature);
}
/**
* {@inheritDoc}
*/
@Override
public Object eGet(final EStructuralFeature feature, final boolean resolve) {
EObject eo = (EObject) this.obj;
return eo.eGet(feature, resolve);
}
/**
* {@inheritDoc}
*/
@Override
public void eSet(final EStructuralFeature feature, final Object newValue) {
EObject eo = (EObject) this.obj;
eo.eSet(feature, newValue);
return;
}
/**
* {@inheritDoc}
*/
@Override
public boolean eIsSet(final EStructuralFeature feature) {
EObject eo = (EObject) this.obj;
boolean eIsSet = eo.eIsSet(feature);
return eIsSet;
}
/**
* {@inheritDoc}
*/
@Override
public void eUnset(final EStructuralFeature feature) {
EObject eo = (EObject) this.obj;
eo.eUnset(feature);
}
/**
* {@inheritDoc}
*/
@Override
public Object eInvoke(final EOperation operation, final EList<?> arguments) throws InvocationTargetException {
EObject eo = (EObject) this.obj;
return eo.eInvoke(operation, arguments);
}
}
Then I have written a custom Scope Provider that extends the AbstractDeclarativeScopeProvider:
/*
* generated by Xtext 2.20.0
*/
package org.xtext.scoping;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.xtext.ecuCValues_Extend.ARPathContainer_With_Relative;
import org.xtext.ecuCValues_Extend.ARPathElement;
import org.xtext.ecuCValues_Extend.AbsoluteARPathContainer;
import com.bosch.bct.javaaction.modelaccess.artop.IASWModel;
import autosar40.ecucdescription.EcucModuleConfigurationValues;
/**
* This class contains custom scoping description. See
* https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping on how and when to use it.
*/
public class EcuCValues_ExtendScopeProvider extends AbstractDeclarativeScopeProvider {
@Override
public IScope getScope(final EObject context, final EReference reference) {
EcuCValues_ExtendIndex index = new EcuCValues_ExtendIndex();
List<ARPathElement> candidates = new ArrayList<>();
String projectName = null;
// Get the project name from the EObject
projectName = context.eContainer().eResource().getURI().segment(1);
List<Scope_Object> scope_obj_lst = new BasicEList<>();
IScope scopeFor = null;
// Load the Artop project context and if needed the central elements from CEL
if (projectName != null) {
IASWModel artopModelSingleton = ArtopModelSingleton.getArtopModelSingleton(projectName);
if (context instanceof AbsoluteARPathContainer) {
AbsoluteARPathContainer arpc = (AbsoluteARPathContainer) context;
EObject eContainer = context.eContainer();
ARPathContainer_With_Relative path = arpc.getPath();
// IResourceDescription resourceDescription_1 = index.getResourceDescription(arpc);
// Iterable<IEObjectDescription> exportedEObjectDescriptions_1 = index.getExportedEObjectDescriptions(arpc);
if (path != null) {
ARPathElement full_path = path.getName();
}
List<EcucModuleConfigurationValues> ecuCValueModules =
artopModelSingleton.getElements(EcucModuleConfigurationValues.class);
for (EcucModuleConfigurationValues values : ecuCValueModules) {
Scope_Object scope_obj = new Scope_Object(values.getDefinition().getShortName(), values);
scope_obj_lst.add(scope_obj);
}
EObject rootElement = EcoreUtil.getRootContainer(context);
DefaultDeclarativeQualifiedNameProvider qnp = new Scoping_Object_QualifiedName_Provider();
scopeFor = Scopes.scopeFor(scope_obj_lst, qnp, IScope.NULLSCOPE);
}
if (context instanceof ARPathElement) {
ARPathElement arpe = (ARPathElement) context;
List<EcucModuleConfigurationValues> ecuCValueModules =
artopModelSingleton.getElements(EcucModuleConfigurationValues.class);
for (EcucModuleConfigurationValues values : ecuCValueModules) {
Scope_Object scope_obj = new Scope_Object(values.getDefinition().getShortName(), values);
scope_obj_lst.add(scope_obj);
}
EObject rootElement = EcoreUtil.getRootContainer(context);
DefaultDeclarativeQualifiedNameProvider qnp = new Scoping_Object_QualifiedName_Provider();
scopeFor = Scopes.scopeFor(scope_obj_lst, qnp, IScope.NULLSCOPE);
}
else {
List<EcucModuleConfigurationValues> ecuCValueModules =
artopModelSingleton.getElements(EcucModuleConfigurationValues.class);
List<EcucModuleConfigurationValues> ecuCValueModules2 =
artopModelSingleton.getElements(EcucModuleConfigurationValues.class);
for (EcucModuleConfigurationValues values : ecuCValueModules) {
Scope_Object scope_obj = new Scope_Object(values.getDefinition().getShortName(), values);
scope_obj_lst.add(scope_obj);
}
DefaultDeclarativeQualifiedNameProvider qnp = new Scoping_Object_QualifiedName_Provider();
scopeFor = Scopes.scopeFor(scope_obj_lst, qnp, IScope.NULLSCOPE);
}
}
return scopeFor;
}
}
This getScope works in the sense that it is executed and that it is providing me with my context menu entries.
> did you debug DefaultLinkingServices why scoping fails?
I did not but will seek to do so now.
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.24348 seconds