带有此关键字的 Xtext 交叉引用

Xtext cross reference with this keyword

我目前正在借助 op Xtext 制作新的 DSL。我希望能够在我的语法中定义规则,其中可以操纵某些值并使用 this 引用当前对象。但是,我无法获得正确的语法使其工作。

我从 Xtext Expressions example 中提取了一些代码并对其进行了修改,以便能够对卡片值进行交叉引用。如何使用 this 关键字?我从其他一些 SO 问题中了解到我可以为此使用我自己的范围提供程序,但不知道从哪里开始。

查看一些代码:

// MyDSL.xtext

Game returns Game:
    'Game'
    name=STRING
    ...
    ('Cardpropertytypes' '{' cardpropertytypes+=CardPropertyType ( "," cardpropertytypes+=CardPropertyType)* '}' )?
    cards += Card*
;

Card returns Card:
    'Card'
    name=ID
    '{'
        'type' type=[CardType]
        ('cost' '{' cost+=Cost ( "," cost+=Cost)* '}' )?
        ('properties' '{' properties+=CardProperty ( "," properties+=CardProperty)* '}' )?
        ('rules' '{' rules+=CardRule ( "," rules+=CardRule)* '}' )?
        ('actions' '{' actions+=CardAction ( "," actions+=CardAction)* '}' )?
    '}';

CardRule returns CardRule:
    {CardRule}
    '{'
        ('description' description=STRING)?
        ('requirements' requirements=Addition)?
        ('action' action=Addition)?
        ('duration' duration=Duration)?
    '}';

CardProperty returns CardProperty:
  type=[CardPropertyType] (':' value=INT)?;

Addition returns Expression:
  Multiplication ({Addition.left=current} '+' right=Multiplication)*;

Multiplication returns Expression:
  Primary ({Multiplication.left=current} '*' right=Primary)*;

Primary returns Expression:
  Literal |
  '(' Addition ')';

Literal returns Expression: 
    {Expression}
    QualifiedName |
    NumberLiteral;

QualifiedName:
    ID ('.' ID)*;

NumberLiteral:
  value=INT;

// Card.mydsl

Cardpropertytypes {
    Toughness,
    Power,
    Flying,
    Indestructible
}
Card AdantoVanguard {
    ...
    properties {
        Toughness: 1,
        Power: 1,
        Flying
    }
    rules {
        {
            //action this.properties.Toughness + 2
            action ????
        }
    }
}

澄清: 如果我有一个 Card 模型,它具有上面代码示例中的属性,我希望能够在规则部分说:

this.properties.propertyName + 2

我怎样才能做到这一点?

在 xtext 中交叉引用看起来像

ref=[SomeType]

的缩写
ref=[SomeType|ID]

这意味着 ID 将被解析为引用 SomeType 因此,将 ID 替换为另一条规则,例如

ref=[SomeType|IDORTHIS]
...
IDORTHIS: ID | "this";

你可以实现解析端

对于范围方面,您需要实施范围提供程序

范围提供商内部

  • 覆盖 getScope
  • 使用上下文和引用参数来确定范围内的引用
  • 使用上下文收集要放入范围的元素
  • 创建一个新的范围,例如使用 Scopesclass 中的方法或手动实例化 SimpleScope / EObjectDescription.create 或 .....(您的要求对此非常模糊)