Reputation: 2270
I want to create the following DSL
namespace x.y.z
system <NAME> {
component A { ... }
component B { ... }
coordinator component C { ... }
component D { ... }
}
All component
's have the same structure except that one and only one requires a coordinator
modifier.
By now I tried two different grammars:
System:
'system' name=ValidID '{'
(coordinatorComponent=CoordinatorComponent) &
(components+=NonCoordinatorComponent*) &
(constraints=ComponentConstraints)?
'}'
;
ComponentConstraints:
'constraints' '{}'
;
CoordinatorComponent:
'coordinator' 'component' {Component}
;
NonCoordinatorComponent:
'component' {Component};
Component:
name=ValidID '{'
features+=Feature*
'}'
;
and the same one with slight changes
CoordinatorComponent:
'coordinator' {Component}
;
NonCoordinatorComponent:
{Component};
Component:
'component' name=ValidID '{'
features+=Feature*
'}'
;
The first one results in an error rule ruleSystem failed predicate: {getUnorderedGroupHelper().canLeave(grammarAccess.getSystemAccess().getUnorderedGroup())}? in the editor when writing the DSL (not the grammar).
The second one works but still I think it is weird because it is not really using a modifier but a whole new type. Is there a better way to define Component
in general and using a modifier which MUST be used exactly once within System
?
Upvotes: 0
Views: 78
Reputation: 11868
what about using parser fragments
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*
'}'
;
Upvotes: 1