【问题标题】:when to use cross-reference and when use containment reference?何时使用交叉引用以及何时使用包含引用?
【发布时间】:2014-08-16 23:46:00
【问题描述】:

我需要实现一种特定领域的语言。我有一个面板和一些形状。

 'panel' name = ID '('  title = STRING',' bgcolor = Color',' width = INT',' height = INT ')''{'((rects += Rect)| (ellipse += Ellipse)|(arcs += Arc)|)*'}'

每个形状都有一个独特的规则和一些其他特征。例如:

RoundRect:
'roundrectangle' name = ID '{'
(fill ?= 'filled' (fillpattern?='fillpattern' fillpaint=Paint)?)?
(stroke?='stroke' str=Stroke)?
'paint' paint=Paint
'coordination' x=INT ',' y=INT
'dimention' height=INT ',' width=INT
'arc' archeight=INT ',' arcwidth=INT
'}' 

在这个 DSL 中很明显,我使用了一些参考资料。但我不知道这条规则是否正确,或者我应该在这些规则中使用交叉引用? 此规则工作正常,我收到了我期望的正确输出。但我知道当一个特性不是基本类型(字符串、整数等)时,它是 实际上是一个引用(EReference 的一个实例),这是一个包含引用,尽管对于非包含引用,被引用的对象存储在其他地方, 例如,在同一资源的另一个对象中,甚至在不同的资源中。 重点是交叉引用被实现为非包含引用。 我需要知道何时应该使用交叉引用以及何时使用包含引用?

【问题讨论】:

    标签: dsl xtext emf cross-reference


    【解决方案1】:

    据我所知,区别如下:
    包含引用是如果您想引用规则的内容,那么每次使用包含引用时重新定义规则的内容只是懒惰。
    交叉引用的行为有点不同:如果您使用交叉引用,解析器需要用户在允许他引用已经输入的内容之前输入交叉引用引用的规则内容。

    一个例子是一个真正的编程语言:一个方法调用将是一个交叉引用,因为这个名称的方法应该已经在代码的某个地方声明了,否则它不存在。相反,普通代码将被实现为包含引用,因为它可以(例如)在类、字段或方法中使用,并且您输入的代码只需要填充一些关键字和结构的存在但是这些仅在解析器本身中定义,在使用它们之前不需要由用户自己定义。

    我希望我已经对它进行了充分的说明,以便您现在了解这些引用类型的区别和含义。

    问候 Krzmbrzl

    【讨论】:

      【解决方案2】:

      您的语法描述了您的语言的 AST。因此,元模型源自您的语法。要描述 AST 元素之间的引用,您可以使用包含修正引用和交叉引用。如果您想描述在创建父对象期间“创建”/声明子对象的父子关系,则使用包含引用。如果父对象指向在另一个父对象中创建/声明的子对象,则使用交叉引用。要“绘制图片”:包含引用是顶部 -> 底部引用,交叉引用是左侧 -> 右侧引用。

      例如,假设您有一个 Java 类的字段 (private int field = 42;) 或方法 (public void foo() {...}) 声明。此声明使用包含引用建模,因为 Java 类包含字段和方法声明。另一方面,您在foo() 的方法主体中有一个声明field++;。在那里您使用以前声明的字段 foo 并将其建模为交叉引用。

      一般来说,我会说:任何声明都被建模为包含引用,任何已声明的任何使用都被建模为交叉引用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-28
        • 2015-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-27
        • 1970-01-01
        相关资源
        最近更新 更多