是否可以在xtext规则中为属性分配常量值?

时间:2017-04-14 13:10:51

标签: xtext

我有一个元模型,其中我有一个Rangeminmax整数值的类,我想定义一个xText DSL,你可以在其中定义一个像{一样的范围{1}},以及1..10?等标准默认值,代表!0..1。我查看了文档,但无法找到任何方法在xText语法中定义它。到目前为止,我对一般情况有一个规则

1..1

但是,我没有找到任何方法来定义类似

的内容

Range: min=INT '..' max=INT;

Range: '?' min=0 max=1;

我怎样才能为我的DSL实现类似的行为?

请注意,我对从语法生成元模型不感兴趣,因为DSL模型应该遵循现有的元模型。

1 个答案:

答案 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) 没有第二个参数指定您所在的节点或规则,并且您拒绝为范围引入子类(在从您继承的元模型中),这会使这一点变得容易(仅覆盖创建)