【问题标题】:Xtext grammar variable definition/referenceXtext 语法变量定义/引用
【发布时间】:2015-09-23 07:01:27
【问题描述】:

[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

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

这里出了什么问题?

【问题讨论】:

    标签: java grammar xtext ebnf


    【解决方案1】:

    您尝试引用整数文字而不是任何其他整数类型变量。实施某事喜欢

    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.Numberjava.lang.Integerjava.lang.Double、...的超类型。

    这里的问题是 type 这个词本身在这里是模棱两可的。该值的 type 将是 int (IntegerLiteral extends TypedLiteral extends VariableValue),但 AST 节点的类型是 IntegerLiteralVariableReference

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

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

    【讨论】:

    • VariableValue的返回类型是什么?默认为 ecore::EString。但是由于IntegerLiteral 返回一个 ELong 而VariableReference(我猜)只能是 EString 或更可能是 EReference,所以不会有共同的超类型...... EMF 类需要一个 VariableValue 但这不是一个实例!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    相关资源
    最近更新 更多