// Copyright (c) 2008-2010 by Kavanagh Consultancy Limited. All rights reserved. ActionLanguage : // Syntax Rules code := statementBlock statementBlock := { statement ';' }* statement := ifBlock | switchBlock | forEachBlock | whileBlock | breakStatement | continueStatement | createObjectStatement | deleteObjectStatement | migrateStatement | selectFromStatement | relateStatement | unrelateStatement | selectRelatedByStatement | generateStatement | createEventStatement | deleteEventStatement | invokeStatement | returnStatement | assignStatement | declareStatement // Control Structures ifBlock := IF '(' booleanExpression ')' statementBlock { ELIF '(' booleanExpression ')' statementBlock }* [ ELSE statementBlock ] END IF switchBlock := SWITCH '(' enumeratedExpression ')' { CASE legalValue { ',' legalValue }* ':' statementBlock }+ END SWITCH forEachBlock := FOR EACH variable IN ( variableOrInputParameter | '(' expression ')' ) statementBlock END FOR whileBlock := WHILE '(' booleanExpression ')' statementBlock END WHILE [ numericExpression ] breakStatement := { BREAK }+ continueStatement := { BREAK }* CONTINUE // Objects createObjectStatement := CREATE OBJECT ( INSTANCE [ variableOrSelf ] OF objectSpecification | INSTANCES [ variableOrSelf '=' ] objectSpecification { ',' [ variableOrSelf '=' ] objectSpecification }* ) objectSpecification := objectReference [ '(' [ attribute ':' expression { ',' attribute ':' expression }* [ ',' CURRENT_STATE ':' enumeratedExpression ] | CURRENT_STATE ':' enumeratedExpression ] ')' ] deleteObjectStatement := DELETE OBJECT ( INSTANCE | INSTANCES ) objectInstanceExpression migrateStatement := MIGRATE OBJECT INSTANCES objectInstanceExpression TO [ variable '=' ] objectSpecification { ',' [ variable '=' ] objectSpecification }* selectFromStatement := SELECT ( ANY | MANY ) variable FROM ( INSTANCES OF objectReference | objectInstanceExpression ) [ whereClause ] [ orderedByClause ] whereClause := WHERE booleanExpression // Relationships relateStatement := RELATE objectInstanceExpression TO objectInstanceExpression ACROSS relationshipSpecification [ USING objectInstanceExpression ] relationshipSpecification := relationshipID [ '.' verbPhrase ] | verbPhrase unrelateStatement := UNRELATE objectInstanceExpression FROM objectInstanceExpression ACROSS relationshipSpecification [ USING objectInstanceExpression ] selectRelatedByStatement := SELECT ( ONE | ANY | MANY ) variable RELATED BY instanceChain [ whereClause ] [ orderedByClause ] instanceChain := objectInstanceExpression { "->" objectReference [ '[' relationshipSpecification ']' ] }+ orderedByClause := [ REVERSE ] ORDERED BY ( [ REVERSE ] attribute { ',' [ REVERSE ] attribute }* | relationshipSpecification ) // Events // Can use event instance or complete transfer vector expression in generate statement generateStatement := GENERATE ( eventSpecification | eventInstanceExpression ) [ delayClause ] eventSpecification := ( eventLabel [ ':' eventMeaning ] | eventMeaning ) [ '(' [ eventDataItem ':' expression { ',' eventDataItem ':' expression }* ] ')' ] ( TO ( objectReference CREATOR | ( objectReference | relationshipReference ) ASSIGNER [ USING objectInstanceExpression ] | objectReference CLASS | terminatorReference | objectInstanceExpression ) | FROM eventInstanceExpression ) delayClause := AFTER numericExpression // Delay in seconds createEventStatement := CREATE EVENT INSTANCE variable OF eventSpecification deleteEventStatement := DELETE EVENT INSTANCE eventInstanceExpression // Operations // Can only invoke bridging processes from actions and simple processes // Can only invoke synchronous services from bridge mappings and domain observers invokeStatement := ( [ TRANSFORM [ assignTarget | invokeTarget ] ] objectReference "::" stateModelProcess | [ BRIDGE [ assignTarget | invokeTarget ] ] terminatorReference "::" bridgingProcess | [ domainQualifier ] "::" function | variableOrSelf '.' stateModelProcess // State model or polymorphic process | variable '.' RETURN ) // Return coordinate or partial transfer vector '(' [ inputParameter ':' expression { ',' inputParameter ':' expression }* ] ')' invokeTarget := outputParameter ':' variable { ',' outputParameter ':' variable }* '=' returnStatement := RETURN [ expression | outputParameter ':' expression { ',' outputParameter ':' expression }* ] // Variables assignStatement := [ ASSIGN ] ( assignTarget expression | invokeTarget invokeExpression ) assignTarget := ( variable ! '.' | variableOrSelf '.' attribute ) '=' declareStatement := DECLARE variable AS [ [ EMPTY OR ] ( ONE | MANY ) ] dataType [ '=' expression ] // We would like to use the following rule but can't since predefined type names are fuzzy matched // dataType := ( "Boolean" | "String" | "Integer" | "Real" | "Date" | "Timestamp" | "Arbitrary_ID" ) [ '<' '>' ] // | "Subtype" '<' relationshipReference '>' // | "State" '<' stateModelReference '>' // | "Object_Instance" '<' objectReference '>' // | "Event_Instance" '<' eventReference '>' // | "Return_Coordinate" '<' terminatorReference "::" synchronousService '>' // | "Transfer_Vector" '<' [ terminatorReference '.' positiveInteger ] '>' // | externalName dataType := externalName [ '<' [ relationshipReference | stateModelReference | objectReference | eventReference | terminatorReference ( "::" synchronousService | '.' positiveInteger ) ] '>' ] // We would like to use the following rule but can't since predefined type names are fuzzy matched // enumeratedType := "Subtype" '<' relationshipReference '>' // | "State" '<' stateModelReference '>' // | externalName enumeratedType := externalName [ '<' ( relationshipReference | stateModelReference ) '>' ] // Expressions expression := logicalOrExpression booleanExpression := logicalOrExpression enumeratedExpression := term numericExpression := addExpression objectInstanceExpression := term eventInstanceExpression := term logicalOrExpression := logicalAndExpression { OR logicalAndExpression }* logicalAndExpression := comparisonExpression { AND comparisonExpression }* comparisonExpression := addExpression [ ( "==" | "!=" | '<' | "<=" | '>' | ">=" ) addExpression ] addExpression := multiplyExpression { ( '+' | '-' ) multiplyExpression }* multiplyExpression := unaryExpression { ( '*' | '/' | '%' ) unaryExpression }* unaryExpression := [ NOT | '+' | '-' | EMPTY | NOT_EMPTY | CARDINALITY ] term term := readValue | invokeExpression | '(' expression ')' readValue := literalValue | variableAccess | attributeAccess | eventDataItemAccess | parameterAccess | '?' literalValue := booleanLiteral | enumeratedLiteral | stringLiteral | integerLiteral | realLiteral booleanLiteral := TRUE | FALSE enumeratedLiteral := enumeratedType "::" legalValue ! '(' variableAccess := variableSelfOrSelected ! '.' variableSelfOrSelected := variableOrSelf | SELECTED variableOrSelf := variable | SELF // We don't allow nested expressions below since attribute access is a read value attributeAccess := variableSelfOrSelected '.' ( attribute ! '(' | CURRENT_SUBTYPE [ '<' relationshipID '>' ] | CURRENT_STATE [ '<' stateModelLabelPrefix '>' ] ) | CURRENT_STATE '<' stateModelReference '>' | CURRENT_TIME eventDataItemAccess := RCVD_EVT '.' eventDataItem parameterAccess := PARAM '.' inputParameter invokeExpression := ( [ TRANSFORM ] objectReference "::" stateModelProcess | [ BRIDGE ] terminatorReference "::" bridgingProcess | [ domainQualifier ] "::" function | variableSelfOrSelected '.' stateModelProcess ) '(' [ inputParameter ':' expression { ',' inputParameter ':' expression }* ] ')' // External References domainQualifier := externalName '@' // Domain qualifiers are only used in bridge mappings objectReference := [ domainQualifier ] externalName // Object name OR object key letters attribute := externalName relationshipReference := [ domainQualifier ] relationshipID verbPhrase := externalName // Verb phrase OR role legalValue := externalName stateModelReference := [ domainQualifier ] stateModelLabelPrefix stateModelLabelPrefix := keyLetters [ '-' assignerSuffix ] | relationshipID '-' assignerSuffix terminatorReference := [ domainQualifier ] externalName // Terminator name OR terminator key letters eventReference := [ domainQualifier ] eventLabel eventLabel := simpleEventLabel | keyLetters '-' assignerEventSuffix | relationshipID '-' ( assignerEventSuffix | polymorphicEventSuffix ) eventMeaning := externalName eventDataItem := externalName function := externalName stateModelProcess := externalName bridgingProcess := externalName synchronousService := externalName inputParameter := externalName outputParameter := externalName variable := externalName variableOrInputParameter := externalName ActionLanguage :: // Lexical Rules input := { $javaWhitespace | comment | token }* comment := "//" { ! '\n' $anyCharacter }* $endOfLine token := name | unconstrainedName | stringLiteral | integerLiteral | realLiteral | separatorOrOperator name ::= nameStart { namePart }* nameStart := $javaIdentifierStart | '#' namePart := $javaIdentifierPart | '#' unconstrainedName ::= '\'' { ! '\n' ! '\'' ! '\\' $anyCharacter | javaEscapeSequence }+ '\'' javaEscapeSequence := '\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '"' | '\'' | '\\' | [ '0'..'3' ] '0'..'7' [ '0'..'7' ] | 'u' hexDigit hexDigit hexDigit hexDigit ) hexDigit := '0'..'9' | 'a'..'f' | 'A'..'F' stringLiteral ::= '"' { ! '\n' ! '"' ! '\\' $anyCharacter | javaEscapeSequence }* '"' integerLiteral ::= [ '-' ] { '0'..'9' }+ ! '.' realLiteral ::= [ '-' ] { '0'..'9' }+ '.' { '0'..'9' }+ separatorOrOperator ::= "!=" | "->" | "::" | "<=" | "==" | ">=" | '%' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' | ']' // Special Name Tokens externalName ::= unconstrainedName | constrainedName // Fuzzy matched constrainedName ::= name && ! keyword && ! relationshipID keyword := ACROSS | AFTER | AND | ANY | AS | ASSIGN | ASSIGNER | BREAK | BRIDGE | BY | CARDINALITY | CASE | CLASS | CONTINUE | CREATE | CREATOR | CURRENT_STATE | CURRENT_SUBTYPE | CURRENT_TIME | DECLARE | DELETE | EACH | ELIF | ELSE | EMPTY | END | EVENT | FALSE | FOR | FROM | GENERATE | IF | IN | INSTANCE | INSTANCES | MANY | MIGRATE | NOT | NOT_EMPTY | OBJECT | OF | ONE | OR | ORDERED | PARAM | RCVD_EVT | RELATE | RELATED | RETURN | REVERSE | SELECT | SELECTED | SELF | SWITCH | TO | TRANSFORM | TRUE | UNRELATE | USING | WHERE | WHILE ACROSS ::= ( "across" | "ACROSS" | "Across" ) ! namePart AFTER ::= ( "after" | "AFTER" | "After" ) ! namePart AND ::= ( "and" | "AND" | "And" ) ! namePart ANY ::= ( "any" | "ANY" | "Any" ) ! namePart AS ::= ( "as" | "AS" | "As" ) ! namePart ASSIGN ::= ( "assign" | "ASSIGN" | "Assign" ) ! namePart ASSIGNER ::= ( "assigner" | "ASSIGNER" | "Assigner" ) ! namePart BREAK ::= ( "break" | "BREAK" | "Break" ) ! namePart BRIDGE ::= ( "bridge" | "BRIDGE" | "Bridge" ) ! namePart BY ::= ( "by" | "BY" | "By" ) ! namePart CARDINALITY ::= ( "cardinality" | "CARDINALITY" | "Cardinality" ) ! namePart CASE ::= ( "case" | "CASE" | "Case" ) ! namePart CLASS ::= ( "class" | "CLASS" | "Class" ) ! namePart CONTINUE ::= ( "continue" | "CONTINUE" | "Continue" ) ! namePart CREATE ::= ( "create" | "CREATE" | "Create" ) ! namePart CREATOR ::= ( "creator" | "CREATOR" | "Creator" ) ! namePart CURRENT_STATE ::= ( "current_state" | "CURRENT_STATE" | "Current_state" ) ! namePart CURRENT_SUBTYPE ::= ( "current_subtype" | "CURRENT_SUBTYPE" | "Current_subtype" ) ! namePart CURRENT_TIME ::= ( "current_time" | "CURRENT_TIME" | "Current_time" ) ! namePart DECLARE ::= ( "declare" | "DECLARE" | "Declare" ) ! namePart DELETE ::= ( "delete" | "DELETE" | "Delete" ) ! namePart EACH ::= ( "each" | "EACH" | "Each" ) ! namePart ELIF ::= ( "elif" | "ELIF" | "Elif" ) ! namePart ELSE ::= ( "else" | "ELSE" | "Else" ) ! namePart EMPTY ::= ( "empty" | "EMPTY" | "Empty" ) ! namePart END ::= ( "end" | "END" | "End" ) ! namePart EVENT ::= ( "event" | "EVENT" | "Event" ) ! namePart FALSE ::= ( "false" | "FALSE" | "False" ) ! namePart FOR ::= ( "for" | "FOR" | "For" ) ! namePart FROM ::= ( "from" | "FROM" | "From" ) ! namePart GENERATE ::= ( "generate" | "GENERATE" | "Generate" ) ! namePart IF ::= ( "if" | "IF" | "If" ) ! namePart IN ::= ( "in" | "IN" | "In" ) ! namePart INSTANCE ::= ( "instance" | "INSTANCE" | "Instance" ) ! namePart INSTANCES ::= ( "instances" | "INSTANCES" | "Instances" ) ! namePart MANY ::= ( "many" | "MANY" | "Many" ) ! namePart MIGRATE ::= ( "migrate" | "MIGRATE" | "Migrate" ) ! namePart NOT ::= ( "not" | "NOT" | "Not" ) ! namePart NOT_EMPTY ::= ( "not_empty" | "NOT_EMPTY" | "Not_empty" ) ! namePart OBJECT ::= ( "object" | "OBJECT" | "Object" ) ! namePart OF ::= ( "of" | "OF" | "Of" ) ! namePart ONE ::= ( "one" | "ONE" | "One" ) ! namePart OR ::= ( "or" | "OR" | "Or" ) ! namePart ORDERED ::= ( "ordered" | "ORDERED" | "Ordered" ) ! namePart PARAM ::= ( "param" | "PARAM" | "Param" ) ! namePart RCVD_EVT ::= ( "rcvd_evt" | "RCVD_EVT" | "Rcvd_evt" ) ! namePart RELATE ::= ( "relate" | "RELATE" | "Relate" ) ! namePart RELATED ::= ( "related" | "RELATED" | "Related" ) ! namePart RETURN ::= ( "return" | "RETURN" | "Return" ) ! namePart REVERSE ::= ( "reverse" | "REVERSE" | "Reverse" ) ! namePart SELECT ::= ( "select" | "SELECT" | "Select" ) ! namePart SELECTED ::= ( "selected" | "SELECTED" | "Selected" ) ! namePart SELF ::= ( "self" | "SELF" | "Self" ) ! namePart SWITCH ::= ( "switch" | "SWITCH" | "Switch" ) ! namePart TO ::= ( "to" | "TO" | "To" ) ! namePart TRANSFORM ::= ( "transform" | "TRANSFORM" | "Transform" ) ! namePart TRUE ::= ( "true" | "TRUE" | "True" ) ! namePart UNRELATE ::= ( "unrelate" | "UNRELATE" | "Unrelate" ) ! namePart USING ::= ( "using" | "USING" | "Using" ) ! namePart WHERE ::= ( "where" | "WHERE" | "Where" ) ! namePart WHILE ::= ( "while" | "WHILE" | "While" ) ! namePart relationshipID ::= ( 'R' | 'r' ) positiveInteger positiveInteger ::= '1'..'9' { '0'..'9' }* ! namePart keyLetters ::= { keyLettersPart }+ ! namePart keyLettersPart := 'A'..'Z' | 'a'..'z' | '_' assignerSuffix ::= ( 'A' | 'a' ) ! namePart simpleEventLabel ::= { keyLettersPart }+ positiveInteger assignerEventSuffix ::= ( 'A' | 'a' ) positiveInteger polymorphicEventSuffix ::= ( 'P' | 'p' ) positiveInteger // End of File