I have the following grammar:
Model: prog+=Program*;
Program: g=Greeting de+=DataEntry* s+=Statement*;
Greeting: 'Hello' t=ProgPara '!';
ProgPara: 'PROGRAM' pname=Progname ';';
Progname : name=ID;
DataEntry: a=INT v=Varname ';';
Varname : name = ID;
Statement: (c=CopyStmt|m=MoveStmt) ';';
CopyStmt: 'COPY' 'TO' qname=[IndexVarname|ID] ;
IndexVarname : (Indexname|Varname);
Indexname : '(' name = ID ')';
MoveStmt: 'MOVE' 'TO' p=[PrVarName|ID];
PrVarName : (Varname|Progname);
But it throws error for:
PrVarName : (Varname|Progname);
So i modified the grammar to have as below:
PrVarName : (v=Varname|Progname);
I updated the Scope provider as below:
override getScope(EObject context, EReference reference) {
if (context instanceof CopyStmt) {
if (reference.featureID == TestDslPackage.COPY_STMT__QNAME) {
val rootElement = EcoreUtil2.getRootContainer(context);
val candidates1 = EcoreUtil2.getAllContentsOfType(rootElement, Indexname);
val candidates2 = EcoreUtil2.getAllContentsOfType(rootElement, Varname);
val candidates = candidates1 + candidates2;
return Scopes.scopeFor(candidates);
}
} else if (context instanceof MoveStmt) {
if (reference.featureID == TestDslPackage.MOVE_STMT__P) {
val rootElement = EcoreUtil2.getRootContainer(context);
val candidates1 = EcoreUtil2.getAllContentsOfType(rootElement, Progname);
val candidates2 = EcoreUtil2.getAllContentsOfType(rootElement, Varname);
val candidates = candidates1 + candidates2;
return Scopes.scopeFor(candidates);
}
}
}
Once the grammar was built and i ran the below test case, it is throwing error in the MOVE statement saying "Couldn't resolve reference to PrVarName 'test1'."
Hello PROGRAM test;!
1 test1;
2 test2;
3 test3;
COPY TO test2;
MOVE TO test1;
Looks like i cannot use Varname in two different cross references. But there is a very valid need for it. How do I achieve this?
Thanks in advance.