##// END OF EJS Templates
sync
cin -
r157:948c015a9011 v2
parent child
Show More
@@ -3,51 +3,63 using Implab.Parsing;
3 3
4 4 namespace Implab.Components {
5 5 public class RunnableComponent : Disposable, IRunnable, IInitializable {
6 class Automaton : DFAutomaton<ExecutionState> {
7 static readonly EDFADefinition<ExecutionState> _dfa;
6
7
8 class Automaton {
9 enum Operations {
10 Initialize,
11 Start,
12 Stop,
13 Fail,
14 Success,
15 Dispose
16 }
17
18 static readonly EDFADefinition<ExecutionState> _def = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet);
19 static readonly DFAStateDescriptior[] _states;
8 20
9 21 static Automaton() {
22 var created = _def.AddState(); // initial state
23 var initializing = _def.AddState();
24 var ready = _def.AddState();
25 var starting = _def.AddState();
26 var running = _def.AddState();
27 var stopping = _def.AddState();
28 var error = _def.AddState();
29 var disposing = _def.AddState();
30 var disposed = _def.AddState(new int[] { 0 });
10 31
11 var token = Token
12 .New(ExecutionState.Uninitialized).Optional() // we can skip uninitialized state
13 .Cat(
14 Token.New(ExecutionState.Ready) // uninitialized -> initial
15 .Cat(
16 Token.New(ExecutionState.Starting) // initial -> starting
17 .Cat(
18 Token.New(ExecutionState.Running) // running -> {stopping -> stopped | failed }
19 .Cat(
20 Token.New(ExecutionState.Stopping) // running -> stopping
21 .Cat(
22 Token.New(ExecutionState.Stopped) // stopping -> stopped
23 .Or(Token.New(ExecutionState.Failed)) // stopping -> failed
24 )
25 .Or(Token.New(ExecutionState.Failed)) // running -> failed
26 )
27 .Or(Token.New(ExecutionState.Failed)) // starting -> failed
28 ).EClosure()
29 )
30 .Or(Token.New(ExecutionState.Failed)) // uninitialized->failed
31 .Cat(Token.New(ExecutionState.Disposed).Tag(0)) // ... -> disposed
32 );
32 _def.DefineTransition(created,initializing,(int)Operations.Initialize);
33
34 _def.DefineTransition(initializing,ready,(int)Operations.Success);
35 _def.DefineTransition(initializing,error,(int)Operations.Fail);
36
37 _def.DefineTransition(ready, starting, (int)Operations.Start);
38 _def.DefineTransition(ready, disposing, (int)Operations.Dispose);
39
33 40
34 var builder = new DFABuilder();
35 token.Accept(builder);
41 _def.DefineTransition(starting, running, (int)Operations.Success);
42 _def.DefineTransition(starting, error, (int)Operations.Fail);
43
44 _def.DefineTransition(running, stopping, (int)Operations.Stop);
45 _def.DefineTransition(running, error, (int)Operations.Fail);
36 46
37 var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet);
38 builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet
47 _def.DefineTransition(stopping, ready, (int)Operations.Success);
48 _def.DefineTransition(stopping, error, (int)Operations.Fail);
39 49
50 _def.DefineTransition(disposing, disposed, (int)Operations.Success);
51
52 _states = _def.States;
40 53 }
41 54
42 public Automaton() : base(_dfa.States, INITIAL_STATE, ExecutionState.Reserved) {
55 int m_state;
56
57 public Automaton() {
58 m_state = DFADefinitionBase.INITIAL_STATE;
43 59 }
44 60
45 public void MoveTo(ExecutionState state) {
61 void Move(Operations op) {
46 62
47 if (!CanMove((int)state))
48 throw new InvalidOperationException(String.Format("Illegal state transition from {0} to {1}", Current, state));
49 Move((int)state);
50 m_context.info = state;
51 63 }
52 64
53 65 public ExecutionState Current {
@@ -18,6 +18,10 namespace Implab.Parsing {
18 18 get { return m_alphabet.Count; }
19 19 }
20 20
21 public void DefineTransition(int s1, int s2, T input) {
22 DefineTransition(s1, s2, m_alphabet.Translate(input));
23 }
24
21 25 public EDFADefinition<T> Optimize() {
22 26 var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
23 27 Optimize(optimized, m_alphabet, optimized.Alphabet);
General Comments 0
You need to be logged in to leave comments. Login now