// automatically generated by Xtext
grammar org.etsi.mts.tdl.graphical.labels.Data with org.eclipse.xtext.common.Terminals

//import "http://www.eclipse.org/uml2/4.0.0/Types" 
import "http://www.etsi.org/spec/TDL/1.4.1"
//import "http://www.eclipse.org/uml2/5.0.0/Types" as types 
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
//import "http://www.etsi.org/spec/TDL/STABLE" as tdl


TDLSpec returns Package:
	{Package}
	'TDLan Specification'
	name=EString
	'{'
		(packagedElement+=PackageableElement ( packagedElement+=PackageableElement)* )?
		(nestedPackage+=Package (nestedPackage+=Package)*)?
	'}'
	(
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
    ;

//#####################################################################################

DataUse returns DataUse:
	DynamicDataUse | StaticDataUse;
	

StaticDataUse returns StaticDataUse:
	SpecialValueUse | DataInstanceUse;

DynamicDataUse returns DynamicDataUse:
	VariableUse| FunctionCall | FormalParameterUse | TimeLabelUse;

SpecialValueUse returns StaticDataUse:
	NoneValue | AnyValue | AnyNoneValue
;

EString returns ecore::EString:
	ID
;


DataInstanceUse returns DataInstanceUse:
	dataInstance=[DataInstance|NumberAsIdentifier] | 
	
	(  dataInstance=[DataInstance|EString]
	   ('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
	   ('.' reduction+=MemberReference)*
	)
	//TODO: if for some reason the data instance use does have a name
	//it will cause problems... same applies for other scenarios 
	//TODO: create a more elegant way to handle that gracefully)
	//(name=EString)?
	;

NumberAsIdentifier returns ecore::EString:
    '-'? INT ('.' INT)?;


MemberReference returns MemberReference:
	member=[Member|EString]
;


FormalParameterUse returns FormalParameterUse:
	parameter=[FormalParameter|EString]
	('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
	( "." reduction+=MemberReference)*
	;

FunctionCall returns FunctionCall:
	function=[Function|EString] 
	'('
	(argument+=ParameterBinding ( "," argument+=ParameterBinding)*)?
	')'
	('.' reduction+=MemberReference)*
	;

VariableUse returns VariableUse:
	componentInstance=[ComponentInstance|EString]
	'->'
	variable=[Variable|EString]
	('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
	("." reduction+=MemberReference)*
	;

TimeLabelUse returns TimeLabelUse:
	timeLabel=[TimeLabel|EString]
	;

ParameterBinding returns ParameterBinding:
	parameter=[Parameter|EString]
	':=' 
	dataUse=DataUse
	;
	
NoneValue returns OmitValue:
	{OmitValue}
	'omit'
	;

AnyValue returns AnyValue:
	'?'
	(':' dataType=[DataType|EString])
	;
	
AnyNoneValue returns AnyValueOrOmit:
    {AnyValueOrOmit}
	'*'
	;




Annotation returns Annotation:
	key=[AnnotationType|EString]
	(':' value=String0)?
	(
	'with'
	  '{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
		(name=EString)?
	'}')?
	';';

AnnotationType returns AnnotationType:
	{AnnotationType}
	'Annotation'
	name=EString
	('with' 
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?	
	';';


Comment returns Comment:
	'Note'
		(name=EString)?
	':'
		body=String0

	(
	'with'
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	';';



DataInstance returns DataInstance:
//	SimpleDataInstance_Impl | StructuredDataInstance | Verdict | TimeLabel;
	SimpleDataInstance_Impl | StructuredDataInstance;

DataType returns DataType:
	SimpleDataType_Impl | StructuredDataType | Time;

EStringDot returns ecore::EString:
	ID '.' ID
;



Function returns Function:
	'Function'
	name=EString
	'(' (formalParameter+=FormalParameter ( "," formalParameter+=FormalParameter)* )? ')'
	'returns' 
	returnType=[DataType|EString]
	(':' body=String0)?
	('with'
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	';';


Member returns Member:
	(isOptional=Optional)?
	name=EString
	'of' 'type'
	dataType=[DataType|EString]
    (
    'with'
    '{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?;

Optional returns ecore::EBoolean :
	'optional'
;

MemberAssignment returns MemberAssignment:
	member=[Member|EString]
	'=' 
	memberSpec=StaticDataUse
    (
    'with'
    '{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
		('name' name=EString)?
	'}')?;

ParameterMapping returns ParameterMapping:
	parameter=[Parameter|EString]
	('mapped' 'to' parameterURI=String0)?
	('as' name=EString)?
    (
    'with'
    '{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	';';


//OptionalBehaviour returns OptionalBehaviour:
//	'optionally'
//	block=Block
//	(
//    'with'
//    '{'
//	    (comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//		('test objectives' ':' testObjective+=[TestObjective|EString] ( "," testObjective+=[TestObjective|EString])* ';')?
//		('name' name=EString)?
//	'}')?
//	(exceptional+=ExceptionalBehaviour ( exceptional+=ExceptionalBehaviour)*)?
//	(periodic+=PeriodicBehaviour ( periodic+=PeriodicBehaviour)* )?
//	';'
//	;
	

Package returns Package:
	{Package}
	'Package'
	name=EString
	'{'
		(packagedElement+=PackageableElement ( packagedElement+=PackageableElement)* )?
		(nestedPackage+=Package (nestedPackage+=Package)*)?
	'}'
   (
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
    ;

PackageableElement returns PackageableElement:
//	AnnotationType | TestObjective | DataResourceMapping | DataElementMapping | SimpleDataType_Impl | SimpleDataInstance_Impl | StructuredDataType | StructuredDataInstance | Action_Impl | Function | Verdict | ComponentType | GateType | Time | TimeLabel | TestConfiguration | TestDescription;
	AnnotationType | SimpleDataType_Impl | SimpleDataInstance_Impl | StructuredDataType | StructuredDataInstance | Function | Time | TestDescription;


Parameter returns Parameter:
	Member | FormalParameter;

FormalParameter returns FormalParameter:
    name=EString
    'of' 'type'
    dataType=[DataType|EString]
    (
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?;

//Real returns Real:
//	'-'? INT+'.'INT+
//;
//


SimpleDataInstance_Impl returns SimpleDataInstance:
	dataType=[DataType|EString]
	name=EString
	('with'
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	;

SimpleDataType_Impl returns SimpleDataType:
	{SimpleDataType}
	//'Simple' 'Data' 'Type'
	'Type'
	name=EString
	 (
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
	';'
	;		


String0 returns ecore::EString:
	STRING
;

StructuredDataInstance returns StructuredDataInstance:
	{StructuredDataInstance}
	dataType=[DataType|EString]
	name=EString
	('(' memberAssignment+=MemberAssignment (',' memberAssignment+=MemberAssignment)* ')' )?		
	('with'
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	';'
	;

StructuredDataType returns StructuredDataType:
	{StructuredDataType}
	//'Structured' 'Data' 'Type'
	'Type'
	name=EString
	('(' member+=Member ( "," member+=Member)* ')')?
   	(
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
    ';';


Time returns Time:
	{Time}
	'Time'
	name=EString
    ('with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
	';';

TimeConstraint returns TimeConstraint:
		(name=EString)?
		timeConstraintExpression=DataUse
		('with'
		'{'
			(comment+=Comment (comment+=Comment)*)?
			(annotation+=Annotation (annotation+=Annotation)*)?
		'}')?
	'}';

TimeLabel returns TimeLabel:
	name=EString
//	'in' 
//	dataType=[DataType|EString]
    ('with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
    '}')?
	';';


Variable returns Variable:
	'variable'
	name=EString
	'of' 'type'
	dataType=[DataType|EString]
	('with' 
	'{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
	'}')?
	';';

//
//StaticDataUse returns StaticDataUse:
//	DataInstanceUse | AnyValue | AnyNoneValue | NoneValue;
//
//DataInstanceUse returns DataInstanceUse:
//	//TODO: validate
//	dataInstance=[DataInstance|EString]
//	('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
//	('.' reduction+=[Member|EString])*
//    ('with'
//    '{'
//		('name' name=EString)?
//        (comment+=Comment (comment+=Comment)*)?
//        (annotation+=Annotation (annotation+=Annotation)*)?
//    '}')?
//	;
//
//
//AnyNoneValue returns AnyNoneValue:
//	'any' 'or' 'no'
//	dataType=[DataType|EString]
//	(
//	'with'
//	  '{'
//		('reduction' '(' reduction+=[Member|EString] ( "," reduction+=[Member|EString])* ')' )?
//		('argument' '{' argument+=ParameterBinding ( "," argument+=ParameterBinding)* '}' )?
//		(comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//		('name' name=EString)?
//	'}')?
//	;
//
//AnyValue returns AnyValue:
//	'any'
//	dataType=[DataType|EString]
//	(
//	'with'
//	  '{'
//		('reduction' '(' reduction+=[Member|EString] ( "," reduction+=[Member|EString])* ')' )?
//		('argument' '{' argument+=ParameterBinding ( "," argument+=ParameterBinding)* '}' )?
//		(comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//		('name' name=EString)?
//	'}')?
//	;
//
//ParameterBinding returns ParameterBinding:
//	parameter=[Parameter|EString]
//	'=' 
//	dataUse=DataUse
//	(
//	'with'
//	  '{'
//		(comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//		('name' name=EString)?
//	'}')?
//	;
//
//
//
//DataUse returns DataUse:
//	DataInstanceUse | FunctionCall | FormalParameterUse | TimeLabelUse | VariableUse | AnyValue | AnyNoneValue | NoneValue;
//
//
//
//TimeLabelUse returns TimeLabelUse:
//	timeLabel=[TimeLabel|EString]
//	//('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
//	//( "." reduction+=[Member|EString])*
//    (
//    'with'
//    '{'
//		('name' name=EString)?
//        (comment+=Comment (comment+=Comment)*)?
//        (annotation+=Annotation (annotation+=Annotation)*)?
//    '}')?;
//
//
//FormalParameterUse returns FormalParameterUse:
//	'parameter'
//	parameter=[FormalParameter|EString]
//	('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
//	( "." reduction+=[Member|EString])*
//    (
//    'with'
//    '{'
//		('name' name=EString)?
//        (comment+=Comment (comment+=Comment)*)?
//        (annotation+=Annotation (annotation+=Annotation)*)?
//    '}')?;
//
//
//
//
//VariableUse returns VariableUse:
//	//TODO: try to adjust syntax so that -> is not necessary
//	componentInstance=[ComponentInstance|EString]
//	'->'
//	variable=[Variable|EString]
//	('(' argument+=ParameterBinding ( "," argument+=ParameterBinding)* ')' )?
//	("." reduction+=[Member|EString])*
//	('with' 
//	'{'
//		('name' name=EString)?
//        (comment+=Comment (comment+=Comment)*)?
//        (annotation+=Annotation (annotation+=Annotation)*)?
//	'}')?
//	;
//
//NoneValue returns NoneValue:
//	'no'
//	dataType=[DataType|EString]
//    (
//    'with'
//    '{'
//		('argument' '{' argument+=ParameterBinding ( "," argument+=ParameterBinding)* '}' )?
//		('reduction' '(' reduction+=[Member|EString] ( "," reduction+=[Member|EString])* ')' )?
//		(comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//		('name' name=EString)?
//	'}')?;
//
//
//FunctionCall returns FunctionCall:
//	'instance' 'returned' 'from'
//	function=[Function|EString] 
//	'('
//	(argument+=ParameterBinding ( "," argument+=ParameterBinding)*)?
//	')'
//	('.' reduction+=[Member|EString])*
//	('with'
//	'{'
//		('name' name=EString)?
//		(comment+=Comment (comment+=Comment)*)?
//		(annotation+=Annotation (annotation+=Annotation)*)?
//	'}')?
//	;
//
//

Interaction returns Message:
	sourceGate=[GateReference|EStringDot]
	('sends' | isTrigger=Trigger) 
	argument=DataUse
	'to' 
	target+=Target ( "," target+=Target)* 
	(
	'with'
	'{'
		(comment+=Comment (comment+=Comment)*)?
		(annotation+=Annotation (annotation+=Annotation)*)?
		('test' 'objectives' ':' testObjective+=[TestObjective|EString] ( "," testObjective+=[TestObjective|EString])* ';')?
		('name' name=EString)? //USE FOR STEPS?
		('time' 'label' timeLabel=TimeLabel)?
		('time' 'constraints' ':' timeConstraint+=TimeConstraint ( "," timeConstraint+=TimeConstraint)* ';' )?
	'}')?
	';'
	;

Trigger returns ecore::EBoolean :
	'triggers'
;

Target returns Target:
	targetGate=[GateReference|EStringDot]
	(valueAssignment+=ValueAssignmentMessage)?
   	(
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
		('name' name=EString)?
    '}')?
    ;

ValueAssignmentMessage returns ValueAssignment:
    //TODO: check what the correct syntax shall be
    'where' 'it' 'is' 'assigned' 'to' variable=[Variable|EString]
    (
    'with'
    '{'
        (comment+=Comment (comment+=Comment)*)?
        (annotation+=Annotation (annotation+=Annotation)*)?
        ('name' name=EString)?
    '}')?
    ;


VerdictAssignment returns VerdictAssignment:
	'set' 'verdict' 'to'
	verdict=DataUse
	;
	
Wait returns Wait:
	( 'component' componentInstance=[ComponentInstance|EString])
	'waits' 'for'
	period=DataUse
;

Quiescence returns Quiescence:
	('component' componentInstance=[ComponentInstance|EString] | 'gate' gateReference=[GateReference|EStringDot])
	'is' 'quiet' 'for'
	period=DataUse 
;

TestDescription returns TestDescription:
	'Test' 'Description'
		name=EString
		('(' formalParameter+=FormalParameter ( "," formalParameter+=FormalParameter)* ')')?
		('uses' 'configuration' testConfiguration=[TestConfiguration|EString])
		(behaviourDescription=BehaviourDescription)? 
		
;

TestDescriptionReference returns TestDescriptionReference:
	testDescription=[TestDescription|EString]
    ('(' actualParameter+=ParameterBinding ( "," actualParameter+=ParameterBinding)* ')' )?
	(componentInstanceBinding+=ComponentInstanceBinding ( "," componentInstanceBinding+=ComponentInstanceBinding)*)?
;

ComponentInstanceBinding returns ComponentInstanceBinding:
	actualComponent=[ComponentInstance|EString]
	'->' formalComponent=[ComponentInstance|EString]
	;
BehaviourDescription returns BehaviourDescription:
	behaviour=Behaviour
;
Behaviour returns Behaviour:
  Wait 
| Quiescence 
| CompoundBehaviour
| TestDescriptionReference 
| Interaction
| Assertion
| Assignment
;

Block returns Block:
	('[' guard+=LocalExpression ']')?
	'{'
		behaviour+=Behaviour ( behaviour+=Behaviour)* 
	'}'
	;

LocalExpression returns LocalExpression:
	 expression=DataUse
;


CompoundBehaviour returns CompoundBehaviour:
	block=Block
;

Assignment returns Assignment:
	(componentInstance=[ComponentInstance|EString] '->')?
	('name' name=EString)?
	variable=VariableUse
	'=' 
	expression=DataUse
	;
	
Assertion returns Assertion:
	{Assertion}
	condition=DataUse
	('otherwise' otherwise=DataUse)?
	;

TimerStart returns TimerStart:
	'start'
	componentInstance=[ComponentInstance|EString]
	'.'
	timer=[Timer|EString]
	'for'
	period=DataUse
;

BoundedLoopBehaviour returns BoundedLoopBehaviour:
	'repeat'
	numIteration+=LocalExpression
	'times'
//	'from' startValue=DataInstanceSpecification
//	'to' endValue=DataInstanceSpecification
//	('with step' stepValue=DataInstanceSpecification)?
	block=Block
;