如何访问更高规则的方法?

How to access the methods for a higher rule?

在编写验证规则时遇到了一个问题,我需要语法规则中的一些内容,该规则在层次上高于我传递给 validationMethod 的规则。
我知道我可以使用 .eContainer 引用 "higher" 规则,但我不知道如何访问我想要的值。

例如我有以下语法片段:

rule1:
  name=ID content=rule2
;

rule2:
  <<whatever content>>
;

如果我有一个带参数 rule1 的普通 validationMethod,那么我可以通过 .name 访问名称,但是当我将 rule2 作为参数,然后通过 .eConatiner 引用规则时,.name 方法不存在。

你好 Krzmbrzl

EObject 是所有 AST 节点 classes 的根 class。它来自 Xtext 用来生成 AST 实现的 EMF Ecore 框架。因此,EObject class 包含许多树结构特征,例如遍历树。 EObject.eContainer() 方法 returns 一个 EObject 类型的元素,它实际上是实际返回对象类型的超类型。要访问下一个更高元素的方法,您必须像这样转换 eContainers 方法结果:

@Check
public void check(rule2 r2) {
    EObject o = r2.eContainer();
    rule1 r1 = (rule1) o;
    String r1Name = r1.getName();
}

如果父对象的类型不明确,您应该使用instanceof表达式测试实际类型是否符合预期:

@Check
public void check(rule2 r2) {
    EObject o = r2.eContainer();
    if (o instanceof rule1) {
        rule1 r1 = (rule1) o;
        String r1Name = r1.getName();
    }
}

Xtend 提供与 Java 相同的 instanceof 表达式。但是如果确定要检查的对象可以有那么几种类型,你可以使用Xtends非常强大的switch表达式。它支持所谓的类型保护。您可以切换任何对象,而不是 case value: 守卫只需编写一个具体类型:

switch (anyAbstractTypeObject) {
    ConcreteSubtypeA: {...}
    ConcreteSubtypeB: {...}
}

这是 Xtend 中优雅的 shorthand if-instanceof-eleseif-...。