XText语法变量定义/引用
[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
为什么同一错误的第一行和最后一行彼此不一致?
这里出了什么问题?
解决方案
您尝试引用的是整型文字,而不是任何其他整型变量。实施某事。如
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];
如您所见,它从定义变量的a规则开始。该变量有一个name属性,这对于后面的参考实现非常重要。实际值分配是可选的(因为我会这样做!)在这一点上,重要的是抽象规则VariableValue
,它将对文字(也称为.常量值)或对任何其他变量的引用。
如果要引用任何预定义变量,您将使用其他变量名称,但不是其值。因此,我们还需要VariableReference
,它定义我们通过(限定)名称(在管道操作符|
之后)引用任何其他变量(在管道操作符之前)。
为确保类型安全,您必须实现yourdsl.validation.YourDslValidator
类以检查文本是否与类型兼容,以及引用的变量的类型是否与类型兼容。
编辑:我稍微优化了语法。第一个版本有点不清楚。
回答您的其他问题:
变量值的返回类型是什么?
VariableValue
本身是所有可能值的公共(但抽象)返回类型。它类似于java.lang.Number
,java.lang.Integer
、java.lang.Double
、...
这里的问题是单词type本身在这里是不明确的。值的类型将是int
(IntegerLiteral extends TypedLiteral extends VariableValue
),但AST节点的类型是IntegerLiteral
或VariableReference
。
VariableReference
的值类型,必须查看引用的VariableDeclaration
(((VariableReference)vd1.getValue()).getRef().getValue()
)的value
属性。永远不会有EString
值类型!
若要为VariableDeclaration.value
属性设置值,您需要IntegerLiteral
(最显式的TypeWrital)或VariableReference
。
相关文章