blob: 14592ad0341ac1d0504c92403ef9f431bea15b52 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 protos software gmbh (http://www.protos.de).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* CONTRIBUTORS:
* Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
* Eyrak Paen
*
******************************************************************************/
/**
* @author Henrik Rentz-Reichert and Thomas Schuetz
*
* Xtext Grammar for ROOM models
* this grammar is the base for the ROOM tool eTrice
*
*/
grammar org.eclipse.etrice.core.Room with org.eclipse.etrice.core.fsm.FSM
import "http://www.eclipse.org/etrice/core/fsm/FSM"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate room "http://www.eclipse.org/etrice/Room"
RoomModel :
'RoomModel' name=FQN (docu=Documentation)? '{'
(imports+=Import)*
(
primitiveTypes+=PrimitiveType |
enumerationTypes+=EnumerationType |
externalTypes+=ExternalType |
dataClasses+=DataClass |
protocolClasses+=GeneralProtocolClass |
actorClasses+=ActorClass |
subSystemClasses+=SubSystemClass |
systems+=LogicalSystem |
annotationTypes+=AnnotationType
)*
'}'
;
RoomClass: DataType | GeneralProtocolClass | StructureClass;
StructureClass: ActorContainerClass | LogicalSystem;
ActorContainerClass: ActorClass | SubSystemClass;
// **************************************************************
// data class
VarDecl:
name=ID ':' refType=RefableType;
RefableType: type=[DataType|FQN] (ref?='ref')?;
DataType: PrimitiveType | EnumerationType | ComplexType;
ComplexType: DataClass | ExternalType;
PrimitiveType: 'PrimitiveType' name=ID ':' type=LiteralType '->' targetName=STRING ('(' castName=FQN ')')? 'default' defaultValueLiteral=STRING (docu=Documentation)?;
EnumerationType:
'Enumeration' name=ID (docu=Documentation)? ('of' primitiveType=[PrimitiveType|FQN])? '{'
(literals+=EnumLiteral (',' literals+=EnumLiteral)*)?
'}'
;
EnumLiteral:
name=ID ('=' literal=IntLiteral)?
;
ExternalType: 'ExternalType' name=ID '->' targetName=STRING ('default' defaultValueLiteral=STRING)? (docu=Documentation)?;
// TODOHRR: define detail level language?
DataClass:
'DataClass' name=ID (docu=Documentation)? ('extends' base=[DataClass|FQN])? '{'
annotations+=Annotation*
('usercode1' userCode1=DetailCode)?
('usercode2' userCode2=DetailCode)?
('usercode3' userCode3=DetailCode)?
(
operations+=StandardOperation |
structors+=ClassStructor |
attributes+=Attribute
)*
'}';
Attribute:
'Attribute' name=ID ('[' size=INT ']')? ':' type=RefableType ('=' defaultValueLiteral=STRING)? (docu=Documentation)?;
Operation: StandardOperation | PortOperation;
StandardOperation:
(override?='override')? 'Operation' name=ID '(' (arguments+=VarDecl (',' arguments+=VarDecl)*)? ')' (':' ('void' | (returnType=RefableType)))?
(docu=Documentation)?
detailCode=DetailCode
;
PortOperation:
'Operation' name=ID '(' (arguments+=VarDecl (',' arguments+=VarDecl)*)? ')' ( (':' ('void' | (returnType=RefableType))) | ('sends' sendsMsg=[Message|ID]) )?
(docu=Documentation)?
detailCode=DetailCode
;
ClassStructor:
name=('ctor'|'dtor') detailCode=DetailCode
;
// **************************************************************
// protocol class
enum CommunicationType:
EVENT_DRIVEN='eventdriven' |
DATA_DRIVEN='datadriven' |
SYNCHRONOUS='sync'
;
GeneralProtocolClass: ProtocolClass | CompoundProtocolClass;
ProtocolClass:
(commType=CommunicationType)?
'ProtocolClass' name=ID (docu=Documentation)? ('extends' base=[ProtocolClass|FQN])? '{'
annotations+=Annotation*
('usercode1' userCode1=DetailCode)?
('usercode2' userCode2=DetailCode)?
('usercode3' userCode3=DetailCode)?
('incoming' '{' incomingMessages+=Message* '}')?
('outgoing' '{' outgoingMessages+=Message* '}')?
('regular' 'PortClass' regular=PortClass)?
('conjugated' 'PortClass' conjugated=PortClass)?
(semantics=ProtocolSemantics)?
'}';
CompoundProtocolClass:
'CompoundProtocolClass' name=ID (docu=Documentation)? '{'
annotations+=Annotation*
subProtocols+=SubProtocol*
'}'
;
SubProtocol: 'SubProtocol' name=ID ':' protocol=[GeneralProtocolClass|FQN];
Message:
(priv?='private')? 'Message' name=ID '(' (data=VarDecl)? ')'
(docu=Documentation)?;
PortClass:
{PortClass}
'{'
('usercode' userCode=DetailCode)?
(
msgHandlers+=MessageHandler |
operations+=PortOperation |
attributes+=Attribute
)*
'}';
MessageHandler: InMessageHandler|OutMessageHandler;
InMessageHandler:
'handle' 'incoming' msg=[Message|ID]
detailCode=DetailCode
;
OutMessageHandler:
'handle' 'outgoing' msg=[Message|ID]
detailCode=DetailCode
;
// **************************************************************
// actor class
ModelComponent: ActorClass;
// some notes on ports
//
// in ROOM ports can be contained in the structure and/or the interface
// p in s ==> internal end port
// p in i ==> relay port
// p in i and p in s ==> external end port
// since double containment is not supported we decided to define external ports as reference to interface ports
ActorClass:
(abstract?='abstract'? & commType=ComponentCommunicationType?)
'ActorClass' name=ID (docu=Documentation)? ('extends' base=[ActorClass|FQN])? '{'
annotations+=Annotation*
('Interface' '{'
(
serviceProvisionPoints+=SPP |
interfacePorts+=Port
)*
'}')?
('Structure' (structureDocu=Documentation)? '{'
('usercode1' userCode1=DetailCode)?
('usercode2' userCode2=DetailCode)?
('usercode3' userCode3=DetailCode)?
(
// workaround: reverse the order for serializer
connections+=LayerConnection |
bindings+=Binding |
serviceImplementations+=ServiceImplementation |
attributes+=Attribute |
actorRefs+=ActorRef |
serviceAccessPoints+=SAP |
internalPorts+=Port |
externalPorts+=ExternalPort
)*
'}')?
('Behavior' (behaviorDocu=Documentation)? '{'
behaviorAnnotations+=Annotation*
(
operations+=StandardOperation |
structors+=ClassStructor
)*
(stateMachine=StateMachine)?
'}')?
'}';
InterfaceItem: Port | SAP | SPP;
Port:
(conjugated?='conjugated')? 'Port' name=ID (multiplicity=MULTIPLICITY)? ':' protocol=[GeneralProtocolClass|FQN] (docu=Documentation)?;
ExternalPort:
'external' 'Port' interfacePort=[Port|ID] ;
SAP:
'SAP' name=ID ':' protocol=[ProtocolClass|FQN] ;
SPP:
'SPP' name=ID ':' protocol=[ProtocolClass|FQN] ;
ServiceImplementation:
'ServiceImplementation' 'of' spp=[SPP|ID];
LogicalSystem:
'LogicalSystem' name=ID (docu=Documentation)? '{'
annotations+=Annotation*
(
connections+=LayerConnection |
bindings+=Binding |
subSystems+=SubSystemRef
)*
'}';
ActorContainerRef: SubSystemRef | ActorRef;
SubSystemRef:
'SubSystemRef' name=ID ':' type=[SubSystemClass|FQN] (docu=Documentation)?;
SubSystemClass:
'SubSystemClass' name=ID (docu=Documentation)? '{'
annotations+=Annotation*
('usercode1' userCode1=DetailCode)?
('usercode2' userCode2=DetailCode)?
('usercode3' userCode3=DetailCode)?
(
// workaround: reverse the order for serializer
actorInstanceMappings+=ActorInstanceMapping |
threads+=LogicalThread |
connections+=LayerConnection |
bindings+=Binding |
actorRefs+=ActorRef |
serviceProvisionPoints+=SPP |
relayPorts+=Port
)*
'}';
LogicalThread:
'LogicalThread' name=ID
;
ActorInstanceMapping:
'ActorInstanceMapping' path=RefPath '->' thread=[LogicalThread|ID] ('{'
actorInstanceMappings+=ActorInstanceMapping*
'}')?
;
RefPath:
refs+=RefSegment ('/' refs+=RefSegment)*;
RefSegment:
ref=ID (':' idx=INT)?
;
Binding:
'Binding' endpoint1=BindingEndPoint 'and' endpoint2=BindingEndPoint ;
BindingEndPoint:
(actorRef=[ActorContainerRef|ID]'.')? port=[Port|ID] ('sub' sub=[SubProtocol|ID])?;
LayerConnection:
'LayerConnection' from=SAPoint 'satisfied_by' to=SPPoint
;
SAPoint: RefSAPoint | RelaySAPoint;
RefSAPoint:
// satisfies a sub actor
'ref' ref=[ActorContainerRef|ID];
RelaySAPoint:
// relays from own interface
'relay_sap' relay=[SPP|ID];
SPPoint:
ref=[ActorContainerRef|ID] '.' service=[SPP|ID]
;
ActorRef:
(refType=ReferenceType)? 'ActorRef' name=ID (multiplicity=MULTIPLICITY)? ':' type=[ActorClass|FQN] (docu=Documentation)?;
enum ReferenceType:
FIXED='fixed' |
OPTIONAL='optional'
// IMPORTED='imported'
;
// **************************************************************
// concrete message and interface item for state machines
//AbstractMessage: Message;
AbstractInterfaceItem: InterfaceItem;
// **************************************************************
// general
// the following is a data type rule (accompanied by a value converter) and must not be a terminal rule
// (because then the lexer already would find this in places where it is not expected, e.g. in an Attribute)
MULTIPLICITY returns ecore::EInt : '[' ('*'|INT) ']';
AnnotationTargetType:
'DataClass' |
'ActorClass' |
'ActorBehavior' |
'ProtocolClass' |
'CompoundProtocolClass' |
'SubSystemClass' |
'LogicalSystem'
;
enum RoomAnnotationTargetEnum:
DATA_CLASS='DataClass' |
ACTOR_CLASS='ActorClass' |
ACTOR_BEHAVIOR='ActorBehavior' |
PROTOCOL_CLASS='ProtocolClass' |
COMPOUND_PROTOCOL_CLASS='CompoundProtocolClass' |
SUBSYSTEM_CLASS='SubSystemClass' |
LOGICAL_SYSTEM_CLASS='LogicalSystem'
;