PJ expects a file containing a base state diagram to have the following format:
package <package-name>;[<import-statements>]<state-diagram-declaration>
Note:
The syntax of a state diagram specification (which incidentally is slightly different than the version used to develop the FSATS prototype) is discussed later.
A state diagram extension file has the following format:
package <package-name>;[<import-statements>]<state-digram-extension-declaration>
Note:
The syntax of a state diagram extension specification is discussed later.
A state diagram can be:
Each is specified in the following way, where bold phrases are parameters and [bracketed] phrases are optional:
[modifiers] state_diagram name [implementsClause] SDClassBody[modifiers] state_diagram name extends supername [implementsClause] SDClassBody[modifiers] state_diagram name extends class supername [implementsClause] SDClassBody
The body of a state diagram (SDClassBody above) has the following syntax:
{ event_delivery methodname ( <parameter-list> ); (1)no_transition <block> (2)[ otherwise_default <block> ] (3)[ <states-list> ] (4)[ <ES-list> ] (5)[ <field-and-method-declarations> ] (6) }
The meaning of these concepts is specified in a separate document; here we talk only about the syntax of state diagram specifications. Observe the following notes:
states a, b, c; states e, f, g, h; // and so on
An example of a state diagram specification is:
package root1; import firstPackage.*; state_diagram root extends class common { event_delivery mymessage( M m ); no_transition { ignore(m); } // in root states a, b; states c; // in root edge e1 : a -> b conditions m!=null do { /* action 1 */ } Exit a { /* action a */ } }
An extension to a state diagram is expressed in the following syntax:
[modifiers] extends state_diagram name [implementsClause] SDExtBody
The body of a state diagram extension (SDExtBody above) has the following syntax:
{ [ otherwise_default <block> ] (3)[ <states-list> ] (4)[ <ES-list> ] (5)[ <field-and-method-declarations> ] (6) }
Again, the meaning of these concepts is specified in a separate document; here we talk only about the syntax. The meanings of these concepts is the same as above. Keep the following in mind:
An issue that can arise in the design of state diagrams is that an edge predicate or block of code associated with the actions of a state or edge can be modified by an extension. Since there are no capabilities to extend predicates or code blocks, the way this can be done is to define a boolean method for a predicate and a void method to encapsulate a code block. Methods can be extended using the normal mechanisms. So the way to understand ES-list declarations is that they are one-time-specifications that cannot be modified. These specifications can refer to methods which can be modified by extensions. So the scheme described here is general and simple.
Admittedly, this is a bit different from the original state diagram specification used in the FSATS prototype, it is marginally so. Further, there is no capability now for "refines edge" (i.e., the refinement/extension of edges). This too can be handled by defining predicates and edge transitions as methods which can be modified by extensions.
An example of a state diagram extension is:
package ext1; import firstPackage.*; extends state_diagram root { // from ext 1 states d; states e; // from ext1 edge e2 : d -> e conditions m!=null do { /* action 2 */ } edge e3 : c -> d conditions true do { /* action 3 */ } Exit b { /* action a */ } }
The result of composing the base state diagram defined earlier with the above extension is (defined to be the) union of these specifications, with the proviso that no state or edge is defined twice. The statements in yellow were added by the above extension.
package root1; import firstPackage.*; state_diagram root extends class common { event_delivery mymessage( M m ); no_transition { ignore(m); } // in root states a, b; states c; // from ext 1 states d; states e; // in root edge e1 : a -> b conditions m!=null do { /* action 1 */ } Exit a { /* action a */ } // from ext1 edge e2 : d -> e conditions m!=null do { /* action 2 */ } edge e3 : c -> d conditions true do { /* action 3 */ } Exit b { /* action a */ } }
The complete grammar for state diagram specifications is listed below:
// "state diagram" adds constructs to define state machines "state_diagram" STATE_DIAGRAM "states" STATES "event_delivery" EVENT_DELIVERY "edge" EDGE "conditions" CONDITIONS "->" ARROW "Exit" EXIT "Enter" ENTER "otherwise" OTHERWISE "otherwise_default" OTHERWISE_DEFAULT "no_transition" NO_TRANSITION // the following hooks SDDeclaration with class, interface declarations UnmodifiedTypeDeclaration : SDDeclaration :: SDDecl ; SDDeclaration : STATE_DIAGRAM QName [ SMExtendsClause ] [ ImplementsClause ] SDClassBody :: UmodSdDecl ; SMExtendsClause : LOOKAHEAD(2) ExtendsClause :: SMExtends | LOOKAHEAD(2) "extends" "class" AST_QualifiedName :: SMClsExtends ; SDClassBody : "{" [ RootClause ] [ OtherwiseClause ] [ StatesList ] [ ESList ] [ AST_FieldDecl ] "}" :: SdClassDecl ; StatesList : (StatesClause)+ ; StatesClause : STATES AST_TypeNameList ";" :: StatesDecl ; RootClause : DelivClause NoTransitionClause :: RootDecl ; NoTransitionClause : NO_TRANSITION Block :: NoTransDecl ; DelivClause : EVENT_DELIVERY QName "(" AST_ParList ")" ";" :: DelivDecl ; OtherwiseClause : OTHERWISE_DEFAULT Block :: ODefaultDecl ; ESList : ( Es )+ ; Es : EXIT QName Block :: ExitDecl | ENTER QName Block :: EnterDecl | EDGE QName ":" StartName ARROW QName CONDITIONS AST_Exp DO Block :: EdgeDecl | OTHERWISE QName Block :: OtherDecl ; StartName : QName :: SdSName | "*" :: StarName ; // the following is used to allow SD declarations to be nested within // class declarations; this is useful if we want to include SD specifications // within layers NestedSDDeclaration : [ AST_Modifiers ] SDDeclaration :: NSDDecl ; ClassBodyDeclaration : LOOKAHEAD( [ AST_Modifiers() ] "state_diagram" ) NestedSDDeclaration ; // the following is used to define extensions to state machines UnmodifiedTypeExtension : STATE_DIAGRAM QName [ ImplementsClause ] SDClassBody :: UmodSmExt ;
PJ is still undergoing changes. Known problems include: