Commit 7db6bedf authored by Philip Makedonski's avatar Philip Makedonski Committed by Philip Makedonski
Browse files

+ latest updates to indentation based-syntax (including TO-syntax for the time being)

parent 440e8a2b
Loading
Loading
Loading
Loading
+712 −1
Original line number Diff line number Diff line
@@ -22,8 +22,719 @@ RBrace:
    '}'
;

//for both indented and un-indented blocks within parentheses
@Override
LParen:
    '(' BEGIN?
;

@Override
RParen:
    END? ')'
;

//for indentation based syntax
@Override
terminal BEGIN: 'synthetic:BEGIN';  // increase indentation

@Override
terminal END: 'synthetic:END';      // decrease indentation






//## Part 4 (TO) syntax -> move to separate project? separate brace-based and indentation-based as well 

//# Foundation

@Override
PackageableElement returns tdl::PackageableElement:
    super
    | Entity 
    | Event 
    | PICS
    | StructuredTestObjective
    | TestPurposeDescription
;

//TODO: this will need to be pulled to TX..
//TODO: quite a bit contrived.. -> may be restricted to TO... (separate editor?)
@Override
AnnotationType returns tdl::AnnotationType:
	'Annotation' name = (
		Identifier 
		| InitialBlockName 
		| ExpectedBlockName 
		| FinalBlockName 
		| TestPurposeDescriptionName
		| 'when'
		| 'then'
	)
;

InitialConditionsAnnotation returns tdl::Annotation:
	key=[tdl::AnnotationType|InitialBlockName]
;

ExpectedBehaviourAnnotation returns tdl::Annotation:
	key=[tdl::AnnotationType|ExpectedBlockName]
;

FinalConditionsAnnotation returns tdl::Annotation:
	key=[tdl::AnnotationType|FinalBlockName]
;

TestPurposeDescriptionAnnotation returns tdl::Annotation:
	key=[tdl::AnnotationType|TestPurposeDescriptionName]
;

//TODO: extract as data rule
WhenAnnotation returns tdl::Annotation:
    key=[tdl::AnnotationType|'when']
;

ThenAnnotation returns tdl::Annotation:
    key=[tdl::AnnotationType|'then']
;

Entity returns to::Entity:
    AnnotationCommentFragment
    'Entity' name=Identifier
;

Event returns to::Event:
    AnnotationCommentFragment
    //TODO: extend identifiers with STRING or multi-word value converters?
    //		only for select uses (distinct rule) or for the entire grammar?
    //TODO: check how well multi-word value converters work as a separate rule..
    //		would it then be a single string or should it be decomposed in a sequence?
    'Event' name=Identifier
;

PICS returns to::PICS:
    AnnotationCommentFragment
    'PICS' name=Identifier
;

//# Auxiliary

//## Qualifiers

//TODO: Group by context?
//TODO: Move elsewhere
//TODO: See above regarding multiwords..
//TODO: Add predefined annotations for Blocks and Behaviours?

Qualifier returns tdl::Comment:
    body=Identifier //TODO: Numbers as well? Strings as well??
;

NotQualifier returns tdl::Comment:
    body='not'
;

AndOrQualifier returns tdl::Comment:
    body='and' | body='or'
;

ArticleQualifier returns tdl::Comment:
    body='a' | body='an' | body='the'
;

AssignmentQualifier returns tdl::Comment:
    //TODO: avoid keywords with spaces
    body=Assignments
;

CommonWordQualifier returns tdl::Comment:
    body='before' 
    | body='after' 
    | body='from' 
    | body='to' 
    | body='of'
;

DirectionQualifier returns tdl::Comment:
    body='by'
    | body='in'
    | body='into'
    | body='for' 
    | body='from' 
    | body='to'
;

QuantifiedQualifier returns tdl::Comment:
    body='all' 
    | body='any'
    | body='few'
    | body='multiple' 
    | body='no' 
    | body='only'
    | body='several' 
    | body='some'
;

ReferenceQualifier returns tdl::Comment:
    body=References
;

TimeConstraintQualifier returns tdl::Comment:
    body='before' 
    | body='after' 
    | body='during' 
    | body='within' 
;


//TODO: explore whether this can be simplified as follows
//      - a side benefit being that IdentifierRefined : ID | TimeConstraintKeyword | ...
//      which would make the use of keywords more flexible
//      but also likely removing the formatting?
//      - also it will likely cause some conflicts, 
//      so it shall be used carefully where it makes sense only
TimeConstraintQualifierRefined returns tdl::Comment:
    body=TimeConstraintKeyword
;

TimeConstraintKeyword returns ecore::EString:
    'before' | 'after' | 'during' | 'within'
;

//# Test Objective

StructuredTestObjective returns to::StructuredTestObjective:
    'Test' 'Purpose' name=Identifier
    BEGIN
        ('Objective:' description=EString)? 
        ('Reference:' objectiveURI+=EString (',' objectiveURI+=EString )*)?
        ('Configuration:' configuration=[tdl::TestConfiguration|Identifier])? 
        ('PICS:' picsReference+=FirstPICSReference (picsReference+=PICSReference)*)? 
        (initialConditions=InitialConditions)?
        (expectedBehaviour=ExpectedBehaviour)?
        (finalConditions=FinalConditions)?
        (variants=Variants)?
    END
;

FirstPICSReference returns to::PICSReference :
    (comment+=NotQualifier)?
    pics=[to::PICS|Identifier]
;

PICSReference returns to::PICSReference :
    ElementAndOrPrefix
    (comment+=NotQualifier)?
    pics=[to::PICS|Identifier]
; 

InitialConditions returns to::InitialConditions:
    InitialConditionsFragment
    'with' conditions=EventSequence 
;

ExpectedBehaviour returns to::ExpectedBehaviour:
	//TODO: are the event sequences mapped to distinct behaviours? -> initially no? perhaps yes?
	//TODO: it will mean that the event sequence will be annotated..  
    ExpectedBehaviourFragment
    'ensure' 'that'
    (
		(BEGIN
			'when' whenClause=EventSequence
			'then' thenClause=EventSequence
		END)
		| 
		(thenClause=EventSequence)
	)
;

FinalConditions returns to::FinalConditions:
    FinalConditionsFragment
    'with' conditions=EventSequence 
;



//# Events

EventSequence returns to::EventSequence:
	BEGIN 
    	(RepeatedEventSequence | SimpleEventSequence)
    END 
;

SimpleEventSequence returns to::EventSequence:
    events+=FirstEventOccurrence (events+=EventOccurrence)*
;

RepeatedEventSequence returns to::RepeatedEventSequence:
	//TODO: adapt for behaviours
	'repeat'
	//TODO: revise
	//('every' interval=IterationValue | repetitions=IterationValue 'times')? 
	//DONE: replace
	BEGIN
    	events+=FirstEventOccurrence 
    	events+=EventOccurrence*
    END
;

FirstEventOccurrence returns to::EventOccurrence:
    FirstEventOccurrenceSpecification | FirstEventTemplateOccurrence 
;

EventOccurrence returns to::EventOccurrence:
    EventOccurrenceSpecification | EventTemplateOccurrence 
;

fragment EventTimingPrefix returns to::EventOccurrence:
	//TODO: shall be 0..*
	//TODO: change to specific time labels / constraints, or use generic TDL ones?
    (	(timeLabel=TimeLabel 
			(	(',' timeConstraint+=TimeConstraint)
				| ':'
			)
		) 
		| 
		(timeConstraint+=TimeConstraint)
	)	
;

FirstEventOccurrenceSpecification returns to::EventOccurrenceSpecification:
	EventOccurrenceSpecificationFragment
;

EventOccurrenceSpecification returns to::EventOccurrenceSpecification:
	ElementAndOrPrefix
	EventOccurrenceSpecificationFragment
;

fragment EventOccurrenceSpecificationFragment returns to::EventOccurrenceSpecification:
	//TODO: currently ambiguous
//    EventTimingPrefix?
    entityReference=EntityReference?
    eventReference=EventReference
    eventArgument=Argument?
    (oppositeEntityReference+=OppositeEntityReference 
    	(',' oppositeEntityReference+=OppositeEntityReference)*
    )?
    //DONE: add identifiers for notes? also in general? -> inherited
    (comment+=Comment)*
;

EntityReference returns to::EntityReference:
	EntityReferenceFragment
;

OppositeEntityReference returns to::EntityReference:
    comment+=DirectionQualifier
    EntityReferenceFragment
;

fragment EntityReferenceFragment returns to::EntityReference:
    comment+=ArticleQualifier
    comment+=Qualifier*
    (
        (entity=[to::Entity|Identifier] 'entity')
      | (component=[tdl::ComponentInstance|Identifier] 'component')
    )
;


EventReference returns to::EventReference:
    (comment+=Qualifier | comment+=CommonWordQualifier | comment+=NotQualifier)*
    event=[to::Event|Identifier] 
;

//# Event Templates
//TODO: test and validate
FirstEventTemplateOccurrence returns to::EventTemplateOccurrence:
	EventTemplateOccurrenceFragment
;

EventTemplateOccurrence returns to::EventTemplateOccurrence:
	ElementAndOrPrefix
	EventTemplateOccurrenceFragment
;

fragment EventTemplateOccurrenceFragment returns to::EventTemplateOccurrence:
	//TODO: currently ambiguous
//	EventTimingPrefix?
    'event' 
    eventTemplate=[to::EventSpecificationTemplate|Identifier]
    'occurs'
    ('with' 
    BEGIN
    	(entityBinding+=EntityBinding (',' entityBinding+=EntityBinding)*)?
		('argument' 'replaced' 'by' occurrenceArgument=Argument)?
    END
    )?
    //DONE: add identifiers for notes? also in general? -> inherited
    (comment+=Comment)*
;

EntityBinding returns to::EntityBinding:
	templateEntity=EntityReference
	'replaced' 'by'
	occurrenceEntity=EntityReference
;

//# Data

//TODO: continue with data, simplify where appropriate
Value returns to::Value:
    LiteralValue 
    | DataReference 
    | ContentReference 
    | LiteralValueReference
;

Argument returns to::Value:
    LiteralValueAsArgument
//    | TypedLiteralValueAsArgument
    | DataReferenceAsArgument
    | ContentReferenceAsArgument
    | LiteralValueReferenceArgument
;

LiteralOrDataReferenceAsBinding returns to::Value:
	LiteralValueAsBinding //| DataReferenceAsBinding
;

LiteralValue returns to::LiteralValue:
    comment+=NotQualifier?
    comment+=AssignmentQualifier
    LiteralValueFragment 
;

LiteralValueAsArgument returns to::LiteralValue:
    (comment+=ArticleQualifier | comment+=QuantifiedQualifier)
//  '(literal)'
	LiteralValueFragment
;

LiteralValueAsBinding returns to::LiteralValue:
	LiteralValueFragment    
;

fragment LiteralValueFragment returns to::LiteralValue:
    comment+=Qualifier* 
    (name=Identifier | name=NIdentifier)
    ('containing' 
    	BEGIN
    		content+=DataContent (',' content+=DataContent)* 
		END
    )?
;

DataContent returns to::Content:
    comment+=NotQualifier?
    //(parameter=[Parameter|Identifier] | name=Identifier | name=NumberAsIdentifier)
    comment+=Qualifier*
    (name=Identifier | name=NIdentifier)
    (
		('containing' 
	    	BEGIN
	    		content+=DataContent (',' content+=DataContent)* 
			END
	    )
	    | value=Value
    )?

; 


fragment ValueReferenceFragment returns to::Value:
	comment+=NotQualifier?
   	comment+=ReferenceQualifier
;

LiteralValueReference returns to::LiteralValueReference:
	ValueReferenceFragment
	LiteralValueReferenceFragment
;

LiteralValueReferenceArgument returns to::LiteralValueReference:
	LiteralValueReferenceFragment
;

fragment LiteralValueReferenceFragment returns to::LiteralValueReference:
   	'the' 'value' 'of'
    comment+=Qualifier*
   	content=[to::LiteralValue|Identifier]
;

ContentReference returns to::ContentReference:
	ValueReferenceFragment
	ContentReferenceFragment
;

ContentReferenceAsArgument returns to::ContentReference:
	ContentReferenceFragment
;

fragment ContentReferenceFragment returns to::ContentReference:
   	'the' 'value' 'contained' 'in' 
   	//make more complex: simplify
   	//e.g. 
    //(comment+=ArticleQualifier)?
    //(comment+=Qualifier)*
	//(name=Identifier | name='value')
   	//comment+=ReferenceQualifier
    comment+=Qualifier*
   	content=[to::Content|Identifier]
;

DataReference returns to::DataReference:
    //TODO: is this still needed? causes ambiguity..
    //		-> does not seem to be the case, perhaps for typed?! -> likely not
    //		or simply a leftover..
    //name=Identifier?
	ValueReferenceFragment
	DataReferenceFragment
;

DataReferenceAsArgument returns to::DataReference:
    (
    	comment+=ArticleQualifier 
    	| comment+=QuantifiedQualifier
    )
	'(predefined)'
	DataReferenceFragment    
;

fragment DataReferenceFragment returns to::DataReference:
    comment+=Qualifier*
    //name=Identifier
    //TODO: change to data use?
    //TODO: keep syntax or adapt? 
    //		especially with data element use and literal value use..
    //		may need further consideration
    //		on the other hand no one really used this for the most part..  
    content=StaticDataUse
;

BindingLiteralValueReference returns to::LiteralValueReference:
   	content=[to::LiteralValue|Identifier] | content=[to::LiteralValue|NIdentifier] 
;

BindingContentReference returns to::ContentReference:
   	content=[to::Content|Identifier]
;
    
BindingDataReference returns to::DataReference:
	//TODO: review
   	content=StaticDataUse
;


//# Structured Test Objective Variants

Variants returns to::Variants:
	variants+=Variant+
;

Variant returns to::TestObjectiveVariant:
 	'Variant' name=Identifier
	BEGIN
    	('Objective:' description=EString)? 
    	('Reference:' objectiveURI+=EString (',' objectiveURI+=EString)*)?  
    	('PICS:' picsReference+=FirstPICSReference (picsReference+=PICSReference)*)?
    	('Bindings' 
    		BEGIN
    			bindings+=VariantBinding (',' bindings+=VariantBinding)*
			END
    	)?
	END
;

VariantBinding returns to::VariantBinding:
	VariantBindingValue
	| VariantBindingAttribute 
	| VariantBindingPredefined   
;

VariantBindingValue returns to::VariantBinding:
	'value' value=BindingLiteralValueReference
	comment+=AssignmentQualifier
	boundTo=LiteralOrDataReferenceAsBinding
;

VariantBindingAttribute returns to::VariantBinding:
	'attribute' value=BindingContentReference
	comment+=AssignmentQualifier
	boundTo=LiteralValueAsBinding
;

VariantBindingPredefined returns to::VariantBinding:
	'predefined' 'value' value=BindingDataReference
	comment+=AssignmentQualifier
	boundTo=BindingDataReference
;

//# Test Description
TestPurposeDescription returns tdl::TestDescription:
    //TDPrefixFragment
    //TODO: annotation / comment fragment
    annotation+=TestPurposeDescriptionAnnotation
    //TODO: locally ordered?
	//('TestDescription' | isLocallyOrdered?='Test') 
    name=Identifier
    (LParen formalParameter+=FormalParameter ( ',' formalParameter+=FormalParameter)* RParen )?
    //TODO: Reference, PICS?, Objective reference vs Objective inline (all annotations?) or simply defer to objective
    BEGIN
    	TDObjectiveFragment?
    	'Configuration:' testConfiguration=[tdl::TestConfiguration|Identifier]
    	(behaviourDescription=TPDBehaviourDescription)
	END
;

TPDBehaviourDescription returns tdl::BehaviourDescription:
    //TODO: any behaviour?
    //TODO: annotation to determine syntax?
    behaviour=TPDCompoundBehaviour
;

TPDCompoundBehaviour returns tdl::CompoundBehaviour:
    block=TPDBlock
;

TPDBlock returns tdl::Block:
    //no guard
//    ('[' guard+=LocalExpression (',' guard+=LocalExpression)* ']')?
        (behaviour+=InitialConditionsBehaviour)? 
        (behaviour+=ExpectedBehaviourBehaviour)? 
        (behaviour+=FinalConditionsBehaviour)? 
;

InitialConditionsBehaviour returns tdl::CompoundBehaviour:
    annotation+=InitialConditionsAnnotation
	//TODO: with annotation?
	'with' block=AtomicBehaviourBlock
;

ExpectedBehaviourBehaviour returns tdl::CompoundBehaviour:
    annotation+=ExpectedBehaviourAnnotation
    'ensure' 'that'
    BEGIN
    	block=WhenThenBlock
	END
	//TODO: single then clause
;

FinalConditionsBehaviour returns tdl::CompoundBehaviour:
    annotation+=FinalConditionsAnnotation
    'with' block=AtomicBehaviourBlock
;

WhenThenBlock returns tdl::Block:
    (behaviour+=WhenBehaviour) 
    (behaviour+=ThenBehaviour) 
;

WhenBehaviour returns tdl::CompoundBehaviour:
    annotation+=WhenAnnotation
    block=AtomicBehaviourBlock
;

ThenBehaviour returns tdl::CompoundBehaviour:
    annotation+=ThenAnnotation
    block=AtomicBehaviourBlock
;

AtomicBehaviourBlock returns tdl::Block:
    //no guard
//    ('[' guard+=LocalExpression (',' guard+=LocalExpression)* ']')?
        {tdl::Block} 
        BEGIN
        	(behaviour+=TPDAtomicBehaviour)+
        END
;

//TODO: restrict to atomic?
TPDAtomicBehaviour returns tdl::Behaviour:
    TPDMessage
    //procedure call
    //action
    //TODO: other behaviours?
;

//TODO: Response? / Receive?
TPDMessage returns tdl::Message:
	//add qualifier?
	//TODO: only after first?
    comment+=AndOrQualifier?
    //only one qualifier?
    comment+=ArticleQualifier?
	sourceGate=[tdl::GateReference|GRIdentifier]
	('sends' | (isTrigger?='triggers')) 
	//TODO: use TDLan notation?
	//DONE: expand to more data uses?
	argument=DataUse
	'to' 
	target+=TPDTargetMessage ( "," target+=TPDTargetMessage)* 
;

TPDTargetMessage returns tdl::Target:
    //NOTE: No name, annotations or comments
    comment+=ArticleQualifier?
    targetGate=[tdl::GateReference|GRIdentifier]
    (valueAssignment+=ValueAssignmentMessage)?
;





//## Auxiliary
//TODO: redistribute where applicable

//## Element: Abstract 
fragment InitialConditionsFragment returns tdl::Element:
	annotation+=InitialConditionsAnnotation 
;

fragment ExpectedBehaviourFragment returns tdl::Element:
	annotation+=ExpectedBehaviourAnnotation 
;

fragment FinalConditionsFragment returns tdl::Element:
	annotation+=FinalConditionsAnnotation 
;

fragment ElementAndOrPrefix returns tdl::Element:
	comment+=AndOrQualifier
;

//## ValueConverter Rules (Pseudo-terminals)

Assignments returns ecore::EString:
	'indicating' 'value' 
	| 'set' 'to'
;

References returns ecore::EString:
    'corresponding' 'to' 
    | 'derived' 'from' 
    | 'carrying'  
    | 'contained' 'in' 
    | 'associated' 'with'
;


InitialBlockName returns ecore::EString:
    'Initial' 'conditions'
;

ExpectedBlockName returns ecore::EString:
    'Expected' 'behaviour'
;

FinalBlockName returns ecore::EString:
    'Final' 'conditions'
;

TestPurposeDescriptionName returns ecore::EString:
    'Test' 'Purpose' 'Description'
;