如何在Xtext语法中为多个元素只允许一次修饰符?

时间:2017-01-28 16:10:14

标签: dsl xtext

我想创建以下DSL

namespace x.y.z
system <NAME> {
    component A { ... }
    component B { ... }
    coordinator component C { ... }
    component D { ... }
}

所有component具有相同的结构,只有一个且只有一个需要coordinator修饰符。

到现在为止,我尝试了两种不同的语法:

System:
    'system' name=ValidID '{'
        (coordinatorComponent=CoordinatorComponent) & 
        (components+=NonCoordinatorComponent*) & 
        (constraints=ComponentConstraints)?
    '}'
;

ComponentConstraints:
    'constraints' '{}'
;

CoordinatorComponent:
    'coordinator' 'component' {Component}
;

NonCoordinatorComponent:
    'component' {Component};

Component:
    name=ValidID '{'
        features+=Feature*
    '}'
;

和稍有变化的同一个

CoordinatorComponent:
    'coordinator' {Component}
;

NonCoordinatorComponent:
    {Component};

Component:
    'component' name=ValidID '{'
        features+=Feature*
    '}'
;

第一个导致错误规则ruleSystem失败谓词:{getUnorderedGroupHelper()。canLeave(grammarAccess.getSystemAccess()。getUnorderedGroup())}?在编写DSL时编辑(不是语法)。

第二个可以工作,但我认为这很奇怪,因为它并没有真正使用修饰符而是一个全新的类型。是否有更好的方法来定义Component,并使用一个必须在System内使用一次的修饰符?

1 个答案:

答案 0 :(得分:1)

如何使用解析器片段

System:
    'system' name=ValidID '{'
        ((coordinatorComponent=CoordinatorComponent) & 
        (components+=NonCoordinatorComponent*) & 
        (constraints=ComponentConstraints)?)
    '}'
;

ComponentConstraints:
    'constraints' '{}'
;

CoordinatorComponent:
    'coordinator' 'component' Component
;

NonCoordinatorComponent:
    'component' Component;

fragment Component:
    name=ValidID '{'
        features+=Feature*
    '}'
;