【发布时间】:2021-06-21 09:12:25
【问题描述】:
大家好,
我有一个关于 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。
我想做什么,有可能吗?如果是,怎么做?
谢谢解答....
【问题讨论】:
-
什么不适用于
'element' element=[dsl1::Base|Ceiling] -
Eclipse UI 显示“规则“天花板”对于交叉引用无效,因为它不返回 EString。您必须将其包装在数据类型规则中。'
-
啊,是的,这就是“元素”的语义 element=[dsl1::Base|Ceiling] 请注意 |something 的意思是“并解析某物”
-
如果你的意思是或者你需要在基本语法中通过引入一个抽象元素来支持这一点,并让两者都从那里继承,或者你需要引用一个 EObject 并在作用域中过滤类型
-
Base Grammar 真的不在我的控制之下,所以要改变它会是一场大战。所以你对第二个选项的意思是,我必须有 ''element' element=[EObject]' 然后在范围内确定是 'dsl1::Base' 还是天花板。我可以这样做,但是在 Xtend Genreators 和 EObject 上真的很烦人,我必须写很多'if instanceof'...
标签: xtext