我有语法
Model:
vars+=Vars*
funcs+=Funcs*;
Name:
name=ID;
VarName:
Name;
FuncName:
Name;
Funcs:
'func' left=FuncName (bracket?='(' ')')? '=' right=[Name]';';
Vars:
'var' VarName ';';
Func
规则的右手大小可以是VarName
或FuncName
类型,具体取决于左侧大小的括号。
我必须修改xtext语法或进行一种验证/范围设计吗?
更新1
范围功能:
override getScope(EObject context, EReference reference) {
if (context instanceof Funcs) {
val func = context as Funcs
if (reference == MultiNameDslPackage.Literals.FUNCS__RIGHT) {
if (func.bracket) {
val rootElement = EcoreUtil2.getRootContainer(context)
val candidates = EcoreUtil2.getAllContentsOfType(rootElement, VarName)
return Scopes.scopeFor(candidates)
} else {
val rootElement = EcoreUtil2.getRootContainer(context)
val candidates = EcoreUtil2.getAllContentsOfType(rootElement, FuncName)
return Scopes.scopeFor(candidates)
}
}
return super.getScope(context, reference);
}
}
左手大小与编辑器中括号的存在无关。
更新2
使用验证
@Check
def checkFuncContext(Funcs func) {
if (func.bracket) {
if (!(func.right instanceof VarName)) {
warning("Right hand size must be of Var type",
MultiNameDslPackage.Literals.FUNCS__RIGHT
)
}
} else {
if (!(func.right instanceof FuncName)) {
warning("Right hand size must be of Function type",
MultiNameDslPackage.Literals.FUNCS__RIGHT
)
}
}
}
不执行警告声明。声明func.right instanceof FuncName)
的行为不符合预期。
如何测试正确的实例?
更新3
使用修改后的语法
VarName:
name=ID;
FuncName:
name=ID;
Funcs:
'func' left=FuncName (bracket?='(' ')')? '=' (right=[FuncName] | r1=[VarName]) ';';
无法编译:{{1}}
答案 0 :(得分:1)
您需要更改语法以获取Name,FuncName和VarName的继承顺序(两者的名称超类型)
使用解析器片段
fragment Name: name=ID;
或使用
Name:VarName|FuncName;
VarName: name=ID;
FuncName:name=ID;