Commit 63b0c6fb authored by Philip Makedonski's avatar Philip Makedonski Committed by Philip Makedonski
Browse files

* grammar clean-up, reordering, refinement

parent ff2e2e11
Loading
Loading
Loading
Loading
+219 −294
Original line number Diff line number Diff line
@@ -9,10 +9,6 @@ import "http://www.etsi.org/spec/TDL/1.3.1/configurations" as extendedconfigurat

//# Foundation

//Element : Abstract

//NamedElement : Abstract

//Needs to be the first rule
Package returns tdl::Package:
    AnnotationCommentFragment
@@ -40,22 +36,38 @@ PackageableElement returns tdl::PackageableElement:
     | TestConfiguration 
     | TestDescription
    )
    //WithCommentFragment? 
//    | PredefinedAnnotationType
;

//TODO: use predefined annotation types for syntactical restrictions?
//      or regular annotation type definitions and only custom annotation references?
//PredefinedAnnotationType returns tdl::AnnotationType:
//    {tdl::AnnotationType}
//    'PAnnotationType'
//    name='PAT'
//;
//
//PredefinedAnnotation returns tdl::Annotation:
//    key=[tdl::AnnotationType|'PAT']
//;
//Element : Abstract

fragment AnnotationFragment returns tdl::Element:
    (annotation+=Annotation)*
;

fragment AnnotationCommentFragment returns tdl::Element:
    (comment+=Comment)*
    (annotation+=Annotation)*
;

fragment NameFragment returns tdl::Element:
    'Name:' name=Identifier
;

fragment WithCommentFragment returns tdl::Element:
    'with'
    BEGIN
        (comment+=Comment)+
    END
;

fragment WithNameFragment returns tdl::Element:
    'with'
    BEGIN
        NameFragment
    END
;

//NamedElement : Abstract

ElementImport returns tdl::ElementImport:
    AnnotationCommentFragment
@@ -80,16 +92,12 @@ Annotation returns tdl::Annotation:

AnnotationType returns tdl::AnnotationType:
    AnnotationCommentFragment
    //DONE: Simplify to Annotation?
    //DONE: Discuss (last remaining CamelCased.. -> add note
    'Annotation' name=Identifier
    ('extends' extension=Extension)?
;

TestObjective returns tdl::TestObjective:
    AnnotationCommentFragment
    //DONE: Simplify to Objective?
    //DONE: Discuss -> agreed
    'Objective' name=Identifier
    (BEGIN
        ('Description:' description=EString)?
@@ -130,11 +138,6 @@ DataElementMapping returns tdl::DataElementMapping:
    'in' dataResourceMapping=[tdl::DataResourceMapping|Identifier]
    'as' name=Identifier
    (BEGIN
        //DONE: separator  -> at least one
        //DONE: discuss separator - it may go both ways 
        //		- it is more like a statement, as are components in a configuration
        //			-> that in itself may need to be revised to more static/declarative expression
        //		- everything has to be with a separator
        parameterMapping+=ParameterMapping (',' parameterMapping+=ParameterMapping)*
    END)?
;
@@ -142,14 +145,17 @@ DataElementMapping returns tdl::DataElementMapping:
ParameterMapping returns tdl::ParameterMapping:
    AnnotationCommentFragment
    parameter=[tdl::Parameter|Identifier]
    //DONE: change to mapped to? / map to (to reuse keywords)
    '->' parameterURI=EString
;

//DataType: Abstract

fragment ConstraintFragment returns tdl::DataType:
    (LBrace constraint+=Constraint RBrace)* 
;

SimpleDataType returns tdl::SimpleDataType:
    AnnotationCommentFragment
    //DONE: use Simple instead? or SimpleType? -> Discuss -> keep as type, alternatively 'Primitive'
    'Type' name=Identifier
    ConstraintFragment
    ('extends' extension=Extension)?
@@ -158,21 +164,14 @@ SimpleDataType returns tdl::SimpleDataType:
//DONE: boolean data instance
SimpleDataInstance returns tdl::SimpleDataInstance:
    AnnotationCommentFragment
    //DONE: check if this can be used to ensure that the correct kind of dataType is assigned
    //		alternatively capture in scoping? or leave to constraints on meta-model level? (default)
    //		-> does not seem to work
    //(this is also relevant for collection and structured data instances..)
    //NOTE: too strong syntactic or scoping restrictions would preclude the construction of 
    //		test cases for the constraints in a textual form
    dataType=[tdl::DataType|Identifier]
    (name=Identifier | name=BOOLEANNAME) 
    //for backwards compatibility -> Predefined Booleans now True and False
    //(name=Identifier | name=BOOLEANNAME)
    name=Identifier 
;

StructuredDataType returns tdl::StructuredDataType:
    AnnotationCommentFragment
    //DONE: Different keyword otherwise ambiguity...
    //or StructuredType?
    //DONE: Discuss -> agreed
    'Structure' name=Identifier
    ConstraintFragment
    ('extends' extension+=Extension (',' extension+=Extension)*)?
@@ -184,7 +183,7 @@ Member returns tdl::Member:
    (isOptional?='optional')?
    dataType=[tdl::DataType|Identifier]
    name=Identifier
    MemberConstraintFragment
    (LBrace constraint+=Constraint RBrace)*
;

StructuredDataInstance returns tdl::StructuredDataInstance:
@@ -198,9 +197,6 @@ StructuredDataInstance returns tdl::StructuredDataInstance:
MemberAssignment returns tdl::MemberAssignment:
    AnnotationCommentFragment
    member=[tdl::Member|Identifier]
    //'=' memberSpec=StaticDataUse
    //DONE: needs a meta-model change -> document, add constraint
    //DONE: discuss potential for backward compatibility, alternatively provide dedicated syntaxes
    '=' memberSpec=DataUse
;

@@ -216,9 +212,6 @@ CollectionDataInstance returns tdl::CollectionDataInstance:
    dataType=[tdl::DataType|Identifier] 
    name=Identifier
    (unassignedMember=UnassignedMemberTreatment)?
    //'[' item+=StaticDataUse (',' item+=StaticDataUse)* ']'
    //DONE: needs a meta-model change -> document, add constraint, 
    //DONE: discuss potential for backward compatibility, alternatively provide dedicated syntaxes 
    '[' item+=DataUse (',' item+=DataUse)* ']'    
;

@@ -299,7 +292,6 @@ EnumDataType returns tdl::EnumDataType:
    AnnotationCommentFragment
    'Enumerated' name=Identifier
    BEGIN
        //DONE: without type specification? -> perhaps in the future...
        value+=SimpleDataInstance (',' value+=SimpleDataInstance)*
    END
;
@@ -309,9 +301,6 @@ EnumDataType returns tdl::EnumDataType:

DataUse returns tdl::DataUse:
    //NOTE: No name, annotations or comments
    //StaticDataUse | =>DynamicDataUse | NamedDataElementUse 
    
    //Alternative vision: radically simplified
    //Remove static and dynamic eventually in favour of the sub-rules 
    DataElementUse
//    | LiteralValueUse
@@ -322,6 +311,16 @@ DataUse returns tdl::DataUse:
    | (DynamicDataUse)
;

fragment ReductionFragment returns tdl::DataUse:
    (->reduction+=CollectionReference)?
    ('.' reduction+=MemberReference)*
;

fragment ParameterBindingFragment returns tdl::DataUse:
    LParen (argument+=ParameterBinding ( ',' argument+=ParameterBinding)*)? RParen
;


ParameterBinding returns tdl::ParameterBinding:
    parameter=[tdl::Parameter|Identifier]
    '=' dataUse=DataUse
@@ -338,7 +337,6 @@ CollectionReference returns tdl::MemberReference:

StaticDataUse returns tdl::StaticDataUse:    
    DataInstanceUse
    | AnonymousDataInstanceUse 
    | SpecialValueUse
    | LiteralValueUse
;
@@ -347,7 +345,6 @@ DataInstanceUse returns tdl::DataInstanceUse:
    (
    	'instance' dataInstance=[tdl::DataInstance|Identifier]
    	UnassignedFragment?
    	//DONE: This shall be optional!
    	ParameterBindingFragment?
    	ReductionFragment
    )
@@ -357,48 +354,21 @@ DataInstanceUse returns tdl::DataInstanceUse:
    	UnassignedFragment?
    	(ParameterBindingFragment | CollectionItemFragmentDataInstanceUse)
    )
;

AnonymousDataInstanceUse returns tdl::DataInstanceUse:
    |
    (
	    'an' 'instance' 
	    UnassignedFragment?
	    (ParameterBindingFragment | CollectionItemFragmentDataInstanceUse)    	
    )
;

//TODO: Explore JSON data further or discard
//JSONDataInstanceUse returns tdl::DataInstanceUse:
//    {tdl::DataInstanceUse}
//    //TODO: add annotation?
//    //TODO: add collections?
//    //TODO: persist with indentation?
//    RBegin
//    argument+=JSONParameterBinding ( ',' argument+=JSONParameterBinding)*
//    REnd
//;
//
//JSONParameterBinding returns tdl::ParameterBinding:
//    //PrefixFragment?
//    parameter=[tdl::Parameter|EString]
//    ':' (dataUse=LiteralValueUse | dataUse=JSONDataInstanceUse)
//    //TODO: this is ambiguous    
//    //WithNameFragment?
//;


//TODO: Problematic
//DataInstanceUse returns tdl::DataInstanceUse:
//    {tdl::DataInstanceUse}
//    //PrefixFragment?
//    (
//        ReferencedDataInstance
//        | AnonymousDataInstanceWithType
//        | AnonymousDataInstanceWithoutType
////        | AnonymousCollection
//    ) 
//    //TODO: this is ambiguous    
//    //WithNameFragment?
//;
fragment UnassignedFragment returns tdl::DataInstanceUse:
    '<' unassignedMember=UnassignedMemberTreatment '>'
;

fragment CollectionItemFragmentDataInstanceUse returns tdl::DataInstanceUse:
    '[' (item+=DataUse (',' item+=DataUse)*)? ']'
;

SpecialValueUse returns tdl::SpecialValueUse:
    OmitValue | AnyValue | AnyValueOrOmit 
@@ -418,12 +388,8 @@ OmitValue returns tdl::OmitValue:
;

LiteralValueUse returns tdl::LiteralValueUse:
	//DONE: Currently at least one, pending discussion in Part 1 -> add constraint
    (value=STRING | intValue=BIGINTEGER | boolValue=BOOLEAN)
    //DONE: add option to have the type after wards without any keyword e.g. 100 s?
    //		-> currently with braces due to ambiguity
    //Note overloaded syntax with constraints, in a sense this is a constraint too..
	//DONE: add parameter bindings and reduction (only if type is specified)
	(
		LBrace dataType=[tdl::DataType|Identifier] RBrace
		(ParameterBindingFragment | ReductionFragment)
@@ -439,7 +405,6 @@ DynamicDataUse returns tdl::DynamicDataUse:
;

FunctionCall returns tdl::FunctionCall:
    //DONE: refine syntax - use unified DataElementUse instead
    'instance' 'returned' 'from' function=[tdl::Function|Identifier] 
    ParameterBindingFragment
    ReductionFragment
@@ -451,7 +416,6 @@ FormalParameterUse returns tdl::FormalParameterUse:
;

VariableUse returns tdl::VariableUse:
    //DONE: try to adjust syntax so that -> is not necessary
    componentInstance=[tdl::ComponentInstance|Identifier]
    '::' variable=[tdl::Variable|Identifier]
    (ParameterBindingFragment | ReductionFragment)
@@ -468,7 +432,6 @@ PredefinedFunctionCallSize returns tdl::PredefinedFunctionCall:
    LParen actualParameters+=DataUse RParen
;


PredefinedFunctionCallNot returns tdl::PredefinedFunctionCall:
    function=[tdl::PredefinedFunction|PredefinedIdentifierNot] 
    LParen actualParameters+=DataUse RParen
@@ -500,9 +463,9 @@ DataElementUse returns tdl::DataElementUse:
        //DONE: decide on prefix -> extract to comment? -> capture as name
        //(('new' | 'a') dataElement=[tdl::DataType|Identifier])?
        (
        	//TODO: do we really need different ways?
        	name=('new' | 'a' | 'an' | 'the') 
        	dataElement=[tdl::DataType|Identifier]
        	//DONE: do we really need different ways? -> not for now!
        	//name=('new' | 'a' | 'an' | 'the')
        	'new' dataElement=[tdl::DataType|Identifier]
        )?
        UnassignedFragmentNamedElement?
        (ParameterBindingFragment | CollectionItemFragment)
@@ -515,6 +478,14 @@ DataElementUse returns tdl::DataElementUse:
    )
;

fragment UnassignedFragmentNamedElement returns tdl::DataElementUse:
    '<' unassignedMember=UnassignedMemberTreatment '>'
;

fragment CollectionItemFragment returns tdl::DataElementUse:
    '[' (item+=DataUse (',' item+=DataUse)*)? ']'
;

//# Time

Time returns tdl::Time:
@@ -603,7 +574,8 @@ GateType returns tdl::GateType:
;

enum GateTypeKind returns tdl::GateTypeKind:
    Message = 'Message' | Procedure = 'Procedure';
    Message = 'Message' | Procedure = 'Procedure'
;

GateInstance returns tdl::GateInstance:
    AnnotationCommentFragment
@@ -629,12 +601,12 @@ ComponentInstance returns tdl::ComponentInstance:
;

enum ComponentInstanceRole returns tdl::ComponentInstanceRole:
    SUT = 'SUT' | Tester = 'Tester';
    SUT = 'SUT' | Tester = 'Tester'
;

GateReference returns tdl::GateReference:
    //NOTE: No annotations or comments
    //DONE: make sure this is handled properly in the scoping
    //		-> note that if it is present, it shall be used exclusively
    //		-> note that if the name is present, it shall be used exclusively
    (name=GRIdentifier '=')? 
    component=[tdl::ComponentInstance|Identifier]
    '::' 
@@ -671,6 +643,17 @@ TestDescription returns tdl::TestDescription:
    (behaviourDescription=BehaviourDescription)?
;

fragment TDPrefixFragment returns tdl::TestDescription:
    TDObjectiveFragment?
    AnnotationCommentFragment
;

fragment TDObjectiveFragment returns tdl::TestDescription:
    'Objective:' testObjective+=[tdl::TestObjective|Identifier] 
    	( ',' testObjective+=[tdl::TestObjective|Identifier])*
;


BehaviourDescription returns tdl::BehaviourDescription:
    //NOTE: No annotations or comments
    behaviour=Behaviour
@@ -685,6 +668,20 @@ Behaviour returns tdl::Behaviour:
    //DefaultBehaviour | InterruptBehaviour | 
;

fragment WithBehaviourFragment returns tdl::Behaviour:
    'with'
    BEGIN
        NameFragment?
        ObjectiveFragment?
        (comment+=Comment)*
    END
;

fragment ObjectiveFragment returns tdl::Behaviour:
    'Objective:' testObjective+=[tdl::TestObjective|Identifier] ( ',' testObjective+=[tdl::TestObjective|Identifier])*
;


Block returns tdl::Block:
    //NOTE: No annotations or comments
    ('[' guard+=LocalExpression ( ',' guard+=LocalExpression)* ']' )?
@@ -711,6 +708,18 @@ CombinedBehaviour returns tdl::CombinedBehaviour:
    =>WithCombinedFragment?
;

fragment WithCombinedFragment returns tdl::CombinedBehaviour:
    'with'
    BEGIN
        NameFragment?
        ObjectiveFragment?
        (comment+=Comment)*
        (periodic+=PeriodicBehaviour)*
        (exceptional+=ExceptionalBehaviour)*
    END
;


SingleCombinedBehaviour returns tdl::SingleCombinedBehaviour:
    CompoundBehaviour
    | BoundedLoopBehaviour
@@ -756,20 +765,19 @@ ConditionalBehaviour returns tdl::ConditionalBehaviour:
AlternativeBehaviour returns tdl::AlternativeBehaviour:
    AnnotationFragment
    'alternatively' block+=Block
    //DONE: enforce 2+
    ('or' block+=Block)+ 
;

ParallelBehaviour returns tdl::ParallelBehaviour:
    AnnotationFragment
    'run' block+=Block 
    //DONE: enforce 2+
    ('in' 'parallel' 'to' block+=Block)
    ('and' block+=Block)*
;

ExceptionalBehaviour returns tdl::ExceptionalBehaviour:
    DefaultBehaviour | InterruptBehaviour;
    DefaultBehaviour | InterruptBehaviour
;

DefaultBehaviour returns tdl::DefaultBehaviour:
    AnnotationFragment
@@ -798,7 +806,7 @@ PeriodicBehaviour returns tdl::PeriodicBehaviour:
//## Atomic Behaviour

AtomicBehaviour returns tdl::AtomicBehaviour:
    ((TimerOperation
    (TimerOperation
    | TimeOperation
    | Break | Stop
    | VerdictAssignment | Assertion
@@ -806,11 +814,34 @@ AtomicBehaviour returns tdl::AtomicBehaviour:
    | TestDescriptionReference 
    | ActionBehaviour 
    | Assignment)
    WithAtomicFragment?)
//    |(Interaction) //DONE: isolate procedure call only? -> removed name from atomic behaviour 
    //DONE: should add with fragments without name -> by default no name, add name only as needed
    WithAtomicFragment?
;

fragment AtomicPrefixFragment returns tdl::AtomicBehaviour:
    ObjectiveFragment?
    AnnotationCommentFragment
;

fragment WithAtomicFragment returns tdl::AtomicBehaviour:
	//NOTE: No names
    'with'
    BEGIN
        //NameFragment?
        TimeLabelFragment?
        TimeConstraintFragment?
    END
;

fragment TimeLabelFragment returns tdl::AtomicBehaviour:
    timeLabel=TimeLabel 
;

fragment TimeConstraintFragment returns tdl::AtomicBehaviour:
    LBrace timeConstraint+=TimeConstraint ( ',' timeConstraint+=TimeConstraint)* RBrace
;



Break returns tdl::Break:
    {tdl::Break}
    AtomicPrefixFragment
@@ -860,7 +891,6 @@ ValueAssignmentMessage returns tdl::ValueAssignment:
    'assigned' 'to' variable=[tdl::Variable|Identifier]
;


ReceiveMessage returns tdl::Message:
    AtomicPrefixFragment
    //NOTE: Only single target possible
@@ -881,11 +911,8 @@ ReceiveValueAssignmentMessage returns tdl::ValueAssignment:
    variable=[tdl::Variable|Identifier] '='
;



ProcedureCall returns tdl::ProcedureCall:
    AtomicPrefixFragment
    //DONE: duplicate name assignment -> see workaround in AtomicBehaviour, refine! -> removed name from with fragment
    (name=Identifier ':')?
    sourceGate=[tdl::GateReference|GRIdentifier]
    'calls' signature=[tdl::ProcedureSignature|Identifier]
@@ -895,7 +922,6 @@ ProcedureCall returns tdl::ProcedureCall:

ProcedureCallResponse returns tdl::ProcedureCall:
    AtomicPrefixFragment
    //DONE: this shall probably be switched -> resolved
    (replyTo=[tdl::ProcedureCall|Identifier] ':')?
    sourceGate=[tdl::GateReference|GRIdentifier]
    'responds' 'with' signature=[tdl::ProcedureSignature|Identifier]
@@ -911,18 +937,17 @@ TargetProcedure returns tdl::Target:

ValueAssignmentProcedure returns tdl::ValueAssignment:
    //NOTE: No name, annotations or comments
    'where' parameter=[tdl::Parameter|Identifier] 'is' 'assigned' 'to' variable=[tdl::Variable|Identifier]
    'where' parameter=[tdl::Parameter|Identifier] 'is' 
    'assigned' 'to' variable=[tdl::Variable|Identifier]
;
    
TestDescriptionReference returns tdl::TestDescriptionReference:
    AtomicPrefixFragment
    'execute' testDescription=[tdl::TestDescription|Identifier]
    //TODO: when was this changed in v1.5.1? the constraints are utterly broken!
    (LParen argument+=ParameterBinding ( ',' argument+=ParameterBinding)* RParen )?
    (BEGIN
    	//DONE: enforce at least 2? -> no
    	//DONE: check all other + quantifiers
        componentInstanceBinding+=ComponentInstanceBinding (',' componentInstanceBinding+=ComponentInstanceBinding)*
        componentInstanceBinding+=ComponentInstanceBinding 
        (',' componentInstanceBinding+=ComponentInstanceBinding)*
    END)?
;

@@ -953,7 +978,6 @@ Assignment returns tdl::Assignment:
    AtomicPrefixFragment
    variable=VariableUse
    '=' expression=DataUse
    //('on' componentInstance=[tdl::ComponentInstance|Identifier])?
;


@@ -961,191 +985,20 @@ Assignment returns tdl::Assignment:

//## Fragments

//Element : Abstract
fragment AnnotationFragment returns tdl::Element:
    (annotation+=Annotation)*
;

fragment AnnotationCommentFragment returns tdl::Element:
    (comment+=Comment)*
    (annotation+=Annotation)*
;

fragment NameFragment returns tdl::Element:
    'Name:' name=Identifier
;

//Use: inline block - within other blocks, e.g. with other contents 
fragment WithCommentFragment returns tdl::Element:
    'with'
    BEGIN
        //DONE: Shall this be '*'? Ambiguity?
        // 		-> empty blocks problematic for indentation-based syntax
        (comment+=Comment)+
    END
;

fragment WithNameFragment returns tdl::Element:
    'with'
    BEGIN
        NameFragment
    END
;

//DataType: Abstract

fragment ConstraintFragment returns tdl::DataType:
    (LBrace constraint+=Constraint RBrace)* 
;

//Member

fragment MemberConstraintFragment returns tdl::Member:
     (LBrace constraint+=Constraint RBrace)* 
;


//DataUse: Abstract

fragment ReductionFragment returns tdl::DataUse:
    (->reduction+=CollectionReference)?
    ('.' reduction+=MemberReference)*
;

fragment ParameterBindingFragment returns tdl::DataUse:
    LParen (argument+=ParameterBinding ( ',' argument+=ParameterBinding)*)? RParen
;

//DataInstanceUse: Abstract

fragment UnassignedFragment returns tdl::DataInstanceUse:
    '<' unassignedMember=UnassignedMemberTreatment '>'
;

//DataElementUse: Abstract

//DONE: Inline both, no need for fragments at this point -> used in multiple spots
fragment UnassignedFragmentNamedElement returns tdl::DataElementUse:
    '<' unassignedMember=UnassignedMemberTreatment '>'
;

fragment CollectionItemFragment returns tdl::DataElementUse:
    '[' (item+=DataUse (',' item+=DataUse)*)? ']'
;

fragment CollectionItemFragmentDataInstanceUse returns tdl::DataInstanceUse:
    '[' (item+=DataUse (',' item+=DataUse)*)? ']'
;


//fragment ReferencedDataInstance returns tdl::DataInstanceUse:
//    //referenced DataInstance, arguments or reduction optional
//    dataInstance=[tdl::DataInstance|Identifier]
//    UnassignedFragment?
//    (
//        ParameterBindingFragment
//        //TODO: reduction problematic
//        |
//        (   (->reduction+=CollectionReference)?
//            ('.' reduction+=MemberReference)*
//        )
//    )?
//;
//
//fragment AnonymousDataInstanceWithType returns tdl::DataInstanceUse:
//    //anonymous with data type, arguments mandatory, only structured data types
//    ('a' dataType=[tdl::StructuredDataType|Identifier])?
//    UnassignedFragment?
//    ParameterBindingFragment
//;
//
//fragment AnonymousDataInstanceWithoutType returns tdl::DataInstanceUse:
//    //anonymous with no data type, arguments mandatory, otherwise AnyValue, only structured data types
//    //type assumed from context
//    //TODO: ambiguity -> placehodler keyword?
//    UnassignedFragment?
//    ParameterBindingFragment
//;
//
//fragment AnonymousCollection returns tdl::DataInstanceUse:
//    //TODO: Not standardised: inline collections, no type needed? (only when used in interaction?)
//    ('a' dataType=[tdl::CollectionDataType|Identifier])?
//    UnassignedFragment?
//    //TODO: Only static?
//    '[' (item+=StaticDataUse (',' item+=StaticDataUse)*)? ']'
//;





//Behaviour : Abstract

fragment WithBehaviourFragment returns tdl::Behaviour:
    'with'
    BEGIN
        NameFragment?
        ObjectiveFragment?
        (comment+=Comment)*
    END
;

fragment ObjectiveFragment returns tdl::Behaviour:
    'Objective:' testObjective+=[tdl::TestObjective|Identifier] ( ',' testObjective+=[tdl::TestObjective|Identifier])*
;

//TestDescription

fragment TDPrefixFragment returns tdl::TestDescription:
    TDObjectiveFragment?
    AnnotationCommentFragment
;

fragment TDObjectiveFragment returns tdl::TestDescription:
    'Objective:' testObjective+=[tdl::TestObjective|Identifier] 
    	( ',' testObjective+=[tdl::TestObjective|Identifier])*
;

//AtomicBehaviour : Abstract

fragment AtomicPrefixFragment returns tdl::AtomicBehaviour:
    ObjectiveFragment?
    AnnotationCommentFragment
;

fragment WithAtomicFragment returns tdl::AtomicBehaviour:
	//NOTE: No names
	//TODO: At least one?
    'with'
    BEGIN
        //NameFragment?
        TimeLabelFragment?
        TimeConstraintFragment?
    END
;

fragment TimeLabelFragment returns tdl::AtomicBehaviour:
    timeLabel=TimeLabel 
;

fragment TimeConstraintFragment returns tdl::AtomicBehaviour:
    LBrace timeConstraint+=TimeConstraint ( ',' timeConstraint+=TimeConstraint)* RBrace
;


//CombinedBehaviour : Abstract

fragment WithCombinedFragment returns tdl::CombinedBehaviour:
    'with'
    BEGIN
        NameFragment?
        ObjectiveFragment?
        (comment+=Comment)*
        //DONE: periodic / exceptional as separate fragment(s) for combined behaviour? -> keep in with block..
        (periodic+=PeriodicBehaviour)*
        (exceptional+=ExceptionalBehaviour)*
    END
;


//## ValueConverter Rules (Pseudo-terminals)
@@ -1166,8 +1019,6 @@ Identifier returns ecore::EString:
    ID
;

//DONE: rename? merge? (only applicable to gates..
//		-> GRIdentifier
GRIdentifier returns ecore::EString:
    ID ('::' ID)?
;
@@ -1222,3 +1073,77 @@ terminal FALSE : 'false';
//alternative bindings for brace-based delimiters
terminal BEGIN: '{';
terminal END: '}';



//TODO: Explore JSON data further or discard
//JSONDataInstanceUse returns tdl::DataInstanceUse:
//    {tdl::DataInstanceUse}
//    //TODO: add annotation?
//    //TODO: add collections?
//    //TODO: persist with indentation?
//    RBegin
//    argument+=JSONParameterBinding ( ',' argument+=JSONParameterBinding)*
//    REnd
//;
//
//JSONParameterBinding returns tdl::ParameterBinding:
//    //PrefixFragment?
//    parameter=[tdl::Parameter|EString]
//    ':' (dataUse=LiteralValueUse | dataUse=JSONDataInstanceUse)
//    //TODO: this is ambiguous    
//    //WithNameFragment?
//;


//TODO: Problematic
//DataInstanceUse returns tdl::DataInstanceUse:
//    {tdl::DataInstanceUse}
//    //PrefixFragment?
//    (
//        ReferencedDataInstance
//        | AnonymousDataInstanceWithType
//        | AnonymousDataInstanceWithoutType
////        | AnonymousCollection
//    ) 
//    //TODO: this is ambiguous    
//    //WithNameFragment?
//;


//fragment ReferencedDataInstance returns tdl::DataInstanceUse:
//    //referenced DataInstance, arguments or reduction optional
//    dataInstance=[tdl::DataInstance|Identifier]
//    UnassignedFragment?
//    (
//        ParameterBindingFragment
//        //TODO: reduction problematic
//        |
//        (   (->reduction+=CollectionReference)?
//            ('.' reduction+=MemberReference)*
//        )
//    )?
//;
//
//fragment AnonymousDataInstanceWithType returns tdl::DataInstanceUse:
//    //anonymous with data type, arguments mandatory, only structured data types
//    ('a' dataType=[tdl::StructuredDataType|Identifier])?
//    UnassignedFragment?
//    ParameterBindingFragment
//;
//
//fragment AnonymousDataInstanceWithoutType returns tdl::DataInstanceUse:
//    //anonymous with no data type, arguments mandatory, otherwise AnyValue, only structured data types
//    //type assumed from context
//    //TODO: ambiguity -> placehodler keyword?
//    UnassignedFragment?
//    ParameterBindingFragment
//;
//
//fragment AnonymousCollection returns tdl::DataInstanceUse:
//    //TODO: Not standardised: inline collections, no type needed? (only when used in interaction?)
//    ('a' dataType=[tdl::CollectionDataType|Identifier])?
//    UnassignedFragment?
//    //TODO: Only static?
//    '[' (item+=StaticDataUse (',' item+=StaticDataUse)*)? ']'
//;