ステートマシン図からコード生成

やりたいこと
ステートマシン図からコードに変換したい
実現方法
・Windows:エンタープライズアーキテクトで可能(高い)
http://www.sparxsystems.jp/products/EA/state.htm
・Mac:state machine compilerを使えば可能(無料)
http://smc.sourceforge.net/
1.以下から6_0_1をダウンロード(最新版の6_3_0はJava7が必要ぽいのでスキップ)
http://sourceforge.jp/projects/sfnet_smc/releases/
2.smc_6_0_1.tgzをドキュメントルートに解凍する
$ cd /var/www/html
$ tar zxvf smc_6_0_1.tgz
3.サンプルでPNGでステートマシン図を出してみる
$ cd smc_6_0_1/examples/Java/EX1
$ make png
以下の形式で記載されているAppClass.smに対してdotファイルが自動生成される
%start Map1::Start
%class AppClass

%map Map1
%%
// State Transition End State Action(s)
Start {
Zero Zeros {}
One Ones {}
Unknown Error {}
EOS OK {Acceptable();}
}

Zeros {
Zero Zeros {}
One Ones {}
Unknown Error {}
EOS OK {Acceptable();}
}

Ones {
Zero Error {}
One Ones {}
Unknown Error {}
EOS OK {Acceptable();}
}

OK {}

Error {
Zero nil {}
One nil {}
Unknown nil {}
EOS nil {Unacceptable();}
}

%%
make pngで生成されたdotファイル
digraph AppClass_sm {

node
[shape=Mrecord width=1.5];

subgraph cluster_Map1 {

label=”Map1″;

//
// States (Nodes)
//

“Map1::Start”
[label=”{Start}”];

“Map1::Zeros2″
[label=”{Zeros2}”];

“Map1::Ones”
[label=”{Ones}”];

“Map1::OK”
[label=”{OK}”];

“Map1::Error”
[label=”{Error|Zero/\lOne/\lUnknown/\lEOS/\l   Unacceptable;\l}”];

“%start”
[label=”” shape=circle style=filled fillcolor=black width=0.25];

//
// Transitions (Edges)
//

“Map1::Start” -> “Map1::Zeros2″
[label=”Zero/\l”];

“Map1::Start” -> “Map1::Ones”
[label=”One/\l”];

“Map1::Start” -> “Map1::Error”
[label=”Unknown/\l”];

“Map1::Start” -> “Map1::OK”
[label=”EOS/\lAcceptable;\l”];

“Map1::Zeros2” -> “Map1::Zeros2″
[label=”Zero/\l”];

“Map1::Zeros2” -> “Map1::Ones”
[label=”One/\l”];

“Map1::Zeros2” -> “Map1::Error”
[label=”Unknown/\l”];

“Map1::Zeros2” -> “Map1::OK”
[label=”EOS/\lAcceptable;\l”];

“Map1::Ones” -> “Map1::Error”
[label=”Zero/\l”];

“Map1::Ones” -> “Map1::Ones”
[label=”One/\l”];

“Map1::Ones” -> “Map1::Error”
[label=”Unknown/\l”];

“Map1::Ones” -> “Map1::OK”
[label=”EOS/\lAcceptable;\l”];

“%start” -> “Map1::Start”
}

}
make pngで生成された画像。
AppClass_sm.dot.png
make tableとすると遷移表がhtmlで出力される
スクリーンショット 2014-04-04 10.32.51.png
make checkingとするとコードが生成される
/*
* ex: set ro:
* DO NOT EDIT.
* generated by smc (http://smc.sourceforge.net/)
* from file : AppClassContext.sm
*/

public class AppClassContext
extends statemap.FSMContext
{
//—————————————————————
// Member methods.
//

public AppClassContext(AppClass owner)
{
super (Map1.Start);

_owner = owner;
}

public AppClassContext(AppClass owner, AppClassState initState)
{
super (initState);

_owner = owner;
}

public void enterStartState()
{
getState().Entry(this);
return;
}

public void EOS()
{
_transition = “EOS”;
getState().EOS(this);
_transition = “”;
return;
}

public void One()
{
_transition = “One”;
getState().One(this);
_transition = “”;
return;
}

public void Unknown()
{
_transition = “Unknown”;
getState().Unknown(this);
_transition = “”;
return;
}

public void Zero()
{
_transition = “Zero”;
getState().Zero(this);
_transition = “”;
return;
}

public AppClassState getState()
throws statemap.StateUndefinedException
{
if (_state == null)
{
throw(
new statemap.StateUndefinedException());
}

return ((AppClassState) _state);
}

protected AppClass getOwner()
{
return (_owner);
}

public void setOwner(AppClass owner)
{
if (owner == null)
{
throw (
new NullPointerException(
“null owner”));
}
else
{
_owner = owner;
}

return;
}

//—————————————————————
// Member data.
//

transient private AppClass _owner;

public static abstract class AppClassState
extends statemap.State
{
//———————————————————–
// Member methods.
//

protected AppClassState(String name, int id)
{
super (name, id);
}

protected void Entry(AppClassContext context) {}
protected void Exit(AppClassContext context) {}

protected void EOS(AppClassContext context)
{
Default(context);
}

protected void One(AppClassContext context)
{
Default(context);
}

protected void Unknown(AppClassContext context)
{
Default(context);
}

protected void Zero(AppClassContext context)
{
Default(context);
}

protected void Default(AppClassContext context)
{
throw (
new statemap.TransitionUndefinedException(
“State: ” +
context.getState().getName() +
“, Transition: ” +
context.getTransition()));
}

//———————————————————–
// Member data.
//
}

/* package */ static abstract class Map1
{
//———————————————————–
// Member methods.
//

//———————————————————–
// Member data.
//

//——————————————————-
// Constants.
//
public static final Map1_Start Start =
new Map1_Start(“Map1.Start”, 0);
public static final Map1_Zeros2 Zeros2 =
new Map1_Zeros2(“Map1.Zeros2”, 1);
public static final Map1_Ones Ones =
new Map1_Ones(“Map1.Ones”, 2);
public static final Map1_OK OK =
new Map1_OK(“Map1.OK”, 3);
public static final Map1_Error Error =
new Map1_Error(“Map1.Error”, 4);
private static final Map1_Default Default =
new Map1_Default(“Map1.Default”, -1);

}

protected static class Map1_Default
extends AppClassState
{
//———————————————————–
// Member methods.
//

protected Map1_Default(String name, int id)
{
super (name, id);
}
//———————————————————–
// Member data.
//
}

private static final class Map1_Start
extends Map1_Default
{
//——————————————————-
// Member methods.
//

private Map1_Start(String name, int id)
{
super (name, id);
}

protected void EOS(AppClassContext context)
{
AppClass ctxt = context.getOwner();

(context.getState()).Exit(context);
context.clearState();
try
{
ctxt.Acceptable();
}
finally
{
context.setState(Map1.OK);
(context.getState()).Entry(context);
}
return;
}

protected void One(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Ones);
(context.getState()).Entry(context);
return;
}

protected void Unknown(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Error);
(context.getState()).Entry(context);
return;
}

protected void Zero(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Zeros2);
(context.getState()).Entry(context);
return;
}

//——————————————————-
// Member data.
//
}

private static final class Map1_Zeros2
extends Map1_Default
{
//——————————————————-
// Member methods.
//

private Map1_Zeros2(String name, int id)
{
super (name, id);
}

protected void EOS(AppClassContext context)
{
AppClass ctxt = context.getOwner();

(context.getState()).Exit(context);
context.clearState();
try
{
ctxt.Acceptable();
}
finally
{
context.setState(Map1.OK);
(context.getState()).Entry(context);
}
return;
}

protected void One(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Ones);
(context.getState()).Entry(context);
return;
}

protected void Unknown(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Error);
(context.getState()).Entry(context);
return;
}

protected void Zero(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Zeros2);
(context.getState()).Entry(context);
return;
}

//——————————————————-
// Member data.
//
}

private static final class Map1_Ones
extends Map1_Default
{
//——————————————————-
// Member methods.
//

private Map1_Ones(String name, int id)
{
super (name, id);
}

protected void EOS(AppClassContext context)
{
AppClass ctxt = context.getOwner();

(context.getState()).Exit(context);
context.clearState();
try
{
ctxt.Acceptable();
}
finally
{
context.setState(Map1.OK);
(context.getState()).Entry(context);
}
return;
}

protected void One(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Ones);
(context.getState()).Entry(context);
return;
}

protected void Unknown(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Error);
(context.getState()).Entry(context);
return;
}

protected void Zero(AppClassContext context)
{

(context.getState()).Exit(context);
context.setState(Map1.Error);
(context.getState()).Entry(context);
return;
}

//——————————————————-
// Member data.
//
}

private static final class Map1_OK
extends Map1_Default
{
//——————————————————-
// Member methods.
//

private Map1_OK(String name, int id)
{
super (name, id);
}

//——————————————————-
// Member data.
//
}

private static final class Map1_Error
extends Map1_Default
{
//——————————————————-
// Member methods.
//

private Map1_Error(String name, int id)
{
super (name, id);
}

protected void EOS(AppClassContext context)
{
AppClass ctxt = context.getOwner();

AppClassState endState = context.getState();

context.clearState();
try
{
ctxt.Unacceptable();
}
finally
{
context.setState(endState);
}
return;
}

protected void One(AppClassContext context)
{

return;
}

protected void Unknown(AppClassContext context)
{

return;
}

protected void Zero(AppClassContext context)
{

return;
}

//——————————————————-
// Member data.
//
}
}

/*
* Local variables:
* buffer-read-only: t
* End:
*/