我想创建以下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
内使用一次的修饰符?
答案 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*
'}'
;