Xtext 语法变量 definition/reference

Xtext grammar variable definition/reference

一个[any type]Realisation语法规则初始化应该是一个值或对预定义变量的引用。 对于整数,它看起来与您从 java:

中了解到的相似
public int i = 3;

为什么下面的语法会抛出异常?

Integer returns ecore::ELong:
  (Plus|Minus)? INT;

IntegerRealisation:
  {Integer} Integer | 
  ref=[Integer];

异常:

Caused by: java.io.IOException: Generated EMF Model incomplete: The context 'IntegerRealisation' is not valid for type 'Integer'
Recommended contexts for type 'Integer': 
Other valid contexts for type 'Integer': .... The context 'IntegerRealisation' is valid for types: Integer, IntegerRealisation

为什么同一个错误的第一行和最后一行不一致?

这里出了什么问题?

您尝试引用整数文字而不是任何其他整数类型的变量。实施s.th。喜欢

public int i = 5; // 5 is a value
public int j = i; // i reference to a predefined variable

你的语法定义应该是这样的

VariableDeclaration:
    modifiers+=Modifier* type=Type name=ID ('=' value=VariableValue)? ';';

VariableValue:
    TypedLiteral | VariableReference;

TypedLiteral:
    IntegerLiteral | ...;

IntegerLiteral:
    value=INTVAL;

terminal INTVAL returns ecore::ELong:
    (Plus|Minus)? INT;

VariableReference:
    ref=[VariableDeclaration|QualifiedName];

如您所见,它以定义变量的规则开头。这个变量有一个 name 属性,这对后面的参考实现非常重要。实际的值分配是可选的(因为我会这样做!)在这一点上重要的是 abstract 规则 VariableValue 它将模拟一个文字(又名。常量值) 或对任何其他变量的引用。

如果您想引用任何预定义变量,您将使用其他变量名称,但不是它的值。由于这个原因,我们还需要 VariableReference 来定义我们通过(限定的)名称(在管道运算符 | 之后)引用任何其他变量(在管道运算符前面)。

为了确保类型安全,您必须实现 yourdsl.validation.YourDslValidator class 来检查文字是否与类型兼容以及引用变量的类型是否与类型兼容。

编辑:我稍微优化了语法。第一个版本有点不清楚。

回答您的其他问题:

What is the return type of VariableValue?

VariableValue 本身是所有可能值的通用(但抽象)return 类型。就像 java.lang.Numberjava.lang.Integerjava.lang.Double、...

的超类型

这里的问题是type这个词本身在这里是有歧义的。值的 type 将为 int (IntegerLiteral extends TypedLiteral extends VariableValue),但 AST 节点的类型为 IntegerLiteralVariableReference

要确定 VariableReference 的值类型,您必须查看引用的 VariableDeclaration (((VariableReference)vd1.getValue()).getRef().getValue()) 的 value 属性。永远不会有 EString 值类型!

要为 VariableDeclaration.value 属性设置值,您需要 IntegerLiteral(最明确的 TypedLiteral)或 VariableReference.