BNF for CoCo3.jj

NON-TERMINALS



compilationUnit
compilationUnit ::= ( ( propertySet | componentType | dataTypeList ) <EOF> )



propertySet
propertySet ::= ( componentPropertySet | portPropertySet )



componentPropertySet
componentPropertySet ::= ( <COMPONENT> <PROPERTIES> identifier <L_BRACE> abstractPropertyList <R_BRACE> )



portPropertySet
portPropertySet ::= ( <PORT> <PROPERTIES> identifier <L_BRACE> abstractPropertyList <R_BRACE> )

/*

	Components are stateful entities that are responsible
	for computations.

*/
// (file suffix *.cm)
componentType
componentType ::= ( abstractComponent | component )



abstractComponent
abstractComponent ::= ( <ABSTRACT> <COMPONENT> identifier ( <EXTENDS> identifierList )? ( <HAS> propertySetReferenceList )? abstractComponentBody ( <SEMICOLON> )? )



component
component ::= ( ( ( <ACTIVE> | <EVENT> ) )? <COMPONENT> identifier ( <IS> interfaceIdentifierList )? ( <HAS> propertySetReferenceList )? componentBody ( <SEMICOLON> )? )

/*
 connectors are responsible for data transfer
 between components.
*/
connector
connector ::= ( <CONNECTOR> identifier <L_PAREN> portAccessList <R_PAREN> ( <HAS> propertySetReferenceList )? ( ( connectorBody ) )? ( <SEMICOLON> )? )

/*	Defines data types of dataTypedata that is
	transmitted between components

	dataType specification --> spec of the structure of
  dataTypes that are transferred between components
 */
dataTypeList
dataTypeList ::= ( dataType ( ( dataType ) )* )

/*
 *
 * Data types in coco are more or less the equivalent of C++ structs (in contrast to C++ structs)
 * data types can not declare methods and only support single inheritance
 * Data types can be inherited from another data type. The only restriction is, that this base
 * data type must also be a user defined data type. Thus it is not possible to inherit directly
 * from coco base types (like int or float)
 *
 */
dataType
dataType ::= ( <TYPE> identifier ( ( ( <EXTENDS> ( ( identifier <L_BRACE> ( fieldList )? <R_BRACE> ( <SEMICOLON> )? ) | ( ( baseTypeIdentifier <SEMICOLON> ) ) ) ) | ( <L_BRACE> ( fieldList )? <R_BRACE> ( <SEMICOLON> )? ) ) ) )



abstractComponentBody
abstractComponentBody ::= ( <L_BRACE> ( ( ( port | abstractProperty | role | instance | connector ) )* ) <R_BRACE> )



componentBody
componentBody ::= ( <L_BRACE> ( ( ( port | property | instance | connector ) )* ) <R_BRACE> )

/*
	Describes all component instances that are to be composed within a composite component

 */
instanceList
instanceList ::= ( instance ( instance )* )



instance
instance ::= ( componentTypeIdentifier identifier ( <IS> roleIdentifier )? <SEMICOLON> )

/*
	Describes roles for component instances that are to be composed within a composite component
	Roles can only appear in an abstract component. When a component inherits from an abstract component,
	all roles must be assigned a certain instance. The type of this instance must be a subtype of
	the type declared for this role.
 */
roleList
roleList ::= ( role ( role )* )



role
role ::= ( <ROLE> componentTypeIdentifier identifier <SEMICOLON> )

/*
  *	ports are in, out or inout ports, they have a data type
  * and the are either optional (may be unbound in the final system)
  * or mandatory (must be bound, this is default)
  */
portList
portList ::= ( port ( port )* )

/*
 * A port can currently only be a data port. However, this might be loosened in the future
 * The grammar also allows for invocation or handler ports. In contrast to data ports,
 * handler/invocation ports have a formal parameter list.
 */
port
port ::= ( ( modifiers )? ( <IN> | <OUT> | <INOUT> ) ( dataTypeIdentifier ) ( ( identifier ( signature )? ) ( <HAS> propertySetReferenceList )? ( portBody | <SEMICOLON> ) ) )



modifiers
modifiers ::= ( <MANDATORY> | <OPTIONAL> )

/*
 * formal parameters of a handler (or, if existing in the model) invocation port
 */
signature
signature ::= ( <L_PAREN> ( invocationParamList )? <R_PAREN> )



portBody
portBody ::= ( ( <L_BRACE> ( propertyList )? <R_BRACE> ( <SEMICOLON> )? ) )



portAccessList
portAccessList ::= ( portAccess ( <COMMA> portAccess )* )



portAccess
portAccess ::= ( designator )



invocationParamList
invocationParamList ::= ( invocationParam ( <COMMA> invocationParam )* )



invocationParam
invocationParam ::= ( dataTypeIdentifier identifier )



fieldList
fieldList ::= ( field <SEMICOLON> ( ( field ) <SEMICOLON> )* )



field
field ::= ( dataTypeIdentifier identifier )



dataTypeIdentifierList
dataTypeIdentifierList ::= ( dataTypeIdentifier ( <COMMA> dataTypeIdentifier )* )



dataTypeIdentifier
dataTypeIdentifier ::= ( baseTypeIdentifier | userTypeIdentifier )



propertySetReferenceList
propertySetReferenceList ::= ( propertySetReference ( <COMMA> propertySetReference )* )



propertySetReference
propertySetReference ::= ( <ID> dummy )



userTypeIdentifier
userTypeIdentifier ::= ( ( <EXTERN> )? identifier ( ( <L_BRACKET> <DECIMALINT> <R_BRACKET> ) )* )

/*
 * Coco provides a set of primitive base types. This set basically resembles more or less
 * the base types known from Java or C++.
 * Maybe one has to change the grammar here since there is actually a difference between
 * the actual base (primitive) type and its usage as an array type. The same applies for user
 * types. Atleast the name should be changed (to something like TypeReference) to reflect
 * the real meaning of this construct. (TG)
 */
baseTypeIdentifier
baseTypeIdentifier ::= ( ( <INT> | <BOOL> | <CHAR> | <FLOAT> | <DOUBLE> | <SHORT> | <LONG> | <BYTE> | <VOID> ) ( ( <L_BRACKET> ( <DECIMALINT> )? <R_BRACKET> ) )* )



connectorBody
connectorBody ::= <L_BRACE> ( propertyList )? <R_BRACE>

/*
 	properties of a component have a type (int, float, string, or enum)
 	and may have an initial value. Mandatory properties (the default)
 	must be bound at least in the final system. Optional properties may
 	not be bound. The distinction between abstract and 'normal' properties
 	is artificial (it makes it easier to deal with those two kinds of properties
 	differently afterwards. Abstract properties can only appear within an abstract
 	component or within a property set definition while normal properties can
 	appear within components, ports, connectors
 */
abstractPropertyList
abstractPropertyList ::= ( abstractProperty ( abstractProperty )* )



propertyList
propertyList ::= ( property ( property )* )



property
property ::= ( <OPTIONAL> | <MANDATORY> )? <PROPERTY> ( propertyIdentifier ( <ASSGMNT> constExpression )? ) <SEMICOLON>



abstractProperty
abstractProperty ::= ( <OPTIONAL> | <MANDATORY> )? <PROPERTY> ( propertyIdentifier ( <ASSGMNT> constExpression )? ) <SEMICOLON>



constExpressionList
constExpressionList ::= ( constExpression ( <COMMA> constExpression )* )



boolLiteral
boolLiteral ::= ( <TRUE> | <FALSE> )



constExpression
constExpression ::= ( numericLiteral | charLiteral | stringLiteral | boolLiteral | mappingLiteral )



mappingLiteral
mappingLiteral ::= <L_BRACE> ( <L_PAREN> constExpression <COMMA> constExpression <R_PAREN> ) ( <COMMA> <L_PAREN> constExpression <COMMA> constExpression <R_PAREN> )* <R_BRACE>



numericLiteral
numericLiteral ::= <OCTALINT>
| <DECIMALINT>
| <HEXADECIMALINT>
| <FLOATONE>
| <FLOATTWO>



charLiteral
charLiteral ::= <CHARACTER>



stringLiteral
stringLiteral ::= <STRING>



identifierList
identifierList ::= identifier ( <COMMA> identifier )*



interfaceIdentifierList
interfaceIdentifierList ::= interfaceIdentifier ( <COMMA> interfaceIdentifier )*



interfaceIdentifier
interfaceIdentifier ::= ( <ID> dummy )



propertyIdentifier
propertyIdentifier ::= ( designator )



componentTypeIdentifier
componentTypeIdentifier ::= ( <ID> dummy )



roleIdentifier
roleIdentifier ::= ( <ID> dummy )



designator
designator ::= identifier ( <DOT> identifier )*



identifier
identifier ::= ( <ID> dummy )

/** Stabilizies the parser by skipping to the specified token.
   * The token itself is removed from the stream.
   * THIS IS NOT A GRAMMAR PRODUCTION
   * Side-effects: increases the numErros variable by one.
   *  @param kind the token to look for
   *  @param e the originally catched exception describing the actual parse problem
   */
error_skipto
error_skipto ::= java code

/** Stabilizies the parser by skipping to one of the specified tokens.
   * When an appropriate token is found it is pushed back onto the stream.
   * before the method returns. If no token is found the method simply
   * re-throws the original exception.
   * THIS IS NOT A GRAMMAR PRODUCTION
   * Side-effects: increases the numErros variable by one.
   *  @param kind[] the array of tokens to look for
   *  @param e the originally catched exception describing the actual parse problem
   */
error_skipto_ex
error_skipto_ex ::= java code



dummy
dummy ::= java code