您尝试引用整数文字而不是任何其他整数类型变量。实施某事喜欢
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 类来检查字面量是否与类型兼容,以及被引用变量的类型是否与类型兼容。
编辑:我稍微优化了语法。第一个版本有点不清楚。
回答您的其他问题:
VariableValue的返回类型是什么?
VariableValue 本身是所有可能值的通用(但抽象)返回类型。就像java.lang.Number 是java.lang.Integer、java.lang.Double、...的超类型。
这里的问题是 type 这个词本身在这里是模棱两可的。该值的 type 将是 int (IntegerLiteral extends TypedLiteral extends VariableValue),但 AST 节点的类型是 IntegerLiteral 或 VariableReference。
要确定VariableReference 的值类型,您必须查看引用的VariableDeclaration (((VariableReference)vd1.getValue()).getRef().getValue()) 的value 属性。永远不会有EString 值类型!
要为VariableDeclaration.value 属性设置值,您需要IntegerLiteral(最显式的TypedLiteral)或VariableReference。