xtext - 无法解析对的引用
xtext - Couldn't resolve reference to
我有以下语法:
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);
但它抛出错误:
PrVarName : (Varname|Progname);
所以我修改了语法如下:
PrVarName : (v=Varname|Progname);
我更新了 Scope provider 如下:
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);
}
}
}
一旦构建了语法并且我 运行 下面的测试用例,它就会在 MOVE 语句中抛出错误 "Couldn't resolve reference to PrVarName 'test1'."
Hello PROGRAM test;!
1 test1;
2 test2;
3 test3;
COPY TO test2;
MOVE TO test1;
看来我不能在两个不同的交叉引用中使用 Varname。但是有一个非常合理的需要。我该如何实现?
提前致谢。
PrVarName : p=(Progname|Varname);
不好,因为它更改了类型层次结构。 Progname 和 Varname 不再是 PrVarName 的子类型。通过还原更改并引入通用的命名超类型,您可以解决此问题
Model:
prog+=Program*;
Program:
g=Greeting de+=DataEntry* s+=Statement*;
Greeting:
'Hello' t=ProgPara '!';
ProgPara:
'PROGRAM' pname=Progname ';';
DataEntry:
a=INT (v=Varname | in=Indexname) ';';
Statement:
(c=CopyStmt | m=MoveStmt) ';';
CopyStmt:
'COPY' 'TO' qname=[IndexVarname|ID];
MoveStmt:
'MOVE' 'TO' p=[PrVarName|ID];
PrVarName:
Progname | Varname;
IndexVarname:
(Indexname | Varname);
Named:Progname|Indexname|Varname;
Progname:
{Progname} name=ID;
Indexname:
{Indexname}'(' name=ID ')';
Varname:
{Varame}name=ID;
我有以下语法:
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);
但它抛出错误:
PrVarName : (Varname|Progname);
所以我修改了语法如下:
PrVarName : (v=Varname|Progname);
我更新了 Scope provider 如下:
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);
}
}
}
一旦构建了语法并且我 运行 下面的测试用例,它就会在 MOVE 语句中抛出错误 "Couldn't resolve reference to PrVarName 'test1'."
Hello PROGRAM test;!
1 test1;
2 test2;
3 test3;
COPY TO test2;
MOVE TO test1;
看来我不能在两个不同的交叉引用中使用 Varname。但是有一个非常合理的需要。我该如何实现?
提前致谢。
PrVarName : p=(Progname|Varname);
不好,因为它更改了类型层次结构。 Progname 和 Varname 不再是 PrVarName 的子类型。通过还原更改并引入通用的命名超类型,您可以解决此问题
Model:
prog+=Program*;
Program:
g=Greeting de+=DataEntry* s+=Statement*;
Greeting:
'Hello' t=ProgPara '!';
ProgPara:
'PROGRAM' pname=Progname ';';
DataEntry:
a=INT (v=Varname | in=Indexname) ';';
Statement:
(c=CopyStmt | m=MoveStmt) ';';
CopyStmt:
'COPY' 'TO' qname=[IndexVarname|ID];
MoveStmt:
'MOVE' 'TO' p=[PrVarName|ID];
PrVarName:
Progname | Varname;
IndexVarname:
(Indexname | Varname);
Named:Progname|Indexname|Varname;
Progname:
{Progname} name=ID;
Indexname:
{Indexname}'(' name=ID ')';
Varname:
{Varame}name=ID;