何时使用交叉引用和何时使用包含引用?

时间:2014-06-26 07:52:38

标签: dsl xtext emf cross-reference

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

 '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的实例),这是一个包含引用,虽然对于非包含引用,引用的对象存储在其他地方, 例如,在同一资源的另一个对象中,甚至在不同的资源中。 并且重点是交叉引用被实现为非包含引用。 我需要知道何时应该使用交叉引用以及何时使用包含引用?

2 个答案:

答案 0 :(得分:1)

据我所知,区别如下:
如果您想引用规则的内容,那么包含引用是指每次使用包含引用时,它只是懒于重新定义规则的内容。
交叉引用的行为略有不同:如果您使用交叉引用,则解析器需要用户输入交叉引用所引用的规则内容,然后才能引用已引用的内容。

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

我希望我已经很好地说明了它,所以你现在知道这些引用类型的区别和含义。

问候Krzmbrzl

答案 1 :(得分:0)

Your grammar describes the AST of your language. Therefore, a meta model is derived from your grammar. To describe references between your AST elements you can use containmend references and cross references. A containment reference is used if you want to describe a parent-child relation where the child object is "created" / declared during the parent object is created. A cross reference is used if the parent object points to a child object which is created / declared in an other parent object. To "draw a picture": A containment reference is a top -> bottom reference and a cross reference is a left -> right reference.

For example assume you have a field (private int field = 42;) or method (public void foo() {...}) declaration of a Java class. This declaration is modeled with a containment reference, because a Java class contains field and method declarations. On the other you have a statement field++; within the method body of foo(). There you use the former declared field foo and it is modeled as a cross reference.

In general I would say: Any declaration is modeled as a containment reference and any usage of an already declared whatever is modeled as a cross reference.