2017-01-28 3 views
0

Je veux créer la liste intérieure suivanteComment autoriser un modificateur une seule fois pour plusieurs éléments dans Xtext Grammar?

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

Tous component « s ont la même structure, sauf que l'un et un seul nécessite un modificateur coordinator.

Maintenant j'ai essayé deux grammaires différentes:

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

ComponentConstraints: 
    'constraints' '{}' 
; 

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

NonCoordinatorComponent: 
    'component' {Component}; 

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

et la même avec de légères modifications

CoordinatorComponent: 
    'coordinator' {Component} 
; 

NonCoordinatorComponent: 
    {Component}; 

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

Les premier résultats dans une erreur règle ruleSystem échoué prédicat: {getUnorderedGroupHelper() .canLeave (grammarAccess.getSystemAccess(). getUnorderedGroup())}? dans l'éditeur lors de l'écriture de la DSL (pas la grammaire).

La seconde fonctionne mais je pense que c'est bizarre car elle n'utilise pas vraiment un modificateur mais un tout nouveau type. Y at-il une meilleure façon de définir Component en général et en utilisant un modificateur qui DOIT être utilisé exactement une fois au sein de System?

Répondre

1

Qu'en est en utilisant des fragments d'analyseur

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* 
    '}' 
;