来自 2 个不同 DSL 的交叉引用

问题描述

无论如何,

我有一个关于 Xtext 的有趣场景,但我没有想法,所以我想问你。

我实际上在我的项目中使用了来自两个不同 DSL 的交叉引用,但我不知道如何处理以下场景。

DSL1:

grammar com.test.DSL1 with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate DSL1 "http://test.com/DSL1"

Model:
   (elements+=AbstractElement)*;
   
   Qualifiedname:
      ID ('.' ID)*;

   QualifiednameWithWildcard:
      Qualifiedname '.*'?;  
   
   AbstractElement:
      Base;

   Base:
      'base' name=ID
      'something' '=' (something=STRING)

DSL2

grammar com.test.DSL2 with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate DSL2 "http://test.com/DSL2"

import "http://test.com/DSL1" as dsl1

Model:
   (elements+=OtherElement)*;
   
   Qualifiedname:
      ID ('.' ID)*;

   QualifiednameWithWildcard:
      Qualifiedname '.*'?;  
   
   OtherElement:
      Ceiling;

   Ceiling:
      'ceiling' name=ID
      'otherthing' '=' (otherthing=STRING)

   Plan:
      'plan' name=ID
      'element' element=[dsl1::Base|Ceiling]

如你所料

'element' element=[dsl1::Base|Ceiling]

不工作。

如果 Base 和 Ceiling 在同一个 DSL 中,我会执行以下操作,它会起作用..

AbstractBaseCeiling:
    Base | Ceiling;

Plan:
    'plan' name=ID
    'element' element=[AbstractBaseCeiling]

但是

AbstractBaseCeiling:
    dsl1::Base| Ceiling;

Plan:
    'plan' name=ID
    'element' element=[AbstractBaseCeiling]

也不起作用...

不要理解我错了,我的交叉引用设置正在运行,因为如果我执行以下操作,一切正常..

Plan:
    'plan' name=ID
    'element' element=[dsl1::Base]

但我无法找到使用另一个 DSL 中的另一个规则的方法,元素可以是“dsl1::Base”或 DSL2 Ceiling。

我想做什么,可能吗?如果是,如何?

感谢回答....

解决方法

我认为有两种方法可以解决这个问题:

  • 如果您想在 DSL1 和 DSL2 之间共享语法规则,请参阅 grammar mixins
  • 或者您想从 DSL2 中引用使用 DSL1 定义的元素,在这种情况下,您需要设置导入机制(参见例如 a tutorial here,但我确定文档中还有其他内容)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...