Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Serialization and concrete syntax validation
Serialization and concrete syntax validation [message #1738006] Thu, 14 July 2016 22:02 Go to next message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 392
Registered: March 2011
Senior Member
Hello. I have a problem with concrete syntax validation during serialization.

I have a grammar based on an existing EMF model which has the following meta-classes:

* AbstractAction
* ActionCode with superType = AbstractAction
* EntryAction with superType = ActionCode
* ExitAction with superType = ActionCode
* TransitionAction with superType = ActionCode
* GuardAction with superType = ActionCode
* ActionReference with superType = AbstractAction

My grammar has the following rules:



AbstractEntryAction returns AbstractAction:
    EntryAction | ActionReference
;

AbstractExitAction returns AbstractAction:
    ExitAction | ActionReference
;

AbstractGuardAction returns AbstractAction:
	GuardAction | ActionReference
;

AbstractTransitionAction returns AbstractAction:
	TransitionAction | ActionReference
;

ActionReference returns ActionReference:
    {ActionReference}
    'actionref' (target=[AbstractAction|QualifiedName])?
;

EntryAction returns EntryAction:
    {EntryAction}
    source=EString
;

ExitAction returns ExitAction:
    {ExitAction}
    source=EString
;

GuardAction returns GuardAction:
	{GuardAction}
	source=EString	
;

TransitionAction returns TransitionAction:
    {TransitionAction}
    source=EString
;

OperationCode returns ActionCode:
	{ActionCode}
	source=EString
;


which are called from other rules.

Now I have a model which was not created by parsing but I'm trying to serialize with this grammar, but serialization fails with the errors below:

org.eclipse.e4.core.di.InjectionException: org.eclipse.xtext.validation.IConcreteSyntaxValidator$InvalidConcreteSyntaxException: These errors need to be fixed before the model can be serialized.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionCode is needed instead of EntryAction for serialization with rule OperationCode.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionReference or ExitAction is needed instead of EntryAction for serialization with rule AbstractExitAction.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionReference or TransitionAction is needed instead of EntryAction for serialization with rule AbstractTransitionAction.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type GuardAction or ActionReference is needed instead of EntryAction for serialization with rule AbstractGuardAction.


I stepped through the validator, and found that in ConcreteSyntaxValidator.validateObject, one of the first things is to obtain the constraints for the relevant EClass (calling constraintProvider.getConstraints(obj.eClass())), and this method does the following:

for (ParserRule r : getValidRules()) {
  if (((EClass) r.getType().getClassifier()).isSuperTypeOf(cls)) {
    ISyntaxConstraint e = getConstraint(r);
    if (e != null)
      eles.add(e);
    else {
      eles.clear();
      break;
    }
  }
}
type2Elements.put(cls, eles);


So it will associate a given EClass cls, to the list of *all* rules whose type is a superType of cls.

In my case, this means that for an EObject of type EntryAction, that table will contain all rules whose type is a superType of EntryAction, including, for example, the 'OperationCode' rule. Then, when this rule is being validated (#validateRule) it fails, because
'collectUnfulfilledSemanticElements(obj.eClass(), rule);' returns more than one element, and this is because the ISyntaxConstraint for that rule has 'ActionCode' as the semantic type and it does not include 'EntryAction' as a semantic type.

So, a couple of questions:

1) why does 'getConstraints' add the constraints for *all* the rules whose type is a super-type of the EClass?
2) how can this error be addressed? defining a custom IConcreteSyntaxValidator or a custom IConcreteSyntaxConstraintProvider? or is there a simpler way?

Thanks
Re: Serialization and concrete syntax validation [message #1738021 is a reply to message #1738006] Fri, 15 July 2016 06:59 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13722
Registered: July 2009
Senior Member
looks like a bug to me. can you file one?

https://github.com/eclipse/xtext-core

can you share a complete minimal reproducale grammar/metamodel?

e.g. how does your state rule look like?


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/it-services/methods-and-tools/xtext
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Serialization and concrete syntax validation [message #1738096 is a reply to message #1738021] Fri, 15 July 2016 17:36 Go to previous message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 392
Registered: March 2011
Senior Member
Thanks. I'll try to create a minimalistic example and open a bug.

In the meantime, the relevant rules (in addition to the ones in the original post) are below. Note that the "Actions" are spread out through several rules, including "State", "Transition" and "Operation" (which is independent of state machines).

State returns State:
    CompositeState | SimpleState;

fragment StateCommonFragment returns State:
        DescriptionFragment
        ('entry action' entryAction=AbstractEntryAction ';')?
        ('exit action' exitAction=AbstractExitAction ';')?
        ('exit points' '{' exitPoints+=ExitPoint ("," exitPoints+=ExitPoint)* '}')?
        ('entry points' '{' entryPoints+=EntryPoint ("," entryPoints+=EntryPoint)* '}')?
    ;

SimpleState returns SimpleState:
    {SimpleState}
    'simple'? 'state'
    name=EString
    RedefinitionFragment
    ( ('{' StateCommonFragment  '}') | ';' )
;

CompositeState:
    'composite state'
    name=EString
    RedefinitionFragment
    (CompositeStateBody | ';')
;

fragment CompositeStateBody returns CompositeState:
    '{'
        StateCommonFragment
        ('initial' initial=InitialPoint ';')?
        ('history' deepHistory=DeepHistory ';')?
        ('junction points' '{' junctionPoints+=JunctionPoint ("," junctionPoints+=JunctionPoint)* '}')?
        ('choice points' '{' choicePoints+=ChoicePoint ("," choicePoints+=ChoicePoint)* '}')?
        (substates+=State)*
        (transitions+=Transition)*
    '}'
;


Transition returns Transition:
    'transition'
    (name=EString)?
    'from' sourceVertex=[Vertex|QualifiedName]
    'to' targetVertex=[Vertex|QualifiedName]
    (
        'triggers'
        (
            triggers+=Trigger
        |
            '{' triggers+=Trigger ("," triggers+=Trigger)* '}'
        )
    )?
    (guard=Guard)?
    ('action' actionChain=TransitionActionChain)?
    RedefinitionFragment
    ';'
;

TransitionAction returns TransitionAction:
    {TransitionAction}
    source=EString
;

TransitionActionChain returns ActionChain:
    {ActionChain}
    actions+=AbstractTransitionAction
;

RTPassiveClass returns RTPassiveClass:
    {RTPassiveClass}
    'class'
    name=EString
    RedefinitionFragment
    DependencyFragment
    '{'
        DescriptionFragment
        StructuredTypeCommonCoreFragment
        BehaviourFragment
        AnnotationsFragment
    '}'
;

fragment StructuredTypeCommonCoreFragment returns StructuredType:
    (attributes+=Attribute)*
    (operations+=Operation)*
;

Operation returns Operation:
    (visibility=VisibilityKind)?
    (static?='static')?
    (abstract?='abstract')?
    (query?='query')?
    'operation'
    name=EString
    ('(' (parameters+=Parameter)* ')')?
    ':' returnType=TypedMultiplicityElement
    body=OperationCode
    ';'
;

OperationCode returns ActionCode:
	{ActionCode}
	source=EString
;

Previous Topic:Complementing EMF/GMF-based Editor with Xtext
Next Topic:how to override and bind ImportUriResolver
Goto Forum:
  


Current Time: Mon Jan 25 02:20:57 GMT 2021

Powered by FUDForum. Page generated in 0.01668 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top