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.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
.
一个[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.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
.