// 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 "::" ] asynchronousReturnWormhole ] '>'
// | externalName
dataType := externalName [ '<' [ relationshipReference | stateModelReference | objectReference | eventReference
| [ terminatorReference "::" ] ( synchronousService
| asynchronousReturnWormhole ) ] '>' ]
// 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