我有一个元模型,其中我有一个Range
个min
个max
整数值的类,我想定义一个xText DSL,你可以在其中定义一个像{一样的范围{1}},以及1..10
和?
等标准默认值,代表!
或0..1
。我查看了文档,但无法找到任何方法在xText语法中定义它。到目前为止,我对一般情况有一个规则
1..1
但是,我没有找到任何方法来定义类似
的内容 Range: min=INT '..' max=INT;
Range: '?' min=0 max=1;
我怎样才能为我的DSL实现类似的行为?
请注意,我对从语法生成元模型不感兴趣,因为DSL模型应该遵循现有的元模型。
答案 0 :(得分:1)
我不知道一个简单的解决方案,但您可以自定义Xtexts对象创建,例如像
Model: ranges+=AbstractRange*;
AbstractRange returns Range: ExplicitRange | ZORange | OORange;
ExplicitRange returns Range: min=INT ".." max=INT;
ZORange returns Range: {Range} max=ZEROONE;
ZEROONE returns ecore::EInt: "?";
OORange returns Range: {Range} max=ONEONE;
ONEONE returns ecore::EInt: "!";
并按照自定义
class MyDslEcoreElementFactory extends DefaultEcoreElementFactory {
@Inject extension MyDslGrammarAccess
override set(EObject object, String feature, Object value, String ruleName, INode node) throws ValueConverterException {
if (object instanceof Range) {
if (ruleName == grammar.name+"."+ZEROONERule.name) {
object.max = 1
object.min = 0
return;
} else if (ruleName == grammar.name+"."+ONEONERule.name) {
object.max = 1
object.min = 1
return;
}
}
super.set(object, feature, value, ruleName, node)
}
}
像这样绑定
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIAstFactory() {
MyDslEcoreElementFactory
}
}
遗憾的是org.eclipse.xtext.parser.IAstFactory.create(EClassifier)
没有第二个参数指定您所在的节点或规则,并且您拒绝为范围引入子类(在从您继承的元模型中),这会使这一点变得容易(仅覆盖创建)