Xtext语法变量定义/引用

时间:2015-07-06 08:05:07

标签: java grammar xtext ebnf

[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

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

这里出了什么问题?

1 个答案:

答案 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.Integerjava.lang.Double的超级类型,...

这里的问题是 type 这个词本身含糊不清。该值的类型将为intIntegerLiteral extends TypedLiteral extends VariableValue),但AST节点的类型为IntegerLiteralVariableReference

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

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

相关问题