[any type]Realisation
语法规则初始化应该是对预定义变量的值或引用。
对于Integer,它看起来与你从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
为什么同一错误的第一行和最后一行彼此不一致?
这里出了什么问题?
答案 0 :(得分:0)
您尝试引用Integer文字而不是任何其他Integer类型变量。实施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];
如您所见,它从定义变量的规则开始。此变量具有名称属性,这对于稍后的参考实现非常重要。实际值分配是可选的(因为我会这样做!)此时重要的是抽象规则VariableValue
,它将模拟文字(也称为常量值)或引用任何其他变量。
如果要引用任何预定义变量,您将使用其他变量名称,但不其值。由于这个原因,我们还需要VariableReference
,它定义我们通过(限定的)名称引用任何其他变量(在管道运算符前面)(管道运算符|
)。
为了确保类型安全,您必须实现yourdsl.validation.YourDslValidator
类来检查文字是否与类型兼容以及引用变量的类型是否与类型兼容。
编辑:我稍微优化了语法。第一个版本有点不清楚。
回答您的其他问题:
VariableValue的返回类型是什么?
VariableValue
本身是所有可能值的常见(但是抽象)返回类型。它就像java.lang.Number
,是java.lang.Integer
,java.lang.Double
的超级类型,...
这里的问题是 type 这个词本身含糊不清。该值的类型将为int
(IntegerLiteral extends TypedLiteral extends VariableValue
),但AST节点的类型为IntegerLiteral
或VariableReference
。
要确定VariableReference
的值类型,您必须查看引用的value
(VariableDeclaration
)的((VariableReference)vd1.getValue()).getRef().getValue()
属性。永远不会有EString
值类型!
要为VariableDeclaration.value
属性设置值,您需要IntegerLiteral
(最明确的TypedLiteral)或VariableReference
。