##// END OF EJS Templates
Promises: SignalXXX methods merged into SignalHandler method....
cin -
r156:97fbbf816844 v2
parent child
Show More
@@ -0,0 +1,8
1 using System;
2
3 namespace Implab.Components {
4 public interface IFactory<out T> {
5 T Create();
6 }
7 }
8
@@ -0,0 +1,141
1 using System;
2 using Implab.Parsing;
3
4 namespace Implab.Components {
5 public class RunnableComponent : Disposable, IRunnable, IInitializable {
6 class Automaton : DFAutomaton<ExecutionState> {
7 static readonly EDFADefinition<ExecutionState> _dfa;
8
9 static Automaton() {
10
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 );
33
34 var builder = new DFABuilder();
35 token.Accept(builder);
36
37 var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet);
38 builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet
39
40 }
41
42 public Automaton() : base(_dfa.States, INITIAL_STATE, ExecutionState.Reserved) {
43 }
44
45 public void MoveTo(ExecutionState state) {
46
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 }
52
53 public ExecutionState Current {
54 get {
55 return (ExecutionState)m_context.info;
56 }
57 }
58 }
59
60 readonly Automaton m_automaton = new Automaton();
61 IPromise m_pending;
62 Exception m_lastError;
63
64 protected RunnableComponent(bool initialized) {
65 if (initialized)
66 m_automaton.MoveTo(ExecutionState.Ready);
67 else
68 m_automaton.MoveTo(ExecutionState.Uninitialized);
69 }
70
71 #region IInitializable implementation
72
73 public void Init() {
74
75 }
76
77 #endregion
78
79 #region IRunnable implementation
80
81 public IPromise Start() {
82 return Safe.InvokePromise(() => {
83 Promise promise;
84 lock (m_automaton) {
85 if (m_automaton.Current == ExecutionState.Starting)
86 return m_pending;
87 m_automaton.MoveTo(ExecutionState.Starting);
88 m_pending = promise = new Promise();
89 }
90
91 var start = Safe.InvokePromise(OnStart);
92 promise.On(null, null, start.Cancel);
93 start.On(promise.Resolve, promise.Reject, promise.CancelOperation);
94
95 return promise.Then(() => {
96 lock(m_automaton) {
97 m_automaton.MoveTo(ExecutionState.Running);
98 m_pending = null;
99 }
100
101 Run();
102 }, err => {
103 if (BeginTransition(RUNNING_REQUIRE)) {
104 m_lastError = err;
105 CompleteTransition(FAILED_STATE);
106 throw new PromiseTransientException(err);
107 }
108 throw new OperationCanceledException();
109 }, reason => {
110 throw new OperationCanceledException("The operation was cancelled", reason);
111 });
112 });
113 }
114
115 protected virtual IPromise OnStart() {
116 return Promise.SUCCESS;
117 }
118
119 protected virtual void Run() {
120 }
121
122 public IPromise Stop() {
123 throw new NotImplementedException();
124 }
125
126 public ExecutionState State {
127 get {
128 throw new NotImplementedException();
129 }
130 }
131
132 public Exception LastError {
133 get {
134 throw new NotImplementedException();
135 }
136 }
137
138 #endregion
139 }
140 }
141
@@ -1,38 +1,23
1 using System.Windows.Forms;
1 using System.Windows.Forms;
2 using System;
2 using System;
3
3
4
4
5 namespace Implab.Fx {
5 namespace Implab.Fx {
6 public class ControlBoundPromise<T> : Promise<T> {
6 public class ControlBoundPromise<T> : Promise<T> {
7 readonly Control m_target;
7 readonly Control m_target;
8
8
9 public ControlBoundPromise(Control target) {
9 public ControlBoundPromise(Control target) {
10 Safe.ArgumentNotNull(target, "target");
10 Safe.ArgumentNotNull(target, "target");
11
11
12 m_target = target;
12 m_target = target;
13 }
13 }
14
14
15 protected override void SignalSuccess(Promise<T>.HandlerDescriptor handler) {
15 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
16 if (m_target.InvokeRequired)
16 if (m_target.InvokeRequired)
17 m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor>(base.SignalSuccess), handler);
17 m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor, int>(base.SignalHandler), handler, signal);
18 else
19 base.SignalSuccess(handler);
20 }
21
22 protected override void SignalCancelled(Promise<T>.HandlerDescriptor handler, Exception reason) {
23 if (m_target.InvokeRequired)
24 m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor,Exception>(base.SignalCancelled), handler, reason);
25 else
18 else
26 base.SignalCancelled(handler, reason);
19 base.SignalHandler(handler, signal);
27 }
20 }
28
29 protected override void SignalError(Promise<T>.HandlerDescriptor handler, Exception error) {
30 if (m_target.InvokeRequired)
31 m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor,Exception>(base.SignalError), handler, error);
32 else
33 base.SignalError(handler, error);
34 }
35
36 }
21 }
37 }
22 }
38
23
@@ -1,353 +1,300
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3 using System.Threading;
3 using System.Threading;
4 using System.Reflection;
4 using System.Reflection;
5
5
6 namespace Implab {
6 namespace Implab {
7 public abstract class AbstractEvent<THandler> : ICancellationToken, ICancellable {
7 public abstract class AbstractEvent<THandler> : ICancellationToken, ICancellable {
8
8
9 const int UNRESOLVED_SATE = 0;
9 const int UNRESOLVED_SATE = 0;
10 const int TRANSITIONAL_STATE = 1;
10 const int TRANSITIONAL_STATE = 1;
11 const int SUCCEEDED_STATE = 2;
11 protected const int SUCCEEDED_STATE = 2;
12 const int REJECTED_STATE = 3;
12 protected const int REJECTED_STATE = 3;
13 const int CANCELLED_STATE = 4;
13 protected const int CANCELLED_STATE = 4;
14
14
15 const int CANCEL_NOT_REQUESTED = 0;
15 const int CANCEL_NOT_REQUESTED = 0;
16 const int CANCEL_REQUESTING = 1;
16 const int CANCEL_REQUESTING = 1;
17 const int CANCEL_REQUESTED = 2;
17 const int CANCEL_REQUESTED = 2;
18
18
19 const int RESERVED_HANDLERS_COUNT = 4;
19 const int RESERVED_HANDLERS_COUNT = 4;
20
20
21 int m_state;
21 int m_state;
22 Exception m_error;
22 Exception m_error;
23 int m_handlersCount;
23 int m_handlersCount;
24
24
25 readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT];
25 //readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT];
26 THandler[] m_handlers;
26 MTQueue<THandler> m_extraHandlers;
27 MTQueue<THandler> m_extraHandlers;
27 int m_handlerPointer = -1;
28 int m_handlerPointer = -1;
28 int m_handlersCommited;
29 int m_handlersCommited;
29
30
30 int m_cancelRequest;
31 int m_cancelRequest;
31 Exception m_cancelationReason;
32 Exception m_cancelationReason;
32 MTQueue<Action<Exception>> m_cancelationHandlers;
33 MTQueue<Action<Exception>> m_cancelationHandlers;
33
34
34
35
35 #region state managment
36 #region state managment
36 bool BeginTransit() {
37 bool BeginTransit() {
37 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
38 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
38 }
39 }
39
40
40 void CompleteTransit(int state) {
41 void CompleteTransit(int state) {
41 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
42 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
42 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
43 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
43 }
44 }
44
45
45 void WaitTransition() {
46 void WaitTransition() {
46 while (m_state == TRANSITIONAL_STATE) {
47 while (m_state == TRANSITIONAL_STATE) {
47 Thread.MemoryBarrier();
48 Thread.MemoryBarrier();
48 }
49 }
49 }
50 }
50
51
51 protected bool BeginSetResult() {
52 protected bool BeginSetResult() {
52 if (!BeginTransit()) {
53 if (!BeginTransit()) {
53 WaitTransition();
54 WaitTransition();
54 if (m_state != CANCELLED_STATE)
55 if (m_state != CANCELLED_STATE)
55 throw new InvalidOperationException("The promise is already resolved");
56 throw new InvalidOperationException("The promise is already resolved");
56 return false;
57 return false;
57 }
58 }
58 return true;
59 return true;
59 }
60 }
60
61
61 protected void EndSetResult() {
62 protected void EndSetResult() {
62 CompleteTransit(SUCCEEDED_STATE);
63 CompleteTransit(SUCCEEDED_STATE);
63 OnSuccess();
64 Signal();
64 }
65 }
65
66
66
67
67
68
68 /// <summary>
69 /// <summary>
69 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
70 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
70 /// </summary>
71 /// </summary>
71 /// <remarks>
72 /// <remarks>
72 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
73 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
73 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
74 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
74 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
75 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
75 /// </remarks>
76 /// </remarks>
76 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
77 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
77 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
78 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
78 protected void SetError(Exception error) {
79 protected void SetError(Exception error) {
79 if (BeginTransit()) {
80 if (BeginTransit()) {
80 if (error is OperationCanceledException) {
81 if (error is OperationCanceledException) {
82 m_error = error.InnerException;
81 CompleteTransit(CANCELLED_STATE);
83 CompleteTransit(CANCELLED_STATE);
82 m_error = error.InnerException;
83 OnCancelled();
84 } else {
84 } else {
85 m_error = error is PromiseTransientException ? error.InnerException : error;
85 m_error = error is PromiseTransientException ? error.InnerException : error;
86 CompleteTransit(REJECTED_STATE);
86 CompleteTransit(REJECTED_STATE);
87 OnError();
88 }
87 }
88 Signal();
89 } else {
89 } else {
90 WaitTransition();
90 WaitTransition();
91 if (m_state == SUCCEEDED_STATE)
91 if (m_state == SUCCEEDED_STATE)
92 throw new InvalidOperationException("The promise is already resolved");
92 throw new InvalidOperationException("The promise is already resolved");
93 }
93 }
94 }
94 }
95
95
96 /// <summary>
96 /// <summary>
97 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
97 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
98 /// </summary>
98 /// </summary>
99 /// <remarks>Для опрСдСлСния Π±Ρ‹Π»Π° Π»ΠΈ опСрация ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π° слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свойство <see cref="IsCancelled"/>.</remarks>
99 /// <remarks>Для опрСдСлСния Π±Ρ‹Π»Π° Π»ΠΈ опСрация ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π° слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свойство <see cref="IsCancelled"/>.</remarks>
100 protected void SetCancelled(Exception reason) {
100 protected void SetCancelled(Exception reason) {
101 if (BeginTransit()) {
101 if (BeginTransit()) {
102 m_error = reason;
102 m_error = reason;
103 CompleteTransit(CANCELLED_STATE);
103 CompleteTransit(CANCELLED_STATE);
104 OnCancelled();
104 Signal();
105 }
105 }
106 }
106 }
107
107
108 protected abstract void SignalSuccess(THandler handler);
108 protected abstract void SignalHandler(THandler handler, int signal);
109
110 protected abstract void SignalError(THandler handler, Exception error);
111
109
112 protected abstract void SignalCancelled(THandler handler, Exception reason);
110 void Signal() {
113
114 void OnSuccess() {
115 var hp = m_handlerPointer;
111 var hp = m_handlerPointer;
116 var slot = hp +1 ;
112 var slot = hp +1 ;
117 while (slot < m_handlersCommited) {
113 while (slot < m_handlersCommited) {
118 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
114 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
119 SignalSuccess(m_handlers[slot]);
115 SignalHandler(m_handlers[slot], m_state);
120 }
116 }
121 hp = m_handlerPointer;
117 hp = m_handlerPointer;
122 slot = hp +1 ;
118 slot = hp +1 ;
123 }
119 }
124
120
125
121
126 if (m_extraHandlers != null) {
122 if (m_extraHandlers != null) {
127 THandler handler;
123 THandler handler;
128 while (m_extraHandlers.TryDequeue(out handler))
124 while (m_extraHandlers.TryDequeue(out handler))
129 SignalSuccess(handler);
125 SignalHandler(handler, m_state);
130 }
131 }
132
133 void OnError() {
134 var hp = m_handlerPointer;
135 var slot = hp +1 ;
136 while (slot < m_handlersCommited) {
137 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
138 SignalError(m_handlers[slot],m_error);
139 }
140 hp = m_handlerPointer;
141 slot = hp +1 ;
142 }
143
144 if (m_extraHandlers != null) {
145 THandler handler;
146 while (m_extraHandlers.TryDequeue(out handler))
147 SignalError(handler, m_error);
148 }
149 }
150
151 void OnCancelled() {
152 var hp = m_handlerPointer;
153 var slot = hp +1 ;
154 while (slot < m_handlersCommited) {
155 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
156 SignalCancelled(m_handlers[slot], m_error);
157 }
158 hp = m_handlerPointer;
159 slot = hp +1 ;
160 }
161
162 if (m_extraHandlers != null) {
163 THandler handler;
164 while (m_extraHandlers.TryDequeue(out handler))
165 SignalCancelled(handler, m_error);
166 }
126 }
167 }
127 }
168
128
169 #endregion
129 #endregion
170
130
171 protected abstract Signal GetResolveSignal();
131 protected abstract Signal GetResolveSignal();
172
132
173 #region synchronization traits
133 #region synchronization traits
174 protected void WaitResult(int timeout) {
134 protected void WaitResult(int timeout) {
175 if (!(IsResolved || GetResolveSignal().Wait(timeout)))
135 if (!(IsResolved || GetResolveSignal().Wait(timeout)))
176 throw new TimeoutException();
136 throw new TimeoutException();
177
137
178 switch (m_state) {
138 switch (m_state) {
179 case SUCCEEDED_STATE:
139 case SUCCEEDED_STATE:
180 return;
140 return;
181 case CANCELLED_STATE:
141 case CANCELLED_STATE:
182 throw new OperationCanceledException();
142 throw new OperationCanceledException();
183 case REJECTED_STATE:
143 case REJECTED_STATE:
184 throw new TargetInvocationException(m_error);
144 throw new TargetInvocationException(m_error);
185 default:
145 default:
186 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
146 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
187 }
147 }
188 }
148 }
189 #endregion
149 #endregion
190
150
191 #region handlers managment
151 #region handlers managment
192
152
193 protected void AddHandler(THandler handler) {
153 protected void AddHandler(THandler handler) {
194
154
195 if (m_state > 1) {
155 if (m_state > 1) {
196 // the promise is in the resolved state, just invoke the handler
156 // the promise is in the resolved state, just invoke the handler
197 InvokeHandler(handler);
157 SignalHandler(handler, m_state);
198 } else {
158 } else {
199 var slot = Interlocked.Increment(ref m_handlersCount) - 1;
159 var slot = Interlocked.Increment(ref m_handlersCount) - 1;
200
160
201 if (slot < RESERVED_HANDLERS_COUNT) {
161 if (slot < RESERVED_HANDLERS_COUNT) {
202
162
163 if (slot == 0)
164 Interlocked.CompareExchange(ref m_handlers, new THandler[RESERVED_HANDLERS_COUNT], null);
165
203 m_handlers[slot] = handler;
166 m_handlers[slot] = handler;
204
167
205 while (slot != Interlocked.CompareExchange(ref m_handlersCommited, slot + 1, slot)) {
168 while (slot != Interlocked.CompareExchange(ref m_handlersCommited, slot + 1, slot)) {
206 }
169 }
207
170
208 if (m_state > 1) {
171 if (m_state > 1) {
209 do {
172 do {
210 var hp = m_handlerPointer;
173 var hp = m_handlerPointer;
211 slot = hp + 1;
174 slot = hp + 1;
212 if (slot < m_handlersCommited) {
175 if (slot < m_handlersCommited) {
213 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) != hp)
176 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) != hp)
214 continue;
177 continue;
215 InvokeHandler(m_handlers[slot]);
178 SignalHandler(m_handlers[slot], m_state);
216 }
179 }
217 break;
180 break;
218 } while(true);
181 } while(true);
219 }
182 }
220 } else {
183 } else {
221 if (slot == RESERVED_HANDLERS_COUNT) {
184 if (slot == RESERVED_HANDLERS_COUNT) {
222 m_extraHandlers = new MTQueue<THandler>();
185 m_extraHandlers = new MTQueue<THandler>();
223 } else {
186 } else {
224 while (m_extraHandlers == null)
187 while (m_extraHandlers == null)
225 Thread.MemoryBarrier();
188 Thread.MemoryBarrier();
226 }
189 }
227
190
228 m_extraHandlers.Enqueue(handler);
191 m_extraHandlers.Enqueue(handler);
229
192
230 if (m_state > 1 && m_extraHandlers.TryDequeue(out handler))
193 if (m_state > 1 && m_extraHandlers.TryDequeue(out handler))
231 // if the promise have been resolved while we was adding the handler to the queue
194 // if the promise have been resolved while we was adding the handler to the queue
232 // we can't guarantee that someone is still processing it
195 // we can't guarantee that someone is still processing it
233 // therefore we need to fetch a handler from the queue and execute it
196 // therefore we need to fetch a handler from the queue and execute it
234 // note that fetched handler may be not the one that we have added
197 // note that fetched handler may be not the one that we have added
235 // even we can fetch no handlers at all :)
198 // even we can fetch no handlers at all :)
236 InvokeHandler(handler);
199 SignalHandler(handler, m_state);
237 }
200 }
238 }
201 }
239 }
202 }
240
203
241 protected void InvokeHandler(THandler handler) {
242 switch (m_state) {
243 case SUCCEEDED_STATE:
244 SignalSuccess(handler);
245 break;
246 case CANCELLED_STATE:
247 SignalCancelled(handler, m_error);
248 break;
249 case REJECTED_STATE:
250 SignalError(handler, m_error);
251 break;
252 default:
253 throw new Exception(String.Format("Invalid promise state {0}", m_state));
254 }
255 }
256
257 #endregion
204 #endregion
258
205
259 #region IPromise implementation
206 #region IPromise implementation
260
207
261 public bool IsResolved {
208 public bool IsResolved {
262 get {
209 get {
263 Thread.MemoryBarrier();
210 Thread.MemoryBarrier();
264 return m_state > 1;
211 return m_state > 1;
265 }
212 }
266 }
213 }
267
214
268 public bool IsCancelled {
215 public bool IsCancelled {
269 get {
216 get {
270 Thread.MemoryBarrier();
217 Thread.MemoryBarrier();
271 return m_state == CANCELLED_STATE;
218 return m_state == CANCELLED_STATE;
272 }
219 }
273 }
220 }
274
221
275 #endregion
222 #endregion
276
223
277 public Exception Error {
224 public Exception Error {
278 get {
225 get {
279 return m_error;
226 return m_error;
280 }
227 }
281 }
228 }
282
229
283 public bool CancelOperationIfRequested() {
230 public bool CancelOperationIfRequested() {
284 if (IsCancellationRequested) {
231 if (IsCancellationRequested) {
285 CancelOperation(CancellationReason);
232 CancelOperation(CancellationReason);
286 return true;
233 return true;
287 }
234 }
288 return false;
235 return false;
289 }
236 }
290
237
291 public virtual void CancelOperation(Exception reason) {
238 public virtual void CancelOperation(Exception reason) {
292 SetCancelled(reason);
239 SetCancelled(reason);
293 }
240 }
294
241
295 public void CancellationRequested(Action<Exception> handler) {
242 public void CancellationRequested(Action<Exception> handler) {
296 Safe.ArgumentNotNull(handler, "handler");
243 Safe.ArgumentNotNull(handler, "handler");
297 if (IsCancellationRequested)
244 if (IsCancellationRequested)
298 handler(CancellationReason);
245 handler(CancellationReason);
299
246
300 if (m_cancelationHandlers == null)
247 if (m_cancelationHandlers == null)
301 Interlocked.CompareExchange(ref m_cancelationHandlers, new MTQueue<Action<Exception>>(), null);
248 Interlocked.CompareExchange(ref m_cancelationHandlers, new MTQueue<Action<Exception>>(), null);
302
249
303 m_cancelationHandlers.Enqueue(handler);
250 m_cancelationHandlers.Enqueue(handler);
304
251
305 if (IsCancellationRequested && m_cancelationHandlers.TryDequeue(out handler))
252 if (IsCancellationRequested && m_cancelationHandlers.TryDequeue(out handler))
306 // TryDeque implies MemoryBarrier()
253 // TryDeque implies MemoryBarrier()
307 handler(m_cancelationReason);
254 handler(m_cancelationReason);
308 }
255 }
309
256
310 public bool IsCancellationRequested {
257 public bool IsCancellationRequested {
311 get {
258 get {
312 do {
259 do {
313 if (m_cancelRequest == CANCEL_NOT_REQUESTED)
260 if (m_cancelRequest == CANCEL_NOT_REQUESTED)
314 return false;
261 return false;
315 if (m_cancelRequest == CANCEL_REQUESTED)
262 if (m_cancelRequest == CANCEL_REQUESTED)
316 return true;
263 return true;
317 Thread.MemoryBarrier();
264 Thread.MemoryBarrier();
318 } while(true);
265 } while(true);
319 }
266 }
320 }
267 }
321
268
322 public Exception CancellationReason {
269 public Exception CancellationReason {
323 get {
270 get {
324 do {
271 do {
325 Thread.MemoryBarrier();
272 Thread.MemoryBarrier();
326 } while(m_cancelRequest == CANCEL_REQUESTING);
273 } while(m_cancelRequest == CANCEL_REQUESTING);
327
274
328 return m_cancelationReason;
275 return m_cancelationReason;
329 }
276 }
330 }
277 }
331
278
332 #region ICancellable implementation
279 #region ICancellable implementation
333
280
334 public void Cancel() {
281 public void Cancel() {
335 Cancel(null);
282 Cancel(null);
336 }
283 }
337
284
338 public void Cancel(Exception reason) {
285 public void Cancel(Exception reason) {
339 if (CANCEL_NOT_REQUESTED == Interlocked.CompareExchange(ref m_cancelRequest, CANCEL_REQUESTING, CANCEL_NOT_REQUESTED)) {
286 if (CANCEL_NOT_REQUESTED == Interlocked.CompareExchange(ref m_cancelRequest, CANCEL_REQUESTING, CANCEL_NOT_REQUESTED)) {
340 m_cancelationReason = reason;
287 m_cancelationReason = reason;
341 m_cancelRequest = CANCEL_REQUESTED;
288 m_cancelRequest = CANCEL_REQUESTED;
342 if (m_cancelationHandlers != null) {
289 if (m_cancelationHandlers != null) {
343 Action<Exception> handler;
290 Action<Exception> handler;
344 while (m_cancelationHandlers.TryDequeue(out handler))
291 while (m_cancelationHandlers.TryDequeue(out handler))
345 handler(m_cancelationReason);
292 handler(m_cancelationReason);
346 }
293 }
347 }
294 }
348 }
295 }
349
296
350 #endregion
297 #endregion
351 }
298 }
352 }
299 }
353
300
@@ -1,138 +1,142
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3
3
4 namespace Implab {
4 namespace Implab {
5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
6 public struct HandlerDescriptor {
6 public struct HandlerDescriptor {
7 readonly Action m_handler;
7 readonly Action m_handler;
8 readonly Action<Exception> m_error;
8 readonly Action<Exception> m_error;
9 readonly Action<Exception> m_cancel;
9 readonly Action<Exception> m_cancel;
10 readonly PromiseEventType m_mask;
10 readonly PromiseEventType m_mask;
11
11
12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
13 m_handler = success;
13 m_handler = success;
14 m_error = error;
14 m_error = error;
15 m_cancel = cancel;
15 m_cancel = cancel;
16 m_mask = PromiseEventType.Success;
16 m_mask = PromiseEventType.Success;
17 }
17 }
18
18
19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
20 m_handler = handler;
20 m_handler = handler;
21 m_error = null;
21 m_error = null;
22 m_cancel = null;
22 m_cancel = null;
23 m_mask = mask;
23 m_mask = mask;
24 }
24 }
25
25
26 public void SignalSuccess() {
26 public void SignalSuccess() {
27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
28 try {
28 try {
29 m_handler();
29 m_handler();
30 } catch (Exception err) {
30 } catch (Exception err) {
31 // avoid calling handler twice in case of error
31 // avoid calling handler twice in case of error
32 if (m_error != null)
32 if (m_error != null)
33 SignalError(err);
33 SignalError(err);
34 }
34 }
35 }
35 }
36 }
36 }
37
37
38 public void SignalError(Exception err) {
38 public void SignalError(Exception err) {
39 if (m_error != null) {
39 if (m_error != null) {
40 try {
40 try {
41 m_error(err);
41 m_error(err);
42 // Analysis disable once EmptyGeneralCatchClause
42 // Analysis disable once EmptyGeneralCatchClause
43 } catch {
43 } catch {
44 }
44 }
45 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
45 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
46 try {
46 try {
47 m_handler();
47 m_handler();
48 // Analysis disable once EmptyGeneralCatchClause
48 // Analysis disable once EmptyGeneralCatchClause
49 } catch {
49 } catch {
50 }
50 }
51 }
51 }
52 }
52 }
53
53
54 public void SignalCancel(Exception reason) {
54 public void SignalCancel(Exception reason) {
55 if (m_cancel != null) {
55 if (m_cancel != null) {
56 try {
56 try {
57 m_cancel(reason);
57 m_cancel(reason);
58 } catch (Exception err) {
58 } catch (Exception err) {
59 SignalError(err);
59 SignalError(err);
60 }
60 }
61 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
61 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
62 try {
62 try {
63 m_handler();
63 m_handler();
64 // Analysis disable once EmptyGeneralCatchClause
64 // Analysis disable once EmptyGeneralCatchClause
65 } catch {
65 } catch {
66 }
66 }
67 }
67 }
68 }
68 }
69 }
69 }
70
70
71
71
72 #region implemented abstract members of AbstractPromise
72 #region implemented abstract members of AbstractPromise
73
73
74 protected override void SignalSuccess(HandlerDescriptor handler) {
74 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
75 handler.SignalSuccess();
75 switch (signal) {
76 }
76 case SUCCEEDED_STATE:
77
77 handler.SignalSuccess();
78 protected override void SignalError(HandlerDescriptor handler, Exception error) {
78 break;
79 handler.SignalError(error);
79 case REJECTED_STATE:
80 }
80 handler.SignalError(Error);
81
81 break;
82 protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) {
82 case CANCELLED_STATE:
83 handler.SignalCancel(reason);
83 handler.SignalCancel(CancellationReason);
84 break;
85 default:
86 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
87 }
84 }
88 }
85
89
86 protected override Signal GetResolveSignal() {
90 protected override Signal GetResolveSignal() {
87 var signal = new Signal();
91 var signal = new Signal();
88 On(signal.Set, PromiseEventType.All);
92 On(signal.Set, PromiseEventType.All);
89 return signal;
93 return signal;
90 }
94 }
91
95
92 #endregion
96 #endregion
93
97
94 public Type PromiseType {
98 public Type PromiseType {
95 get {
99 get {
96 return typeof(void);
100 return typeof(void);
97 }
101 }
98 }
102 }
99
103
100 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
104 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
101 AddHandler(new HandlerDescriptor(success, error, cancel));
105 AddHandler(new HandlerDescriptor(success, error, cancel));
102 return this;
106 return this;
103 }
107 }
104
108
105 public IPromise On(Action success, Action<Exception> error) {
109 public IPromise On(Action success, Action<Exception> error) {
106 AddHandler(new HandlerDescriptor(success, error, null));
110 AddHandler(new HandlerDescriptor(success, error, null));
107 return this;
111 return this;
108 }
112 }
109
113
110 public IPromise On(Action success) {
114 public IPromise On(Action success) {
111 AddHandler(new HandlerDescriptor(success, null, null));
115 AddHandler(new HandlerDescriptor(success, null, null));
112 return this;
116 return this;
113 }
117 }
114
118
115 public IPromise On(Action handler, PromiseEventType events) {
119 public IPromise On(Action handler, PromiseEventType events) {
116 AddHandler(new HandlerDescriptor(handler,events));
120 AddHandler(new HandlerDescriptor(handler,events));
117 return this;
121 return this;
118 }
122 }
119
123
120 public IPromise<T> Cast<T>() {
124 public IPromise<T> Cast<T>() {
121 throw new InvalidCastException();
125 throw new InvalidCastException();
122 }
126 }
123
127
124 public void Join() {
128 public void Join() {
125 WaitResult(-1);
129 WaitResult(-1);
126 }
130 }
127
131
128 public void Join(int timeout) {
132 public void Join(int timeout) {
129 WaitResult(timeout);
133 WaitResult(timeout);
130 }
134 }
131
135
132 protected void SetResult() {
136 protected void SetResult() {
133 BeginSetResult();
137 BeginSetResult();
134 EndSetResult();
138 EndSetResult();
135 }
139 }
136 }
140 }
137 }
141 }
138
142
@@ -1,202 +1,206
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3
3
4 namespace Implab {
4 namespace Implab {
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
6 public struct HandlerDescriptor {
6 public struct HandlerDescriptor {
7 readonly Action m_handler;
7 readonly Action m_handler;
8 readonly Action<T> m_success;
8 readonly Action<T> m_success;
9 readonly Action<Exception> m_error;
9 readonly Action<Exception> m_error;
10 readonly Action<Exception> m_cancel;
10 readonly Action<Exception> m_cancel;
11 readonly PromiseEventType m_mask;
11 readonly PromiseEventType m_mask;
12
12
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
14 m_success = success;
14 m_success = success;
15 m_error = error;
15 m_error = error;
16 m_cancel = cancel;
16 m_cancel = cancel;
17
17
18 m_handler = null;
18 m_handler = null;
19 m_mask = 0;
19 m_mask = 0;
20 }
20 }
21
21
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
23 m_handler = success;
23 m_handler = success;
24 m_success = null;
24 m_success = null;
25 m_error = error;
25 m_error = error;
26 m_cancel = cancel;
26 m_cancel = cancel;
27 m_mask = PromiseEventType.Success;
27 m_mask = PromiseEventType.Success;
28 }
28 }
29
29
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
31 m_handler = handler;
31 m_handler = handler;
32 m_mask = mask;
32 m_mask = mask;
33 m_success = null;
33 m_success = null;
34 m_error = null;
34 m_error = null;
35 m_cancel = null;
35 m_cancel = null;
36 }
36 }
37
37
38 public void SignalSuccess(T result) {
38 public void SignalSuccess(T result) {
39 if (m_success != null) {
39 if (m_success != null) {
40 try {
40 try {
41 m_success(result);
41 m_success(result);
42 } catch(Exception err) {
42 } catch(Exception err) {
43 SignalError(err);
43 SignalError(err);
44 }
44 }
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
46 try {
46 try {
47 m_handler();
47 m_handler();
48 } catch(Exception err) {
48 } catch(Exception err) {
49 // avoid calling handler twice in case of error
49 // avoid calling handler twice in case of error
50 if (m_error != null)
50 if (m_error != null)
51 SignalError(err);
51 SignalError(err);
52 }
52 }
53 }
53 }
54 }
54 }
55
55
56 public void SignalError(Exception err) {
56 public void SignalError(Exception err) {
57 if (m_error != null) {
57 if (m_error != null) {
58 try {
58 try {
59 m_error(err);
59 m_error(err);
60 // Analysis disable once EmptyGeneralCatchClause
60 // Analysis disable once EmptyGeneralCatchClause
61 } catch {
61 } catch {
62 }
62 }
63 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
63 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
64 try {
64 try {
65 m_handler();
65 m_handler();
66 // Analysis disable once EmptyGeneralCatchClause
66 // Analysis disable once EmptyGeneralCatchClause
67 } catch {
67 } catch {
68 }
68 }
69 }
69 }
70 }
70 }
71
71
72 public void SignalCancel(Exception reason) {
72 public void SignalCancel(Exception reason) {
73 if (m_cancel != null) {
73 if (m_cancel != null) {
74 try {
74 try {
75 m_cancel(reason);
75 m_cancel(reason);
76 } catch (Exception err) {
76 } catch (Exception err) {
77 SignalError(err);
77 SignalError(err);
78 }
78 }
79 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
79 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
80 try {
80 try {
81 m_handler();
81 m_handler();
82 // Analysis disable once EmptyGeneralCatchClause
82 // Analysis disable once EmptyGeneralCatchClause
83 } catch {
83 } catch {
84 }
84 }
85 }
85 }
86 }
86 }
87 }
87 }
88
88
89 public Type PromiseType {
89 public Type PromiseType {
90 get {
90 get {
91 return typeof(T);
91 return typeof(T);
92 }
92 }
93 }
93 }
94
94
95 public T Join() {
95 public T Join() {
96 WaitResult(-1);
96 WaitResult(-1);
97 return m_result;
97 return m_result;
98 }
98 }
99 public T Join(int timeout) {
99 public T Join(int timeout) {
100 WaitResult(timeout);
100 WaitResult(timeout);
101 return m_result;
101 return m_result;
102 }
102 }
103
103
104 void IPromise.Join() {
104 void IPromise.Join() {
105 WaitResult(-1);
105 WaitResult(-1);
106 }
106 }
107 void IPromise.Join(int timeout) {
107 void IPromise.Join(int timeout) {
108 WaitResult(timeout);
108 WaitResult(timeout);
109 }
109 }
110
110
111 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
111 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
112 AddHandler(new HandlerDescriptor(success, error, cancel));
112 AddHandler(new HandlerDescriptor(success, error, cancel));
113 return this;
113 return this;
114 }
114 }
115
115
116 public IPromise<T> On(Action<T> success, Action<Exception> error) {
116 public IPromise<T> On(Action<T> success, Action<Exception> error) {
117 AddHandler(new HandlerDescriptor(success, error, null));
117 AddHandler(new HandlerDescriptor(success, error, null));
118 return this;
118 return this;
119 }
119 }
120
120
121 public IPromise<T> On(Action<T> success) {
121 public IPromise<T> On(Action<T> success) {
122 AddHandler(new HandlerDescriptor(success, null, null));
122 AddHandler(new HandlerDescriptor(success, null, null));
123 return this;
123 return this;
124 }
124 }
125
125
126 public IPromise<T> On(Action handler, PromiseEventType events) {
126 public IPromise<T> On(Action handler, PromiseEventType events) {
127 AddHandler(new HandlerDescriptor(handler, events));
127 AddHandler(new HandlerDescriptor(handler, events));
128 return this;
128 return this;
129 }
129 }
130
130
131 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
131 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
132 AddHandler(new HandlerDescriptor(success, error, cancel));
132 AddHandler(new HandlerDescriptor(success, error, cancel));
133 return this;
133 return this;
134 }
134 }
135
135
136 public IPromise<T> On(Action success, Action<Exception> error) {
136 public IPromise<T> On(Action success, Action<Exception> error) {
137 AddHandler(new HandlerDescriptor(success, error, null));
137 AddHandler(new HandlerDescriptor(success, error, null));
138 return this;
138 return this;
139 }
139 }
140
140
141 public IPromise<T> On(Action success) {
141 public IPromise<T> On(Action success) {
142 AddHandler(new HandlerDescriptor(success, null, null));
142 AddHandler(new HandlerDescriptor(success, null, null));
143 return this;
143 return this;
144 }
144 }
145
145
146 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
146 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
147 AddHandler(new HandlerDescriptor(success, error, cancel));
147 AddHandler(new HandlerDescriptor(success, error, cancel));
148 return this;
148 return this;
149 }
149 }
150
150
151 IPromise IPromise.On(Action success, Action<Exception> error) {
151 IPromise IPromise.On(Action success, Action<Exception> error) {
152 AddHandler(new HandlerDescriptor(success, error, null));
152 AddHandler(new HandlerDescriptor(success, error, null));
153 return this;
153 return this;
154 }
154 }
155
155
156 IPromise IPromise.On(Action success) {
156 IPromise IPromise.On(Action success) {
157 AddHandler(new HandlerDescriptor(success, null, null));
157 AddHandler(new HandlerDescriptor(success, null, null));
158 return this;
158 return this;
159 }
159 }
160
160
161 IPromise IPromise.On(Action handler, PromiseEventType events) {
161 IPromise IPromise.On(Action handler, PromiseEventType events) {
162 AddHandler(new HandlerDescriptor(handler, events));
162 AddHandler(new HandlerDescriptor(handler, events));
163 return this;
163 return this;
164 }
164 }
165
165
166 public IPromise<T2> Cast<T2>() {
166 public IPromise<T2> Cast<T2>() {
167 return (IPromise<T2>)this;
167 return (IPromise<T2>)this;
168 }
168 }
169
169
170 #region implemented abstract members of AbstractPromise
170 #region implemented abstract members of AbstractPromise
171
171
172 protected override Signal GetResolveSignal() {
172 protected override Signal GetResolveSignal() {
173 var signal = new Signal();
173 var signal = new Signal();
174 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
174 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
175 return signal;
175 return signal;
176 }
176 }
177
177
178 protected override void SignalSuccess(HandlerDescriptor handler) {
178 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
179 handler.SignalSuccess(m_result);
179 switch (signal) {
180 }
180 case SUCCEEDED_STATE:
181
181 handler.SignalSuccess(m_result);
182 protected override void SignalError(HandlerDescriptor handler, Exception error) {
182 break;
183 handler.SignalError(error);
183 case REJECTED_STATE:
184 }
184 handler.SignalError(Error);
185
185 break;
186 protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) {
186 case CANCELLED_STATE:
187 handler.SignalCancel(reason);
187 handler.SignalCancel(CancellationReason);
188 break;
189 default:
190 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
191 }
188 }
192 }
189
193
190 #endregion
194 #endregion
191
195
192 T m_result;
196 T m_result;
193
197
194 protected void SetResult(T value) {
198 protected void SetResult(T value) {
195 if (BeginSetResult()) {
199 if (BeginSetResult()) {
196 m_result = value;
200 m_result = value;
197 EndSetResult();
201 EndSetResult();
198 }
202 }
199 }
203 }
200 }
204 }
201 }
205 }
202
206
@@ -1,13 +1,14
1 namespace Implab.Components {
1 namespace Implab.Components {
2
2
3 public enum ExecutionState {
3 public enum ExecutionState {
4 Reserved = 0,
4 Uninitialized,
5 Uninitialized,
5 Initial,
6 Ready,
6 Starting,
7 Starting,
7 Running,
8 Running,
8 Stopping,
9 Stopping,
9 Stopped,
10 Stopped,
10 Disposed,
11 Disposed,
11 Failed
12 Failed
12 }
13 }
13 } No newline at end of file
14 }
@@ -1,260 +1,262
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 <ProductVersion>8.0.30703</ProductVersion>
10 <ProductVersion>8.0.30703</ProductVersion>
11 <SchemaVersion>2.0</SchemaVersion>
11 <SchemaVersion>2.0</SchemaVersion>
12 <ReleaseVersion>0.2</ReleaseVersion>
12 <ReleaseVersion>0.2</ReleaseVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
14 </PropertyGroup>
14 </PropertyGroup>
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
17 <DebugType>full</DebugType>
17 <DebugType>full</DebugType>
18 <Optimize>false</Optimize>
18 <Optimize>false</Optimize>
19 <OutputPath>bin\Debug</OutputPath>
19 <OutputPath>bin\Debug</OutputPath>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
21 <ErrorReport>prompt</ErrorReport>
21 <ErrorReport>prompt</ErrorReport>
22 <WarningLevel>4</WarningLevel>
22 <WarningLevel>4</WarningLevel>
23 <ConsolePause>false</ConsolePause>
23 <ConsolePause>false</ConsolePause>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
25 </PropertyGroup>
25 </PropertyGroup>
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27 <DebugType>full</DebugType>
27 <DebugType>full</DebugType>
28 <Optimize>true</Optimize>
28 <Optimize>true</Optimize>
29 <OutputPath>bin\Release</OutputPath>
29 <OutputPath>bin\Release</OutputPath>
30 <ErrorReport>prompt</ErrorReport>
30 <ErrorReport>prompt</ErrorReport>
31 <WarningLevel>4</WarningLevel>
31 <WarningLevel>4</WarningLevel>
32 <ConsolePause>false</ConsolePause>
32 <ConsolePause>false</ConsolePause>
33 </PropertyGroup>
33 </PropertyGroup>
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
35 <DebugSymbols>true</DebugSymbols>
35 <DebugSymbols>true</DebugSymbols>
36 <DebugType>full</DebugType>
36 <DebugType>full</DebugType>
37 <Optimize>false</Optimize>
37 <Optimize>false</Optimize>
38 <OutputPath>bin\Debug</OutputPath>
38 <OutputPath>bin\Debug</OutputPath>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
40 <ErrorReport>prompt</ErrorReport>
40 <ErrorReport>prompt</ErrorReport>
41 <WarningLevel>4</WarningLevel>
41 <WarningLevel>4</WarningLevel>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
43 <ConsolePause>false</ConsolePause>
43 <ConsolePause>false</ConsolePause>
44 </PropertyGroup>
44 </PropertyGroup>
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
46 <Optimize>true</Optimize>
46 <Optimize>true</Optimize>
47 <OutputPath>bin\Release</OutputPath>
47 <OutputPath>bin\Release</OutputPath>
48 <ErrorReport>prompt</ErrorReport>
48 <ErrorReport>prompt</ErrorReport>
49 <WarningLevel>4</WarningLevel>
49 <WarningLevel>4</WarningLevel>
50 <ConsolePause>false</ConsolePause>
50 <ConsolePause>false</ConsolePause>
51 <DefineConstants>NET_4_5</DefineConstants>
51 <DefineConstants>NET_4_5</DefineConstants>
52 </PropertyGroup>
52 </PropertyGroup>
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
54 <DebugSymbols>true</DebugSymbols>
54 <DebugSymbols>true</DebugSymbols>
55 <DebugType>full</DebugType>
55 <DebugType>full</DebugType>
56 <Optimize>false</Optimize>
56 <Optimize>false</Optimize>
57 <OutputPath>bin\Debug</OutputPath>
57 <OutputPath>bin\Debug</OutputPath>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
59 <ErrorReport>prompt</ErrorReport>
59 <ErrorReport>prompt</ErrorReport>
60 <WarningLevel>4</WarningLevel>
60 <WarningLevel>4</WarningLevel>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
62 <ConsolePause>false</ConsolePause>
62 <ConsolePause>false</ConsolePause>
63 </PropertyGroup>
63 </PropertyGroup>
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
65 <Optimize>true</Optimize>
65 <Optimize>true</Optimize>
66 <OutputPath>bin\Release</OutputPath>
66 <OutputPath>bin\Release</OutputPath>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
68 <ErrorReport>prompt</ErrorReport>
68 <ErrorReport>prompt</ErrorReport>
69 <WarningLevel>4</WarningLevel>
69 <WarningLevel>4</WarningLevel>
70 <ConsolePause>false</ConsolePause>
70 <ConsolePause>false</ConsolePause>
71 </PropertyGroup>
71 </PropertyGroup>
72 <ItemGroup>
72 <ItemGroup>
73 <Reference Include="System" />
73 <Reference Include="System" />
74 <Reference Include="System.Xml" />
74 <Reference Include="System.Xml" />
75 <Reference Include="mscorlib" />
75 <Reference Include="mscorlib" />
76 </ItemGroup>
76 </ItemGroup>
77 <ItemGroup>
77 <ItemGroup>
78 <Compile Include="CustomEqualityComparer.cs" />
78 <Compile Include="CustomEqualityComparer.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
80 <Compile Include="Diagnostics\EventText.cs" />
80 <Compile Include="Diagnostics\EventText.cs" />
81 <Compile Include="Diagnostics\LogChannel.cs" />
81 <Compile Include="Diagnostics\LogChannel.cs" />
82 <Compile Include="Diagnostics\LogicalOperation.cs" />
82 <Compile Include="Diagnostics\LogicalOperation.cs" />
83 <Compile Include="Diagnostics\TextFileListener.cs" />
83 <Compile Include="Diagnostics\TextFileListener.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
87 <Compile Include="ICancellable.cs" />
87 <Compile Include="ICancellable.cs" />
88 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressHandler.cs" />
89 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IProgressNotifier.cs" />
90 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromiseT.cs" />
91 <Compile Include="IPromise.cs" />
91 <Compile Include="IPromise.cs" />
92 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="IServiceLocator.cs" />
93 <Compile Include="ITaskController.cs" />
93 <Compile Include="ITaskController.cs" />
94 <Compile Include="JSON\JSONElementContext.cs" />
94 <Compile Include="JSON\JSONElementContext.cs" />
95 <Compile Include="JSON\JSONElementType.cs" />
95 <Compile Include="JSON\JSONElementType.cs" />
96 <Compile Include="JSON\JSONGrammar.cs" />
96 <Compile Include="JSON\JSONGrammar.cs" />
97 <Compile Include="JSON\JSONParser.cs" />
97 <Compile Include="JSON\JSONParser.cs" />
98 <Compile Include="JSON\JSONScanner.cs" />
98 <Compile Include="JSON\JSONScanner.cs" />
99 <Compile Include="JSON\JsonTokenType.cs" />
99 <Compile Include="JSON\JsonTokenType.cs" />
100 <Compile Include="JSON\JSONWriter.cs" />
100 <Compile Include="JSON\JSONWriter.cs" />
101 <Compile Include="JSON\JSONXmlReader.cs" />
101 <Compile Include="JSON\JSONXmlReader.cs" />
102 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
102 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
103 <Compile Include="JSON\StringTranslator.cs" />
103 <Compile Include="JSON\StringTranslator.cs" />
104 <Compile Include="Parallels\DispatchPool.cs" />
104 <Compile Include="Parallels\DispatchPool.cs" />
105 <Compile Include="Parallels\ArrayTraits.cs" />
105 <Compile Include="Parallels\ArrayTraits.cs" />
106 <Compile Include="Parallels\MTQueue.cs" />
106 <Compile Include="Parallels\MTQueue.cs" />
107 <Compile Include="Parallels\WorkerPool.cs" />
107 <Compile Include="Parallels\WorkerPool.cs" />
108 <Compile Include="Parsing\Alphabet.cs" />
108 <Compile Include="Parsing\Alphabet.cs" />
109 <Compile Include="Parsing\AlphabetBase.cs" />
109 <Compile Include="Parsing\AlphabetBase.cs" />
110 <Compile Include="Parsing\AltToken.cs" />
110 <Compile Include="Parsing\AltToken.cs" />
111 <Compile Include="Parsing\BinaryToken.cs" />
111 <Compile Include="Parsing\BinaryToken.cs" />
112 <Compile Include="Parsing\CatToken.cs" />
112 <Compile Include="Parsing\CatToken.cs" />
113 <Compile Include="Parsing\CDFADefinition.cs" />
113 <Compile Include="Parsing\CDFADefinition.cs" />
114 <Compile Include="Parsing\DFABuilder.cs" />
114 <Compile Include="Parsing\DFABuilder.cs" />
115 <Compile Include="Parsing\DFADefinitionBase.cs" />
115 <Compile Include="Parsing\DFADefinitionBase.cs" />
116 <Compile Include="Parsing\DFAStateDescriptor.cs" />
116 <Compile Include="Parsing\DFAStateDescriptor.cs" />
117 <Compile Include="Parsing\DFAutomaton.cs" />
117 <Compile Include="Parsing\DFAutomaton.cs" />
118 <Compile Include="Parsing\EDFADefinition.cs" />
118 <Compile Include="Parsing\EDFADefinition.cs" />
119 <Compile Include="Parsing\EmptyToken.cs" />
119 <Compile Include="Parsing\EmptyToken.cs" />
120 <Compile Include="Parsing\EndToken.cs" />
120 <Compile Include="Parsing\EndToken.cs" />
121 <Compile Include="Parsing\EnumAlphabet.cs" />
121 <Compile Include="Parsing\EnumAlphabet.cs" />
122 <Compile Include="Parsing\Grammar.cs" />
122 <Compile Include="Parsing\Grammar.cs" />
123 <Compile Include="Parsing\IAlphabet.cs" />
123 <Compile Include="Parsing\IAlphabet.cs" />
124 <Compile Include="Parsing\IDFADefinition.cs" />
124 <Compile Include="Parsing\IDFADefinition.cs" />
125 <Compile Include="Parsing\IVisitor.cs" />
125 <Compile Include="Parsing\IVisitor.cs" />
126 <Compile Include="Parsing\ParserException.cs" />
126 <Compile Include="Parsing\ParserException.cs" />
127 <Compile Include="Parsing\Scanner.cs" />
127 <Compile Include="Parsing\Scanner.cs" />
128 <Compile Include="Parsing\StarToken.cs" />
128 <Compile Include="Parsing\StarToken.cs" />
129 <Compile Include="Parsing\SymbolToken.cs" />
129 <Compile Include="Parsing\SymbolToken.cs" />
130 <Compile Include="Parsing\Token.cs" />
130 <Compile Include="Parsing\Token.cs" />
131 <Compile Include="ProgressInitEventArgs.cs" />
131 <Compile Include="ProgressInitEventArgs.cs" />
132 <Compile Include="Properties\AssemblyInfo.cs" />
132 <Compile Include="Properties\AssemblyInfo.cs" />
133 <Compile Include="Parallels\AsyncPool.cs" />
133 <Compile Include="Parallels\AsyncPool.cs" />
134 <Compile Include="Safe.cs" />
134 <Compile Include="Safe.cs" />
135 <Compile Include="ValueEventArgs.cs" />
135 <Compile Include="ValueEventArgs.cs" />
136 <Compile Include="PromiseExtensions.cs" />
136 <Compile Include="PromiseExtensions.cs" />
137 <Compile Include="SyncContextPromise.cs" />
137 <Compile Include="SyncContextPromise.cs" />
138 <Compile Include="Diagnostics\OperationContext.cs" />
138 <Compile Include="Diagnostics\OperationContext.cs" />
139 <Compile Include="Diagnostics\TraceContext.cs" />
139 <Compile Include="Diagnostics\TraceContext.cs" />
140 <Compile Include="Diagnostics\LogEventArgs.cs" />
140 <Compile Include="Diagnostics\LogEventArgs.cs" />
141 <Compile Include="Diagnostics\LogEventArgsT.cs" />
141 <Compile Include="Diagnostics\LogEventArgsT.cs" />
142 <Compile Include="Diagnostics\Extensions.cs" />
142 <Compile Include="Diagnostics\Extensions.cs" />
143 <Compile Include="PromiseEventType.cs" />
143 <Compile Include="PromiseEventType.cs" />
144 <Compile Include="Parallels\AsyncQueue.cs" />
144 <Compile Include="Parallels\AsyncQueue.cs" />
145 <Compile Include="PromiseT.cs" />
145 <Compile Include="PromiseT.cs" />
146 <Compile Include="IDeferred.cs" />
146 <Compile Include="IDeferred.cs" />
147 <Compile Include="IDeferredT.cs" />
147 <Compile Include="IDeferredT.cs" />
148 <Compile Include="Promise.cs" />
148 <Compile Include="Promise.cs" />
149 <Compile Include="PromiseTransientException.cs" />
149 <Compile Include="PromiseTransientException.cs" />
150 <Compile Include="Parallels\Signal.cs" />
150 <Compile Include="Parallels\Signal.cs" />
151 <Compile Include="Parallels\SharedLock.cs" />
151 <Compile Include="Parallels\SharedLock.cs" />
152 <Compile Include="Diagnostics\ILogWriter.cs" />
152 <Compile Include="Diagnostics\ILogWriter.cs" />
153 <Compile Include="Diagnostics\ListenerBase.cs" />
153 <Compile Include="Diagnostics\ListenerBase.cs" />
154 <Compile Include="Parallels\BlockingQueue.cs" />
154 <Compile Include="Parallels\BlockingQueue.cs" />
155 <Compile Include="AbstractEvent.cs" />
155 <Compile Include="AbstractEvent.cs" />
156 <Compile Include="AbstractPromise.cs" />
156 <Compile Include="AbstractPromise.cs" />
157 <Compile Include="AbstractPromiseT.cs" />
157 <Compile Include="AbstractPromiseT.cs" />
158 <Compile Include="FuncTask.cs" />
158 <Compile Include="FuncTask.cs" />
159 <Compile Include="FuncTaskBase.cs" />
159 <Compile Include="FuncTaskBase.cs" />
160 <Compile Include="FuncTaskT.cs" />
160 <Compile Include="FuncTaskT.cs" />
161 <Compile Include="ActionChainTaskBase.cs" />
161 <Compile Include="ActionChainTaskBase.cs" />
162 <Compile Include="ActionChainTask.cs" />
162 <Compile Include="ActionChainTask.cs" />
163 <Compile Include="ActionChainTaskT.cs" />
163 <Compile Include="ActionChainTaskT.cs" />
164 <Compile Include="FuncChainTaskBase.cs" />
164 <Compile Include="FuncChainTaskBase.cs" />
165 <Compile Include="FuncChainTask.cs" />
165 <Compile Include="FuncChainTask.cs" />
166 <Compile Include="FuncChainTaskT.cs" />
166 <Compile Include="FuncChainTaskT.cs" />
167 <Compile Include="ActionTaskBase.cs" />
167 <Compile Include="ActionTaskBase.cs" />
168 <Compile Include="ActionTask.cs" />
168 <Compile Include="ActionTask.cs" />
169 <Compile Include="ActionTaskT.cs" />
169 <Compile Include="ActionTaskT.cs" />
170 <Compile Include="ICancellationToken.cs" />
170 <Compile Include="ICancellationToken.cs" />
171 <Compile Include="SuccessPromise.cs" />
171 <Compile Include="SuccessPromise.cs" />
172 <Compile Include="SuccessPromiseT.cs" />
172 <Compile Include="SuccessPromiseT.cs" />
173 <Compile Include="PromiseAwaiterT.cs" />
173 <Compile Include="PromiseAwaiterT.cs" />
174 <Compile Include="PromiseAwaiter.cs" />
174 <Compile Include="PromiseAwaiter.cs" />
175 <Compile Include="Components\ComponentContainer.cs" />
175 <Compile Include="Components\ComponentContainer.cs" />
176 <Compile Include="Components\Disposable.cs" />
176 <Compile Include="Components\Disposable.cs" />
177 <Compile Include="Components\DisposablePool.cs" />
177 <Compile Include="Components\DisposablePool.cs" />
178 <Compile Include="Components\ObjectPool.cs" />
178 <Compile Include="Components\ObjectPool.cs" />
179 <Compile Include="Components\ServiceLocator.cs" />
179 <Compile Include="Components\ServiceLocator.cs" />
180 <Compile Include="Components\IInitializable.cs" />
180 <Compile Include="Components\IInitializable.cs" />
181 <Compile Include="TaskController.cs" />
181 <Compile Include="TaskController.cs" />
182 <Compile Include="Components\App.cs" />
182 <Compile Include="Components\App.cs" />
183 <Compile Include="Components\IRunnable.cs" />
183 <Compile Include="Components\IRunnable.cs" />
184 <Compile Include="Components\ExecutionState.cs" />
184 <Compile Include="Components\ExecutionState.cs" />
185 <Compile Include="Components\RunnableComponent.cs" />
186 <Compile Include="Components\IFactory.cs" />
185 </ItemGroup>
187 </ItemGroup>
186 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
188 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
187 <ItemGroup />
189 <ItemGroup />
188 <ProjectExtensions>
190 <ProjectExtensions>
189 <MonoDevelop>
191 <MonoDevelop>
190 <Properties>
192 <Properties>
191 <Policies>
193 <Policies>
192 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
194 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
193 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
195 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
194 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
196 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
195 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
197 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
196 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
198 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
197 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
199 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
198 <NameConventionPolicy>
200 <NameConventionPolicy>
199 <Rules>
201 <Rules>
200 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
202 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
201 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
203 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
202 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
204 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
203 <RequiredPrefixes>
205 <RequiredPrefixes>
204 <String>I</String>
206 <String>I</String>
205 </RequiredPrefixes>
207 </RequiredPrefixes>
206 </NamingRule>
208 </NamingRule>
207 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
209 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
208 <RequiredSuffixes>
210 <RequiredSuffixes>
209 <String>Attribute</String>
211 <String>Attribute</String>
210 </RequiredSuffixes>
212 </RequiredSuffixes>
211 </NamingRule>
213 </NamingRule>
212 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
214 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
213 <RequiredSuffixes>
215 <RequiredSuffixes>
214 <String>EventArgs</String>
216 <String>EventArgs</String>
215 </RequiredSuffixes>
217 </RequiredSuffixes>
216 </NamingRule>
218 </NamingRule>
217 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
219 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
218 <RequiredSuffixes>
220 <RequiredSuffixes>
219 <String>Exception</String>
221 <String>Exception</String>
220 </RequiredSuffixes>
222 </RequiredSuffixes>
221 </NamingRule>
223 </NamingRule>
222 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
224 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
223 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
225 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
224 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
226 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
225 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
227 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
226 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
228 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
227 <RequiredPrefixes>
229 <RequiredPrefixes>
228 <String>m_</String>
230 <String>m_</String>
229 </RequiredPrefixes>
231 </RequiredPrefixes>
230 </NamingRule>
232 </NamingRule>
231 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
233 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
232 <RequiredPrefixes>
234 <RequiredPrefixes>
233 <String>_</String>
235 <String>_</String>
234 </RequiredPrefixes>
236 </RequiredPrefixes>
235 </NamingRule>
237 </NamingRule>
236 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
238 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
237 <RequiredPrefixes>
239 <RequiredPrefixes>
238 <String>m_</String>
240 <String>m_</String>
239 </RequiredPrefixes>
241 </RequiredPrefixes>
240 </NamingRule>
242 </NamingRule>
241 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
243 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
242 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
244 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
243 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
245 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
244 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
246 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
245 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
247 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
246 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
248 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
247 <RequiredPrefixes>
249 <RequiredPrefixes>
248 <String>T</String>
250 <String>T</String>
249 </RequiredPrefixes>
251 </RequiredPrefixes>
250 </NamingRule>
252 </NamingRule>
251 </Rules>
253 </Rules>
252 </NameConventionPolicy>
254 </NameConventionPolicy>
253 </Policies>
255 </Policies>
254 </Properties>
256 </Properties>
255 </MonoDevelop>
257 </MonoDevelop>
256 </ProjectExtensions>
258 </ProjectExtensions>
257 <ItemGroup>
259 <ItemGroup>
258 <Folder Include="Components\" />
260 <Folder Include="Components\" />
259 </ItemGroup>
261 </ItemGroup>
260 </Project> No newline at end of file
262 </Project>
@@ -1,103 +1,99
1 using Implab.Parsing;
1 using Implab.Parsing;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
2 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
3
8 namespace Implab.JSON {
4 namespace Implab.JSON {
9 internal class JSONGrammar : Grammar<JSONGrammar> {
5 class JSONGrammar : Grammar<JSONGrammar> {
10 public enum TokenType : int {
6 public enum TokenType {
11 None,
7 None,
12 BeginObject,
8 BeginObject,
13 EndObject,
9 EndObject,
14 BeginArray,
10 BeginArray,
15 EndArray,
11 EndArray,
16 String,
12 String,
17 Number,
13 Number,
18 Literal,
14 Literal,
19 NameSeparator,
15 NameSeparator,
20 ValueSeparator,
16 ValueSeparator,
21
17
22 StringBound,
18 StringBound,
23 EscapedChar,
19 EscapedChar,
24 UnescapedChar,
20 UnescapedChar,
25 EscapedUnicode,
21 EscapedUnicode,
26
22
27 Minus,
23 Minus,
28 Plus,
24 Plus,
29 Sign,
25 Sign,
30 Integer,
26 Integer,
31 Dot,
27 Dot,
32 Exp
28 Exp
33 }
29 }
34
30
35 readonly CDFADefinition m_jsonDFA;
31 readonly CDFADefinition m_jsonDFA;
36 readonly CDFADefinition m_stringDFA;
32 readonly CDFADefinition m_stringDFA;
37
33
38 public JSONGrammar() {
34 public JSONGrammar() {
39 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
35 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
40 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
36 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
41 var digit9 = SymbolRangeToken('1', '9');
37 var digit9 = SymbolRangeToken('1', '9');
42 var zero = SymbolToken('0');
38 var zero = SymbolToken('0');
43 var digit = zero.Or(digit9);
39 var digit = zero.Or(digit9);
44 var dot = SymbolToken('.');
40 var dot = SymbolToken('.');
45 var minus = SymbolToken('-');
41 var minus = SymbolToken('-');
46 var sign = SymbolSetToken('-', '+');
42 var sign = SymbolSetToken('-', '+');
47 var expSign = SymbolSetToken('e', 'E');
43 var expSign = SymbolSetToken('e', 'E');
48 var letters = SymbolRangeToken('a', 'z');
44 var letters = SymbolRangeToken('a', 'z');
49 var integer = zero.Or(digit9.Cat(digit.EClosure()));
45 var integer = zero.Or(digit9.Cat(digit.EClosure()));
50 var frac = dot.Cat(digit.Closure());
46 var frac = dot.Cat(digit.Closure());
51 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
47 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
52 var quote = SymbolToken('"');
48 var quote = SymbolToken('"');
53 var backSlash = SymbolToken('\\');
49 var backSlash = SymbolToken('\\');
54 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
50 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
55 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
51 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
56 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
52 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
57 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
53 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
58 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
54 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
59 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
55 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
60 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
56 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
61 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
57 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
62 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
58 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
63
59
64 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
60 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
65 var literal = letters.Closure();
61 var literal = letters.Closure();
66 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
62 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
67
63
68 var jsonExpression =
64 var jsonExpression =
69 number.Tag(TokenType.Number)
65 number.Tag(TokenType.Number)
70 .Or(literal.Tag(TokenType.Literal))
66 .Or(literal.Tag(TokenType.Literal))
71 .Or(quote.Tag(TokenType.StringBound))
67 .Or(quote.Tag(TokenType.StringBound))
72 .Or(beginObject.Tag(TokenType.BeginObject))
68 .Or(beginObject.Tag(TokenType.BeginObject))
73 .Or(endObject.Tag(TokenType.EndObject))
69 .Or(endObject.Tag(TokenType.EndObject))
74 .Or(beginArray.Tag(TokenType.BeginArray))
70 .Or(beginArray.Tag(TokenType.BeginArray))
75 .Or(endArray.Tag(TokenType.EndArray))
71 .Or(endArray.Tag(TokenType.EndArray))
76 .Or(nameSep.Tag(TokenType.NameSeparator))
72 .Or(nameSep.Tag(TokenType.NameSeparator))
77 .Or(valueSep.Tag(TokenType.ValueSeparator));
73 .Or(valueSep.Tag(TokenType.ValueSeparator));
78
74
79
75
80 var jsonStringExpression =
76 var jsonStringExpression =
81 quote.Tag(TokenType.StringBound)
77 quote.Tag(TokenType.StringBound)
82 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
78 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
83 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
79 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
84 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
80 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
85
81
86
82
87 m_jsonDFA = BuildDFA(jsonExpression);
83 m_jsonDFA = BuildDFA(jsonExpression);
88 m_stringDFA = BuildDFA(jsonStringExpression);
84 m_stringDFA = BuildDFA(jsonStringExpression);
89 }
85 }
90
86
91 public CDFADefinition JsonDFA {
87 public CDFADefinition JsonDFA {
92 get {
88 get {
93 return m_jsonDFA;
89 return m_jsonDFA;
94 }
90 }
95 }
91 }
96
92
97 public CDFADefinition JsonStringDFA {
93 public CDFADefinition JsonStringDFA {
98 get {
94 get {
99 return m_stringDFA;
95 return m_stringDFA;
100 }
96 }
101 }
97 }
102 }
98 }
103 }
99 }
@@ -1,283 +1,277
1 using Implab;
1 using Implab.Parsing;
2 using Implab.Parsing;
3 using System;
2 using System;
4 using System.Collections.Generic;
5 using System.Diagnostics;
3 using System.Diagnostics;
6 using System.IO;
4 using System.IO;
7 using System.Linq;
8 using System.Text;
9 using System.Threading.Tasks;
10
5
11 namespace Implab.JSON {
6 namespace Implab.JSON {
12 /// <summary>
7 /// <summary>
13 /// internal
8 /// internal
14 /// </summary>
9 /// </summary>
15 public struct JSONParserContext {
10 public struct JSONParserContext {
16 public string memberName;
11 public string memberName;
17 public JSONElementContext elementContext;
12 public JSONElementContext elementContext;
18 }
13 }
19
14
20 /// <summary>
15 /// <summary>
21 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
16 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
22 /// </summary>
17 /// </summary>
23 /// <remarks>
18 /// <remarks>
24 /// Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΡŽ свойства <see cref="Level"/>,
19 /// Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΡŽ свойства <see cref="Level"/>,
25 /// ΠΎΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ
20 /// ΠΎΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ
26 /// элСмСнт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ массива ΠΈΠΌΠ΅Π΅Ρ‚ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ мСньшС, Ρ‡Π΅ΠΌ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
21 /// элСмСнт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ массива ΠΈΠΌΠ΅Π΅Ρ‚ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ мСньшС, Ρ‡Π΅ΠΌ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
27 /// <code>
22 /// <code>
28 /// { // Level = 1
23 /// { // Level = 1
29 /// "name" : "Peter", // Level = 1
24 /// "name" : "Peter", // Level = 1
30 /// "address" : { // Level = 2
25 /// "address" : { // Level = 2
31 /// city : "Stern" // Level = 2
26 /// city : "Stern" // Level = 2
32 /// } // Level = 1
27 /// } // Level = 1
33 /// } // Level = 0
28 /// } // Level = 0
34 /// </code>
29 /// </code>
35 /// </remarks>
30 /// </remarks>
36 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
31 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
37
32
38 enum MemberContext {
33 enum MemberContext {
39 MemberName,
34 MemberName,
40 MemberValue
35 MemberValue
41 }
36 }
42
37
43 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
38 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
44 static readonly DFAStateDescriptior[] _jsonDFA;
39 static readonly DFAStateDescriptior[] _jsonDFA;
45 static readonly DFAStateDescriptior[] _objectDFA;
40 static readonly DFAStateDescriptior[] _objectDFA;
46 static readonly DFAStateDescriptior[] _arrayDFA;
41 static readonly DFAStateDescriptior[] _arrayDFA;
47
42
48 static JSONParser() {
43 static JSONParser() {
49
44
50
45
51 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
46 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
52 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
47 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
53
48
54 var objectExpression = memberExpression
49 var objectExpression = memberExpression
55 .Cat(
50 .Cat(
56 Token.New(JsonTokenType.ValueSeparator)
51 Token.New(JsonTokenType.ValueSeparator)
57 .Cat(memberExpression)
52 .Cat(memberExpression)
58 .EClosure()
53 .EClosure()
59 )
54 )
60 .Optional()
55 .Optional()
61 .Cat(Token.New(JsonTokenType.EndObject))
56 .Cat(Token.New(JsonTokenType.EndObject))
62 .Tag(0);
57 .Tag(0);
63 var arrayExpression = valueExpression
58 var arrayExpression = valueExpression
64 .Cat(
59 .Cat(
65 Token.New(JsonTokenType.ValueSeparator)
60 Token.New(JsonTokenType.ValueSeparator)
66 .Cat(valueExpression)
61 .Cat(valueExpression)
67 .EClosure()
62 .EClosure()
68 )
63 )
69 .Optional()
64 .Optional()
70 .Cat(Token.New(JsonTokenType.EndArray))
65 .Cat(Token.New(JsonTokenType.EndArray))
71 .Tag(0);
66 .Tag(0);
72
67
73 var jsonExpression = valueExpression.Tag(0);
68 var jsonExpression = valueExpression.Tag(0);
74
69
75 _jsonDFA = BuildDFA(jsonExpression).States;
70 _jsonDFA = BuildDFA(jsonExpression).States;
76 _objectDFA = BuildDFA(objectExpression).States;
71 _objectDFA = BuildDFA(objectExpression).States;
77 _arrayDFA = BuildDFA(arrayExpression).States;
72 _arrayDFA = BuildDFA(arrayExpression).States;
78 }
73 }
79
74
80 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
75 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
81 var builder = new DFABuilder();
76 var builder = new DFABuilder();
82 var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
77 var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
83 expr.Accept(builder);
78 expr.Accept(builder);
84
79
85 builder.BuildDFA(dfa);
80 builder.BuildDFA(dfa);
86 return dfa;
81 return dfa;
87 }
82 }
88
83
89 JSONScanner m_scanner;
84 JSONScanner m_scanner;
90 MemberContext m_memberContext;
85 MemberContext m_memberContext;
91
86
92 JSONElementType m_elementType;
87 JSONElementType m_elementType;
93 object m_elementValue;
88 object m_elementValue;
94
89
95 /// <summary>
90 /// <summary>
96 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
91 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
97 /// </summary>
92 /// </summary>
98 /// <param name="text"></param>
93 /// <param name="text"></param>
99 public JSONParser(string text)
94 public JSONParser(string text)
100 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
95 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
101 Safe.ArgumentNotEmpty(text, "text");
96 Safe.ArgumentNotEmpty(text, "text");
102 m_scanner = new JSONScanner();
97 m_scanner = new JSONScanner();
103 m_scanner.Feed(text.ToCharArray());
98 m_scanner.Feed(text.ToCharArray());
104 }
99 }
105
100
106 /// <summary>
101 /// <summary>
107 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
102 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
108 /// </summary>
103 /// </summary>
109 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
104 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
110 /// <param name="dispose">ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ парсСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠΎΠ½Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ врСмя ΠΆΠΈΠ·Π½ΠΈ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.</param>
105 /// <param name="dispose">ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ парсСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠΎΠ½Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ врСмя ΠΆΠΈΠ·Π½ΠΈ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.</param>
111 public JSONParser(TextReader reader, bool dispose)
106 public JSONParser(TextReader reader, bool dispose)
112 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
107 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
113 Safe.ArgumentNotNull(reader, "reader");
108 Safe.ArgumentNotNull(reader, "reader");
114 m_scanner = new JSONScanner();
109 m_scanner = new JSONScanner();
115 m_scanner.Feed(reader, dispose);
110 m_scanner.Feed(reader, dispose);
116 }
111 }
117
112
118 /// <summary>
113 /// <summary>
119 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
114 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
120 /// </summary>
115 /// </summary>
121 public JSONElementType ElementType {
116 public JSONElementType ElementType {
122 get { return m_elementType; }
117 get { return m_elementType; }
123 }
118 }
124
119
125 /// <summary>
120 /// <summary>
126 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
121 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
127 /// пустая строка.
122 /// пустая строка.
128 /// </summary>
123 /// </summary>
129 public string ElementName {
124 public string ElementName {
130 get { return m_context.info.memberName; }
125 get { return m_context.info.memberName; }
131 }
126 }
132
127
133 /// <summary>
128 /// <summary>
134 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
129 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
135 /// </summary>
130 /// </summary>
136 public object ElementValue {
131 public object ElementValue {
137 get { return m_elementValue; }
132 get { return m_elementValue; }
138 }
133 }
139
134
140 /// <summary>
135 /// <summary>
141 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
136 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
142 /// </summary>
137 /// </summary>
143 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
138 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
144 public bool Read() {
139 public bool Read() {
145 if (m_context.current == UNREACHEBLE_STATE)
140 if (m_context.current == UNREACHEBLE_STATE)
146 throw new InvalidOperationException("The parser is in invalid state");
141 throw new InvalidOperationException("The parser is in invalid state");
147 object tokenValue;
142 object tokenValue;
148 JsonTokenType tokenType;
143 JsonTokenType tokenType;
149 m_context.info.memberName = String.Empty;
144 m_context.info.memberName = String.Empty;
150 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
145 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
151 Move((int)tokenType);
146 Move((int)tokenType);
152 if (m_context.current == UNREACHEBLE_STATE)
147 if (m_context.current == UNREACHEBLE_STATE)
153 UnexpectedToken(tokenValue, tokenType);
148 UnexpectedToken(tokenValue, tokenType);
154 switch (tokenType) {
149 switch (tokenType) {
155 case JsonTokenType.BeginObject:
150 case JsonTokenType.BeginObject:
156 Switch(
151 Switch(
157 _objectDFA,
152 _objectDFA,
158 INITIAL_STATE,
153 INITIAL_STATE,
159 new JSONParserContext {
154 new JSONParserContext {
160 memberName = m_context.info.memberName,
155 memberName = m_context.info.memberName,
161 elementContext = JSONElementContext.Object
156 elementContext = JSONElementContext.Object
162 }
157 }
163 );
158 );
164 m_elementValue = null;
159 m_elementValue = null;
165 m_memberContext = MemberContext.MemberName;
160 m_memberContext = MemberContext.MemberName;
166 m_elementType = JSONElementType.BeginObject;
161 m_elementType = JSONElementType.BeginObject;
167 return true;
162 return true;
168 case JsonTokenType.EndObject:
163 case JsonTokenType.EndObject:
169 Restore();
164 Restore();
170 m_elementValue = null;
165 m_elementValue = null;
171 m_elementType = JSONElementType.EndObject;
166 m_elementType = JSONElementType.EndObject;
172 return true;
167 return true;
173 case JsonTokenType.BeginArray:
168 case JsonTokenType.BeginArray:
174 Switch(
169 Switch(
175 _arrayDFA,
170 _arrayDFA,
176 INITIAL_STATE,
171 INITIAL_STATE,
177 new JSONParserContext {
172 new JSONParserContext {
178 memberName = m_context.info.memberName,
173 memberName = m_context.info.memberName,
179 elementContext = JSONElementContext.Array
174 elementContext = JSONElementContext.Array
180 }
175 }
181 );
176 );
182 m_elementValue = null;
177 m_elementValue = null;
183 m_memberContext = MemberContext.MemberValue;
178 m_memberContext = MemberContext.MemberValue;
184 m_elementType = JSONElementType.BeginArray;
179 m_elementType = JSONElementType.BeginArray;
185 return true;
180 return true;
186 case JsonTokenType.EndArray:
181 case JsonTokenType.EndArray:
187 Restore();
182 Restore();
188 m_elementValue = null;
183 m_elementValue = null;
189 m_elementType = JSONElementType.EndArray;
184 m_elementType = JSONElementType.EndArray;
190 return true;
185 return true;
191 case JsonTokenType.String:
186 case JsonTokenType.String:
192 if (m_memberContext == MemberContext.MemberName) {
187 if (m_memberContext == MemberContext.MemberName) {
193 m_context.info.memberName = (string)tokenValue;
188 m_context.info.memberName = (string)tokenValue;
194 break;
189 break;
195 } else {
196 m_elementType = JSONElementType.Value;
197 m_elementValue = tokenValue;
198 return true;
199 }
190 }
191 m_elementType = JSONElementType.Value;
192 m_elementValue = tokenValue;
193 return true;
200 case JsonTokenType.Number:
194 case JsonTokenType.Number:
201 m_elementType = JSONElementType.Value;
195 m_elementType = JSONElementType.Value;
202 m_elementValue = tokenValue;
196 m_elementValue = tokenValue;
203 return true;
197 return true;
204 case JsonTokenType.Literal:
198 case JsonTokenType.Literal:
205 m_elementType = JSONElementType.Value;
199 m_elementType = JSONElementType.Value;
206 m_elementValue = ParseLiteral((string)tokenValue);
200 m_elementValue = ParseLiteral((string)tokenValue);
207 return true;
201 return true;
208 case JsonTokenType.NameSeparator:
202 case JsonTokenType.NameSeparator:
209 m_memberContext = MemberContext.MemberValue;
203 m_memberContext = MemberContext.MemberValue;
210 break;
204 break;
211 case JsonTokenType.ValueSeparator:
205 case JsonTokenType.ValueSeparator:
212 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
206 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
213 break;
207 break;
214 default:
208 default:
215 UnexpectedToken(tokenValue, tokenType);
209 UnexpectedToken(tokenValue, tokenType);
216 break;
210 break;
217 }
211 }
218 }
212 }
219 if (m_context.info.elementContext != JSONElementContext.None)
213 if (m_context.info.elementContext != JSONElementContext.None)
220 throw new ParserException("Unexpedted end of data");
214 throw new ParserException("Unexpedted end of data");
221 return false;
215 return false;
222 }
216 }
223
217
224 object ParseLiteral(string literal) {
218 object ParseLiteral(string literal) {
225 switch (literal) {
219 switch (literal) {
226 case "null":
220 case "null":
227 return null;
221 return null;
228 case "false":
222 case "false":
229 return false;
223 return false;
230 case "true":
224 case "true":
231 return true;
225 return true;
232 default:
226 default:
233 UnexpectedToken(literal, JsonTokenType.Literal);
227 UnexpectedToken(literal, JsonTokenType.Literal);
234 return null; // avoid compliler error
228 return null; // avoid compliler error
235 }
229 }
236 }
230 }
237
231
238 void UnexpectedToken(object value, JsonTokenType tokenType) {
232 void UnexpectedToken(object value, JsonTokenType tokenType) {
239 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
233 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
240 }
234 }
241
235
242
236
243 /// <summary>
237 /// <summary>
244 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
238 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
245 /// </summary>
239 /// </summary>
246 public bool EOF {
240 public bool EOF {
247 get {
241 get {
248 return m_scanner.EOF;
242 return m_scanner.EOF;
249 }
243 }
250 }
244 }
251
245
252 protected virtual void Dispose(bool disposing) {
246 protected virtual void Dispose(bool disposing) {
253 if (disposing) {
247 if (disposing) {
254 m_scanner.Dispose();
248 m_scanner.Dispose();
255 }
249 }
256 }
250 }
257
251
258 /// <summary>
252 /// <summary>
259 /// ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ‚ парсСр ΠΈ связанный с Π½ΠΈΠΌ сканнСр.
253 /// ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ‚ парсСр ΠΈ связанный с Π½ΠΈΠΌ сканнСр.
260 /// </summary>
254 /// </summary>
261 public void Dispose() {
255 public void Dispose() {
262 Dispose(true);
256 Dispose(true);
263 GC.SuppressFinalize(this);
257 GC.SuppressFinalize(this);
264 }
258 }
265
259
266 ~JSONParser() {
260 ~JSONParser() {
267 Dispose(false);
261 Dispose(false);
268 }
262 }
269
263
270 /// <summary>
264 /// <summary>
271 /// ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΠΊΠΎΠ½Π΅Ρ† Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
265 /// ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΠΊΠΎΠ½Π΅Ρ† Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
272 /// </summary>
266 /// </summary>
273 public void SeekElementEnd() {
267 public void SeekElementEnd() {
274 var level = Level - 1;
268 var level = Level - 1;
275
269
276 Debug.Assert(level >= 0);
270 Debug.Assert(level >= 0);
277
271
278 while (Level != level)
272 while (Level != level)
279 Read();
273 Read();
280 }
274 }
281 }
275 }
282
276
283 }
277 }
@@ -1,100 +1,100
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6 using System.Text;
6 using System.Text;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8
8
9 namespace Implab.Parsing {
9 namespace Implab.Parsing {
10 public abstract class AlphabetBase<T> : IAlphabet<T> {
10 public abstract class AlphabetBase<T> : IAlphabet<T> {
11 public const int UNCLASSIFIED = 0;
11 public const int UNCLASSIFIED = 0;
12
12
13 int m_nextId = 1;
13 int m_nextId = 1;
14 int[] m_map;
14 readonly int[] m_map;
15
15
16 public int Count {
16 public int Count {
17 get { return m_nextId; }
17 get { return m_nextId; }
18 }
18 }
19
19
20 protected AlphabetBase(int mapSize) {
20 protected AlphabetBase(int mapSize) {
21 m_map = new int[mapSize];
21 m_map = new int[mapSize];
22 }
22 }
23
23
24 protected AlphabetBase(int[] map) {
24 protected AlphabetBase(int[] map) {
25 Debug.Assert(map != null);
25 Debug.Assert(map != null);
26
26
27 m_map = map;
27 m_map = map;
28 m_nextId = map.Max() + 1;
28 m_nextId = map.Max() + 1;
29 }
29 }
30
30
31 public int DefineSymbol(T symbol) {
31 public int DefineSymbol(T symbol) {
32 var index = GetSymbolIndex(symbol);
32 var index = GetSymbolIndex(symbol);
33 if (m_map[index] == UNCLASSIFIED)
33 if (m_map[index] == UNCLASSIFIED)
34 m_map[index] = m_nextId++;
34 m_map[index] = m_nextId++;
35 return m_map[index];
35 return m_map[index];
36 }
36 }
37
37
38 public int DefineClass(IEnumerable<T> symbols) {
38 public int DefineClass(IEnumerable<T> symbols) {
39 Safe.ArgumentNotNull(symbols, "symbols");
39 Safe.ArgumentNotNull(symbols, "symbols");
40 symbols = symbols.Distinct();
40 symbols = symbols.Distinct();
41
41
42 foreach (var symbol in symbols) {
42 foreach (var symbol in symbols) {
43 var index = GetSymbolIndex(symbol);
43 var index = GetSymbolIndex(symbol);
44 if (m_map[index] == UNCLASSIFIED)
44 if (m_map[index] == UNCLASSIFIED)
45 m_map[GetSymbolIndex(symbol)] = m_nextId;
45 m_map[GetSymbolIndex(symbol)] = m_nextId;
46 else
46 else
47 throw new InvalidOperationException(String.Format("Symbol '{0}' already in use", symbol));
47 throw new InvalidOperationException(String.Format("Symbol '{0}' already in use", symbol));
48 }
48 }
49 return m_nextId++;
49 return m_nextId++;
50 }
50 }
51
51
52 public List<T>[] CreateReverseMap() {
52 public List<T>[] CreateReverseMap() {
53 return
53 return
54 Enumerable.Range(UNCLASSIFIED, Count)
54 Enumerable.Range(UNCLASSIFIED, Count)
55 .Select(
55 .Select(
56 i => InputSymbols
56 i => InputSymbols
57 .Where(x => i != UNCLASSIFIED && m_map[GetSymbolIndex(x)] == i)
57 .Where(x => i != UNCLASSIFIED && m_map[GetSymbolIndex(x)] == i)
58 .ToList()
58 .ToList()
59 )
59 )
60 .ToArray();
60 .ToArray();
61 }
61 }
62
62
63 public int[] Reclassify(IAlphabet<T> newAlphabet, IEnumerable<ICollection<int>> classes) {
63 public int[] Reclassify(IAlphabet<T> newAlphabet, IEnumerable<ICollection<int>> classes) {
64 Safe.ArgumentNotNull(newAlphabet, "newAlphabet");
64 Safe.ArgumentNotNull(newAlphabet, "newAlphabet");
65 Safe.ArgumentNotNull(classes, "classes");
65 Safe.ArgumentNotNull(classes, "classes");
66 var reverseMap = CreateReverseMap();
66 var reverseMap = CreateReverseMap();
67
67
68 int[] translationMap = new int[Count];
68 int[] translationMap = new int[Count];
69
69
70 foreach (var scl in classes) {
70 foreach (var scl in classes) {
71 // skip if the supper class contains the unclassified element
71 // skip if the supper class contains the unclassified element
72 if (scl.Contains(UNCLASSIFIED))
72 if (scl.Contains(UNCLASSIFIED))
73 continue;
73 continue;
74 var range = new List<T>();
74 var range = new List<T>();
75 foreach (var cl in scl) {
75 foreach (var cl in scl) {
76 if (cl < 0 || cl >= reverseMap.Length)
76 if (cl < 0 || cl >= reverseMap.Length)
77 throw new ArgumentOutOfRangeException(String.Format("Class {0} is not valid for the current alphabet", cl));
77 throw new ArgumentOutOfRangeException(String.Format("Class {0} is not valid for the current alphabet", cl));
78 range.AddRange(reverseMap[cl]);
78 range.AddRange(reverseMap[cl]);
79 }
79 }
80 var newClass = newAlphabet.DefineClass(range);
80 var newClass = newAlphabet.DefineClass(range);
81 foreach (var cl in scl)
81 foreach (var cl in scl)
82 translationMap[cl] = newClass;
82 translationMap[cl] = newClass;
83 }
83 }
84
84
85 return translationMap;
85 return translationMap;
86 }
86 }
87
87
88 public int Translate(T symbol) {
88 public int Translate(T symbol) {
89 return m_map[GetSymbolIndex(symbol)];
89 return m_map[GetSymbolIndex(symbol)];
90 }
90 }
91
91
92 public abstract int GetSymbolIndex(T symbol);
92 public abstract int GetSymbolIndex(T symbol);
93
93
94 public abstract IEnumerable<T> InputSymbols { get; }
94 public abstract IEnumerable<T> InputSymbols { get; }
95
95
96 public int[] GetTranslationMap() {
96 public int[] GetTranslationMap() {
97 return m_map;
97 return m_map;
98 }
98 }
99 }
99 }
100 }
100 }
@@ -1,22 +1,17
1 using Implab;
1 using System;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
2
8 namespace Implab.Parsing {
3 namespace Implab.Parsing {
9 public class AltToken: BinaryToken {
4 public class AltToken: BinaryToken {
10 public AltToken(Token left, Token right)
5 public AltToken(Token left, Token right)
11 : base(left, right) {
6 : base(left, right) {
12 }
7 }
13
8
14 public override void Accept(IVisitor visitor) {
9 public override void Accept(IVisitor visitor) {
15 Safe.ArgumentNotNull(visitor, "visitor");
10 Safe.ArgumentNotNull(visitor, "visitor");
16 visitor.Visit(this);
11 visitor.Visit(this);
17 }
12 }
18 public override string ToString() {
13 public override string ToString() {
19 return String.Format(Right is BinaryToken ? "{0}|({1})" : "{0}|{1}", Left, Right);
14 return String.Format(Right is BinaryToken ? "{0}|({1})" : "{0}|{1}", Left, Right);
20 }
15 }
21 }
16 }
22 }
17 }
@@ -1,36 +1,36
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6 using System.Threading.Tasks;
6 using System.Threading.Tasks;
7
7
8 namespace Implab.Parsing {
8 namespace Implab.Parsing {
9 public class CDFADefinition : DFADefinitionBase {
9 public class CDFADefinition : DFADefinitionBase {
10 Alphabet m_alphabet;
10 readonly Alphabet m_alphabet;
11
11
12 public Alphabet Alphabet {
12 public Alphabet Alphabet {
13 get { return m_alphabet; }
13 get { return m_alphabet; }
14 }
14 }
15
15
16 public override int AlphabetSize {
16 public override int AlphabetSize {
17 get { return m_alphabet.Count; }
17 get { return m_alphabet.Count; }
18 }
18 }
19
19
20 public CDFADefinition(Alphabet alphabet): base() {
20 public CDFADefinition(Alphabet alphabet): base() {
21 Safe.ArgumentNotNull(alphabet, "alphabet");
21 Safe.ArgumentNotNull(alphabet, "alphabet");
22 m_alphabet = alphabet;
22 m_alphabet = alphabet;
23 }
23 }
24
24
25 public CDFADefinition Optimize() {
25 public CDFADefinition Optimize() {
26 var optimized = new CDFADefinition(new Alphabet());
26 var optimized = new CDFADefinition(new Alphabet());
27
27
28 Optimize(optimized, m_alphabet, optimized.Alphabet);
28 Optimize(optimized, m_alphabet, optimized.Alphabet);
29 return optimized;
29 return optimized;
30 }
30 }
31
31
32 public void PrintDFA() {
32 public void PrintDFA() {
33 PrintDFA(m_alphabet);
33 PrintDFA(m_alphabet);
34 }
34 }
35 }
35 }
36 }
36 }
@@ -1,27 +1,22
1 using Implab;
1 using System;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
2
8 namespace Implab.Parsing {
3 namespace Implab.Parsing {
9 public class CatToken : BinaryToken {
4 public class CatToken : BinaryToken {
10 public CatToken(Token left, Token right)
5 public CatToken(Token left, Token right)
11 : base(left, right) {
6 : base(left, right) {
12 }
7 }
13
8
14 public override void Accept(IVisitor visitor) {
9 public override void Accept(IVisitor visitor) {
15 Safe.ArgumentNotNull(visitor, "visitor");
10 Safe.ArgumentNotNull(visitor, "visitor");
16 visitor.Visit(this);
11 visitor.Visit(this);
17 }
12 }
18
13
19 public override string ToString() {
14 public override string ToString() {
20 return String.Format("{0}{1}", FormatToken(Left), FormatToken(Right));
15 return String.Format("{0}{1}", FormatToken(Left), FormatToken(Right));
21 }
16 }
22
17
23 string FormatToken(Token token) {
18 string FormatToken(Token token) {
24 return String.Format(token is AltToken ? "({0})" : "{0}", token);
19 return String.Format(token is AltToken ? "({0})" : "{0}", token);
25 }
20 }
26 }
21 }
27 }
22 }
@@ -1,182 +1,182
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6 using System.Text;
6 using System.Text;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8
8
9 namespace Implab.Parsing {
9 namespace Implab.Parsing {
10 /// <summary>
10 /// <summary>
11 /// Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для построСния Π”ΠšΠ ΠΏΠΎ рСгулярному Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ, сначала ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚
11 /// Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для построСния Π”ΠšΠ ΠΏΠΎ рСгулярному Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ, сначала ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚
12 /// рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈ вычисляСт followpos, Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄
12 /// рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈ вычисляСт followpos, Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄
13 /// <see cref="BuildDFA(IDFADefinition)"/> для построСния Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚Π°.
13 /// <see cref="BuildDFA(IDFADefinition)"/> для построСния Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚Π°.
14 /// </summary>
14 /// </summary>
15 public class DFABuilder : IVisitor {
15 public class DFABuilder : IVisitor {
16 int m_idx = 0;
16 int m_idx = 0;
17 Token m_root;
17 Token m_root;
18 HashSet<int> m_firstpos;
18 HashSet<int> m_firstpos;
19 HashSet<int> m_lastpos;
19 HashSet<int> m_lastpos;
20
20
21 Dictionary<int, HashSet<int>> m_followpos = new Dictionary<int, HashSet<int>>();
21 Dictionary<int, HashSet<int>> m_followpos = new Dictionary<int, HashSet<int>>();
22 Dictionary<int, int> m_indexes = new Dictionary<int, int>();
22 Dictionary<int, int> m_indexes = new Dictionary<int, int>();
23 Dictionary<int, int> m_ends = new Dictionary<int, int>();
23 Dictionary<int, int> m_ends = new Dictionary<int, int>();
24
24
25 public Dictionary<int, HashSet<int>> FollowposMap {
25 public Dictionary<int, HashSet<int>> FollowposMap {
26 get { return m_followpos; }
26 get { return m_followpos; }
27 }
27 }
28
28
29 public HashSet<int> Followpos(int pos) {
29 public HashSet<int> Followpos(int pos) {
30 HashSet<int> set;
30 HashSet<int> set;
31 if (m_followpos.TryGetValue(pos, out set))
31 if (m_followpos.TryGetValue(pos, out set))
32 return set;
32 return set;
33 return m_followpos[pos] = new HashSet<int>();
33 return m_followpos[pos] = new HashSet<int>();
34 }
34 }
35
35
36 bool Nullable(object n) {
36 bool Nullable(object n) {
37 if (n is EmptyToken || n is StarToken)
37 if (n is EmptyToken || n is StarToken)
38 return true;
38 return true;
39 if (n is AltToken)
39 if (n is AltToken)
40 return Nullable(((AltToken)n).Left) || Nullable(((AltToken)n).Right);
40 return Nullable(((AltToken)n).Left) || Nullable(((AltToken)n).Right);
41 if (n is CatToken)
41 if (n is CatToken)
42 return Nullable(((CatToken)n).Left) && Nullable(((CatToken)n).Right);
42 return Nullable(((CatToken)n).Left) && Nullable(((CatToken)n).Right);
43 return false;
43 return false;
44 }
44 }
45
45
46
46
47 public void Visit(AltToken token) {
47 public void Visit(AltToken token) {
48 if (m_root == null)
48 if (m_root == null)
49 m_root = token;
49 m_root = token;
50 var firtspos = new HashSet<int>();
50 var firtspos = new HashSet<int>();
51 var lastpos = new HashSet<int>();
51 var lastpos = new HashSet<int>();
52
52
53 token.Left.Accept(this);
53 token.Left.Accept(this);
54 firtspos.UnionWith(m_firstpos);
54 firtspos.UnionWith(m_firstpos);
55 lastpos.UnionWith(m_lastpos);
55 lastpos.UnionWith(m_lastpos);
56
56
57 token.Right.Accept(this);
57 token.Right.Accept(this);
58 firtspos.UnionWith(m_firstpos);
58 firtspos.UnionWith(m_firstpos);
59 lastpos.UnionWith(m_lastpos);
59 lastpos.UnionWith(m_lastpos);
60
60
61 m_firstpos = firtspos;
61 m_firstpos = firtspos;
62 m_lastpos = lastpos;
62 m_lastpos = lastpos;
63 }
63 }
64
64
65 public void Visit(StarToken token) {
65 public void Visit(StarToken token) {
66 if (m_root == null)
66 if (m_root == null)
67 m_root = token;
67 m_root = token;
68 token.Token.Accept(this);
68 token.Token.Accept(this);
69
69
70 foreach (var i in m_lastpos)
70 foreach (var i in m_lastpos)
71 Followpos(i).UnionWith(m_firstpos);
71 Followpos(i).UnionWith(m_firstpos);
72 }
72 }
73
73
74 public void Visit(CatToken token) {
74 public void Visit(CatToken token) {
75 if (m_root == null)
75 if (m_root == null)
76 m_root = token;
76 m_root = token;
77
77
78 var firtspos = new HashSet<int>();
78 var firtspos = new HashSet<int>();
79 var lastpos = new HashSet<int>();
79 var lastpos = new HashSet<int>();
80 token.Left.Accept(this);
80 token.Left.Accept(this);
81 firtspos.UnionWith(m_firstpos);
81 firtspos.UnionWith(m_firstpos);
82 var leftLastpos = m_lastpos;
82 var leftLastpos = m_lastpos;
83
83
84 token.Right.Accept(this);
84 token.Right.Accept(this);
85 lastpos.UnionWith(m_lastpos);
85 lastpos.UnionWith(m_lastpos);
86 var rightFirstpos = m_firstpos;
86 var rightFirstpos = m_firstpos;
87
87
88 if (Nullable(token.Left))
88 if (Nullable(token.Left))
89 firtspos.UnionWith(rightFirstpos);
89 firtspos.UnionWith(rightFirstpos);
90
90
91 if (Nullable(token.Right))
91 if (Nullable(token.Right))
92 lastpos.UnionWith(leftLastpos);
92 lastpos.UnionWith(leftLastpos);
93
93
94 m_firstpos = firtspos;
94 m_firstpos = firtspos;
95 m_lastpos = lastpos;
95 m_lastpos = lastpos;
96
96
97 foreach (var i in leftLastpos)
97 foreach (var i in leftLastpos)
98 Followpos(i).UnionWith(rightFirstpos);
98 Followpos(i).UnionWith(rightFirstpos);
99
99
100 }
100 }
101
101
102 public void Visit(EmptyToken token) {
102 public void Visit(EmptyToken token) {
103 if (m_root == null)
103 if (m_root == null)
104 m_root = token;
104 m_root = token;
105 ;
105 ;
106 }
106 }
107
107
108 public void Visit(SymbolToken token) {
108 public void Visit(SymbolToken token) {
109 if (m_root == null)
109 if (m_root == null)
110 m_root = token;
110 m_root = token;
111 m_idx++;
111 m_idx++;
112 m_indexes[m_idx] = token.Value;
112 m_indexes[m_idx] = token.Value;
113 m_firstpos = new HashSet<int>(new[] { m_idx });
113 m_firstpos = new HashSet<int>(new[] { m_idx });
114 m_lastpos = new HashSet<int>(new[] { m_idx });
114 m_lastpos = new HashSet<int>(new[] { m_idx });
115 }
115 }
116
116
117 public void Visit(EndToken token) {
117 public void Visit(EndToken token) {
118 if (m_root == null)
118 if (m_root == null)
119 m_root = token;
119 m_root = token;
120 m_idx++;
120 m_idx++;
121 m_indexes[m_idx] = Alphabet.UNCLASSIFIED;
121 m_indexes[m_idx] = Alphabet.UNCLASSIFIED;
122 m_firstpos = new HashSet<int>(new[] { m_idx });
122 m_firstpos = new HashSet<int>(new[] { m_idx });
123 m_lastpos = new HashSet<int>(new[] { m_idx });
123 m_lastpos = new HashSet<int>(new[] { m_idx });
124 Followpos(m_idx);
124 Followpos(m_idx);
125 m_ends.Add(m_idx, token.Tag);
125 m_ends.Add(m_idx, token.Tag);
126 }
126 }
127
127
128 public void BuildDFA(IDFADefinition dfa) {
128 public void BuildDFA(IDFADefinition dfa) {
129 Safe.ArgumentNotNull(dfa,"dfa");
129 Safe.ArgumentNotNull(dfa,"dfa");
130
130
131 var stateMap = new Dictionary<HashSet<int>, int>(new CustomEqualityComparer<HashSet<int>>(
131 var stateMap = new Dictionary<HashSet<int>, int>(new CustomEqualityComparer<HashSet<int>>(
132 (x, y) => x.SetEquals(y),
132 (x, y) => x.SetEquals(y),
133 (x) => x.Sum(n => n.GetHashCode())
133 (x) => x.Sum(n => n.GetHashCode())
134 ));
134 ));
135
135
136 stateMap[m_firstpos] = DefineState( dfa, m_firstpos);
136 stateMap[m_firstpos] = DefineState( dfa, m_firstpos);
137 Debug.Assert(stateMap[m_firstpos] == DFADefinitionBase.INITIAL_STATE);
137 Debug.Assert(stateMap[m_firstpos] == DFADefinitionBase.INITIAL_STATE);
138
138
139 var queue = new Queue<HashSet<int>>();
139 var queue = new Queue<HashSet<int>>();
140
140
141 queue.Enqueue(m_firstpos);
141 queue.Enqueue(m_firstpos);
142
142
143 while (queue.Count > 0) {
143 while (queue.Count > 0) {
144 var state = queue.Dequeue();
144 var state = queue.Dequeue();
145 var s1 = stateMap[state];
145 var s1 = stateMap[state];
146
146
147 for (int a = 0; a < dfa.AlphabetSize; a++) {
147 for (int a = 0; a < dfa.AlphabetSize; a++) {
148 var next = new HashSet<int>();
148 var next = new HashSet<int>();
149 foreach (var p in state) {
149 foreach (var p in state) {
150 if (m_indexes[p] == a) {
150 if (m_indexes[p] == a) {
151 next.UnionWith(Followpos(p));
151 next.UnionWith(Followpos(p));
152 }
152 }
153 }
153 }
154 if (next.Count > 0) {
154 if (next.Count > 0) {
155 int s2;
155 int s2;
156 if (!stateMap.TryGetValue(next, out s2)) {
156 if (!stateMap.TryGetValue(next, out s2)) {
157 stateMap[next] = s2 = DefineState(dfa, next);
157 stateMap[next] = s2 = DefineState(dfa, next);
158 queue.Enqueue(next);
158 queue.Enqueue(next);
159 }
159 }
160 dfa.DefineTransition(s1, s2, a);
160 dfa.DefineTransition(s1, s2, a);
161 }
161 }
162 }
162 }
163
163
164 }
164 }
165 }
165 }
166
166
167 int[] GetStateTags(HashSet<int> state) {
167 int[] GetStateTags(HashSet<int> state) {
168 Debug.Assert(state != null);
168 Debug.Assert(state != null);
169 return state.Where(pos => m_ends.ContainsKey(pos)).Select(pos => m_ends[pos]).ToArray();
169 return state.Where(m_ends.ContainsKey).Select(pos => m_ends[pos]).ToArray();
170 }
170 }
171
171
172 int DefineState(IDFADefinition automa, HashSet<int> state) {
172 int DefineState(IDFADefinition automa, HashSet<int> state) {
173 Debug.Assert(automa != null);
173 Debug.Assert(automa != null);
174 Debug.Assert(state != null);
174 Debug.Assert(state != null);
175
175
176 var tags = GetStateTags(state);
176 var tags = GetStateTags(state);
177
177
178 return tags.Length > 0 ? automa.AddState(tags) : automa.AddState();
178 return tags.Length > 0 ? automa.AddState(tags) : automa.AddState();
179 }
179 }
180
180
181 }
181 }
182 }
182 }
@@ -1,262 +1,260
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6 using System.Text;
6 using System.Text;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8
8
9 namespace Implab.Parsing {
9 namespace Implab.Parsing {
10 public abstract class DFADefinitionBase : IDFADefinition {
10 public abstract class DFADefinitionBase : IDFADefinition {
11 readonly List<DFAStateDescriptior> m_states;
11 readonly List<DFAStateDescriptior> m_states;
12
12
13 public const int INITIAL_STATE = 1;
13 public const int INITIAL_STATE = 1;
14 public const int UNREACHEBLE_STATE = 0;
14 public const int UNREACHEBLE_STATE = 0;
15
15
16 DFAStateDescriptior[] m_statesArray;
16 DFAStateDescriptior[] m_statesArray;
17
17
18 public DFADefinitionBase() {
18 protected DFADefinitionBase() {
19 m_states = new List<DFAStateDescriptior>();
19 m_states = new List<DFAStateDescriptior>();
20
20
21 m_states.Add(new DFAStateDescriptior());
21 m_states.Add(new DFAStateDescriptior());
22 }
22 }
23
23
24 public DFAStateDescriptior[] States {
24 public DFAStateDescriptior[] States {
25 get {
25 get {
26 if (m_statesArray == null)
26 if (m_statesArray == null)
27 m_statesArray = m_states.ToArray();
27 m_statesArray = m_states.ToArray();
28 return m_statesArray;
28 return m_statesArray;
29 }
29 }
30 }
30 }
31
31
32 public bool InitialStateIsFinal {
32 public bool InitialStateIsFinal {
33 get {
33 get {
34 return m_states[INITIAL_STATE].final;
34 return m_states[INITIAL_STATE].final;
35 }
35 }
36 }
36 }
37
37
38 public int AddState() {
38 public int AddState() {
39 var index = m_states.Count;
39 var index = m_states.Count;
40 m_states.Add(new DFAStateDescriptior {
40 m_states.Add(new DFAStateDescriptior {
41 final = false,
41 final = false,
42 transitions = new int[AlphabetSize]
42 transitions = new int[AlphabetSize]
43 });
43 });
44
44
45 return index;
45 return index;
46 }
46 }
47
47
48 public int AddState(int[] tag) {
48 public int AddState(int[] tag) {
49 var index = m_states.Count;
49 var index = m_states.Count;
50 bool final = tag == null || tag.Length == 0 ? false : true;
50 bool final = tag != null && tag.Length != 0;
51 m_states.Add(new DFAStateDescriptior {
51 m_states.Add(new DFAStateDescriptior {
52 final = final,
52 final = final,
53 transitions = new int[AlphabetSize],
53 transitions = new int[AlphabetSize],
54 tag = final ? tag : null
54 tag = final ? tag : null
55 });
55 });
56 return index;
56 return index;
57 }
57 }
58
58
59 public void DefineTransition(int s1,int s2, int symbol) {
59 public void DefineTransition(int s1,int s2, int symbol) {
60 Safe.ArgumentInRange(s1, 0, m_states.Count-1, "s1");
60 Safe.ArgumentInRange(s1, 0, m_states.Count-1, "s1");
61 Safe.ArgumentInRange(s2, 0, m_states.Count-1, "s2");
61 Safe.ArgumentInRange(s2, 0, m_states.Count-1, "s2");
62 Safe.ArgumentInRange(symbol, 0, AlphabetSize-1, "symbol");
62 Safe.ArgumentInRange(symbol, 0, AlphabetSize-1, "symbol");
63
63
64 m_states[s1].transitions[symbol] = s2;
64 m_states[s1].transitions[symbol] = s2;
65 }
65 }
66
66
67 protected void Optimize<TA>(IDFADefinition minimalDFA,IAlphabet<TA> sourceAlphabet, IAlphabet<TA> minimalAlphabet) {
67 protected void Optimize<TA>(IDFADefinition minimalDFA,IAlphabet<TA> sourceAlphabet, IAlphabet<TA> minimalAlphabet) {
68 Safe.ArgumentNotNull(minimalDFA, "minimalDFA");
68 Safe.ArgumentNotNull(minimalDFA, "minimalDFA");
69 Safe.ArgumentNotNull(minimalAlphabet, "minimalAlphabet");
69 Safe.ArgumentNotNull(minimalAlphabet, "minimalAlphabet");
70
70
71 var setComparer = new CustomEqualityComparer<HashSet<int>>(
71 var setComparer = new CustomEqualityComparer<HashSet<int>>(
72 (x, y) => x.SetEquals(y),
72 (x, y) => x.SetEquals(y),
73 (s) => s.Sum(x => x.GetHashCode())
73 (s) => s.Sum(x => x.GetHashCode())
74 );
74 );
75
75
76 var arrayComparer = new CustomEqualityComparer<int[]>(
76 var arrayComparer = new CustomEqualityComparer<int[]>(
77 (x,y) => (new HashSet<int>(x)).SetEquals(new HashSet<int>(y)),
77 (x,y) => (new HashSet<int>(x)).SetEquals(new HashSet<int>(y)),
78 (a) => a.Sum(x => x.GetHashCode())
78 (a) => a.Sum(x => x.GetHashCode())
79 );
79 );
80
80
81 var optimalStates = new HashSet<HashSet<int>>(setComparer);
81 var optimalStates = new HashSet<HashSet<int>>(setComparer);
82 var queue = new HashSet<HashSet<int>>(setComparer);
82 var queue = new HashSet<HashSet<int>>(setComparer);
83
83
84 foreach (var g in Enumerable
84 foreach (var g in Enumerable
85 .Range(INITIAL_STATE, m_states.Count-1)
85 .Range(INITIAL_STATE, m_states.Count-1)
86 .Select(i => new {
86 .Select(i => new {
87 index = i,
87 index = i,
88 descriptor = m_states[i]
88 descriptor = m_states[i]
89 })
89 })
90 .Where(x => x.descriptor.final)
90 .Where(x => x.descriptor.final)
91 .GroupBy(x => x.descriptor.tag, arrayComparer)
91 .GroupBy(x => x.descriptor.tag, arrayComparer)
92 ) {
92 ) {
93 optimalStates.Add(new HashSet<int>(g.Select(x => x.index)));
93 optimalStates.Add(new HashSet<int>(g.Select(x => x.index)));
94 }
94 }
95
95
96 var state = new HashSet<int>(
96 var state = new HashSet<int>(
97 Enumerable
97 Enumerable
98 .Range(INITIAL_STATE, m_states.Count - 1)
98 .Range(INITIAL_STATE, m_states.Count - 1)
99 .Where(i => !m_states[i].final)
99 .Where(i => !m_states[i].final)
100 );
100 );
101 optimalStates.Add(state);
101 optimalStates.Add(state);
102 queue.Add(state);
102 queue.Add(state);
103
103
104 while (queue.Count > 0) {
104 while (queue.Count > 0) {
105 var stateA = queue.First();
105 var stateA = queue.First();
106 queue.Remove(stateA);
106 queue.Remove(stateA);
107
107
108 for (int c = 0; c < AlphabetSize; c++) {
108 for (int c = 0; c < AlphabetSize; c++) {
109 var stateX = new HashSet<int>();
109 var stateX = new HashSet<int>();
110
110
111 for(int s = 1; s < m_states.Count; s++) {
111 for(int s = 1; s < m_states.Count; s++) {
112 if (stateA.Contains(m_states[s].transitions[c]))
112 if (stateA.Contains(m_states[s].transitions[c]))
113 stateX.Add(s);
113 stateX.Add(s);
114 }
114 }
115
115
116 foreach (var stateY in optimalStates.ToArray()) {
116 foreach (var stateY in optimalStates.ToArray()) {
117 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) {
117 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) {
118 var stateR1 = new HashSet<int>(stateY);
118 var stateR1 = new HashSet<int>(stateY);
119 var stateR2 = new HashSet<int>(stateY);
119 var stateR2 = new HashSet<int>(stateY);
120
120
121 stateR1.IntersectWith(stateX);
121 stateR1.IntersectWith(stateX);
122 stateR2.ExceptWith(stateX);
122 stateR2.ExceptWith(stateX);
123
123
124 optimalStates.Remove(stateY);
124 optimalStates.Remove(stateY);
125 optimalStates.Add(stateR1);
125 optimalStates.Add(stateR1);
126 optimalStates.Add(stateR2);
126 optimalStates.Add(stateR2);
127
127
128 if (queue.Contains(stateY)) {
128 if (queue.Contains(stateY)) {
129 queue.Remove(stateY);
129 queue.Remove(stateY);
130 queue.Add(stateR1);
130 queue.Add(stateR1);
131 queue.Add(stateR2);
131 queue.Add(stateR2);
132 } else {
132 } else {
133 queue.Add(stateR1.Count <= stateR2.Count ? stateR1 : stateR2);
133 queue.Add(stateR1.Count <= stateR2.Count ? stateR1 : stateR2);
134 }
134 }
135 }
135 }
136 }
136 }
137 }
137 }
138 }
138 }
139
139
140 // строим ΠΊΠ°Ρ€Ρ‚Ρ‹ соотвСствия ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… состояний с ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ
140 // строим ΠΊΠ°Ρ€Ρ‚Ρ‹ соотвСствия ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… состояний с ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ
141
141
142 var initialState = optimalStates.Where(x => x.Contains(INITIAL_STATE)).Single();
142 var initialState = optimalStates.Single(x => x.Contains(INITIAL_STATE));
143
143
144 // ΠΊΠ°Ρ€Ρ‚Π° получСния ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ состояния ΠΏΠΎ ΡΠΎΠΎΡ‚Π²Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π΅ΠΌΡƒ простому ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ
144 // ΠΊΠ°Ρ€Ρ‚Π° получСния ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ состояния ΠΏΠΎ ΡΠΎΠΎΡ‚Π²Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π΅ΠΌΡƒ простому ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ
145 int[] reveseOptimalMap = new int[m_states.Count];
145 int[] reveseOptimalMap = new int[m_states.Count];
146 // ΠΊΠ°Ρ€Ρ‚Π° с индСксами ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… состояний
146 // ΠΊΠ°Ρ€Ρ‚Π° с индСксами ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… состояний
147 HashSet<int>[] optimalMap = new HashSet<int>[optimalStates.Count + 1];
147 HashSet<int>[] optimalMap = new HashSet<int>[optimalStates.Count + 1];
148 {
148 {
149 optimalMap[0] = new HashSet<int>(); // unreachable state
149 optimalMap[0] = new HashSet<int>(); // unreachable state
150 optimalMap[1] = initialState; // initial state
150 optimalMap[1] = initialState; // initial state
151 foreach (var ss in initialState)
151 foreach (var ss in initialState)
152 reveseOptimalMap[ss] = 1;
152 reveseOptimalMap[ss] = 1;
153
153
154 int i = 2;
154 int i = 2;
155 foreach (var s in optimalStates) {
155 foreach (var s in optimalStates) {
156 if (s.SetEquals(initialState))
156 if (s.SetEquals(initialState))
157 continue;
157 continue;
158 optimalMap[i] = s;
158 optimalMap[i] = s;
159 foreach (var ss in s)
159 foreach (var ss in s)
160 reveseOptimalMap[ss] = i;
160 reveseOptimalMap[ss] = i;
161 i++;
161 i++;
162 }
162 }
163 }
163 }
164
164
165 // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π»Ρ„Π°Π²ΠΈΡ‚
165 // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π»Ρ„Π°Π²ΠΈΡ‚
166
166
167 var minClasses = new HashSet<HashSet<int>>(setComparer);
167 var minClasses = new HashSet<HashSet<int>>(setComparer);
168 var alphaQueue = new Queue<HashSet<int>>();
168 var alphaQueue = new Queue<HashSet<int>>();
169 alphaQueue.Enqueue(new HashSet<int>(Enumerable.Range(0,AlphabetSize)));
169 alphaQueue.Enqueue(new HashSet<int>(Enumerable.Range(0,AlphabetSize)));
170
170
171 for (int s = 1 ; s < optimalMap.Length; s++) {
171 for (int s = 1 ; s < optimalMap.Length; s++) {
172 var newQueue = new Queue<HashSet<int>>();
172 var newQueue = new Queue<HashSet<int>>();
173
173
174 foreach (var A in alphaQueue) {
174 foreach (var A in alphaQueue) {
175 if (A.Count == 1) {
175 if (A.Count == 1) {
176 minClasses.Add(A);
176 minClasses.Add(A);
177 continue;
177 continue;
178 }
178 }
179
179
180 // Ρ€Π°Π·Π»ΠΈΡ‡Π°Π΅ΠΌ классы символов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ пСрСводят Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Π΅ состояния
180 // Ρ€Π°Π·Π»ΠΈΡ‡Π°Π΅ΠΌ классы символов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ пСрСводят Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Π΅ состояния
181 // optimalState -> alphaClass
181 // optimalState -> alphaClass
182 var classes = new Dictionary<int, HashSet<int>>();
182 var classes = new Dictionary<int, HashSet<int>>();
183
183
184 foreach (var term in A) {
184 foreach (var term in A) {
185 // ΠΈΡ‰Π΅ΠΌ всС ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹ класса ΠΏΠΎ символу term
185 // ΠΈΡ‰Π΅ΠΌ всС ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹ класса ΠΏΠΎ символу term
186 var s2 = reveseOptimalMap[
186 var s2 = reveseOptimalMap[
187 optimalMap[s].Select(x => m_states[x].transitions[term]) // всС элСмСнтарныС состояния, ΠΊΡƒΠ΄Π° ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ класс s
187 optimalMap[s].Select(x => m_states[x].transitions[term]).FirstOrDefault(x => x != 0) // ΠΏΠ΅Ρ€Π²ΠΎΠ΅ допустимоС элСмСнтарноС состояниС, Ссли Π΅ΡΡ‚ΡŒ
188 .Where(x => x != 0) // Ρ‚ΠΎΠ»ΡŒΠΊΠΎ допустимыС
188 ];
189 .FirstOrDefault() // ΠΏΠ΅Ρ€Π²ΠΎΠ΅ допустимоС элСмСнтарноС состояниС, Ссли Π΅ΡΡ‚ΡŒ
190 ];
191
189
192 HashSet<int> A2;
190 HashSet<int> A2;
193 if (!classes.TryGetValue(s2, out A2)) {
191 if (!classes.TryGetValue(s2, out A2)) {
194 A2 = new HashSet<int>();
192 A2 = new HashSet<int>();
195 newQueue.Enqueue(A2);
193 newQueue.Enqueue(A2);
196 classes[s2] = A2;
194 classes[s2] = A2;
197 }
195 }
198 A2.Add(term);
196 A2.Add(term);
199 }
197 }
200 }
198 }
201
199
202 if (newQueue.Count == 0)
200 if (newQueue.Count == 0)
203 break;
201 break;
204 alphaQueue = newQueue;
202 alphaQueue = newQueue;
205 }
203 }
206
204
207 foreach (var A in alphaQueue)
205 foreach (var A in alphaQueue)
208 minClasses.Add(A);
206 minClasses.Add(A);
209
207
210 var alphabetMap = sourceAlphabet.Reclassify(minimalAlphabet, minClasses);
208 var alphabetMap = sourceAlphabet.Reclassify(minimalAlphabet, minClasses);
211
209
212 // построСниС Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚Π°
210 // построСниС Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚Π°
213
211
214 var states = new int[ optimalMap.Length ];
212 var states = new int[ optimalMap.Length ];
215 states[0] = UNREACHEBLE_STATE;
213 states[0] = UNREACHEBLE_STATE;
216
214
217 for(var s = INITIAL_STATE; s < states.Length; s++) {
215 for(var s = INITIAL_STATE; s < states.Length; s++) {
218 var tags = optimalMap[s].SelectMany(x => m_states[x].tag ?? Enumerable.Empty<int>()).Distinct().ToArray();
216 var tags = optimalMap[s].SelectMany(x => m_states[x].tag ?? Enumerable.Empty<int>()).Distinct().ToArray();
219 if (tags.Length > 0)
217 if (tags.Length > 0)
220 states[s] = minimalDFA.AddState(tags);
218 states[s] = minimalDFA.AddState(tags);
221 else
219 else
222 states[s] = minimalDFA.AddState();
220 states[s] = minimalDFA.AddState();
223 }
221 }
224
222
225 Debug.Assert(states[INITIAL_STATE] == INITIAL_STATE);
223 Debug.Assert(states[INITIAL_STATE] == INITIAL_STATE);
226
224
227 for (int s1 = 1; s1 < m_states.Count; s1++) {
225 for (int s1 = 1; s1 < m_states.Count; s1++) {
228 for (int c = 0; c < AlphabetSize; c++) {
226 for (int c = 0; c < AlphabetSize; c++) {
229 var s2 = m_states[s1].transitions[c];
227 var s2 = m_states[s1].transitions[c];
230 if (s2 != UNREACHEBLE_STATE) {
228 if (s2 != UNREACHEBLE_STATE) {
231 minimalDFA.DefineTransition(
229 minimalDFA.DefineTransition(
232 reveseOptimalMap[s1],
230 reveseOptimalMap[s1],
233 reveseOptimalMap[s2],
231 reveseOptimalMap[s2],
234 alphabetMap[c]
232 alphabetMap[c]
235 );
233 );
236 }
234 }
237 }
235 }
238 }
236 }
239
237
240 }
238 }
241
239
242 protected void PrintDFA<TA>(IAlphabet<TA> alphabet) {
240 protected void PrintDFA<TA>(IAlphabet<TA> alphabet) {
243
241
244 var reverseMap = alphabet.CreateReverseMap();
242 var reverseMap = alphabet.CreateReverseMap();
245
243
246 for (int i = 1; i < reverseMap.Length; i++) {
244 for (int i = 1; i < reverseMap.Length; i++) {
247 Console.WriteLine("C{0}: {1}", i, String.Join(",", reverseMap[i]));
245 Console.WriteLine("C{0}: {1}", i, String.Join(",", reverseMap[i]));
248 }
246 }
249
247
250 for (int i = 1; i < m_states.Count; i++) {
248 for (int i = 1; i < m_states.Count; i++) {
251 var s = m_states[i];
249 var s = m_states[i];
252 for (int c = 0; c < AlphabetSize; c++)
250 for (int c = 0; c < AlphabetSize; c++)
253 if (s.transitions[c] != UNREACHEBLE_STATE)
251 if (s.transitions[c] != UNREACHEBLE_STATE)
254 Console.WriteLine("S{0} -{1}-> S{2}{3}", i, String.Join(",", reverseMap[c]), s.transitions[c], m_states[s.transitions[c]].final ? "$" : "");
252 Console.WriteLine("S{0} -{1}-> S{2}{3}", i, String.Join(",", reverseMap[c]), s.transitions[c], m_states[s.transitions[c]].final ? "$" : "");
255 }
253 }
256 }
254 }
257
255
258 public abstract int AlphabetSize {
256 public abstract int AlphabetSize {
259 get;
257 get;
260 }
258 }
261 }
259 }
262 }
260 }
@@ -1,56 +1,61
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6 using System.Text;
6 using System.Text;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8
8
9 namespace Implab.Parsing {
9 namespace Implab.Parsing {
10 public abstract class DFAutomaton<T> {
10 public abstract class DFAutomaton<T> {
11 protected struct ContextFrame {
11 protected struct ContextFrame {
12 public DFAStateDescriptior[] states;
12 public DFAStateDescriptior[] states;
13 public int current;
13 public int current;
14 public T info;
14 public T info;
15 }
15 }
16
16
17 public const int INITIAL_STATE = DFADefinitionBase.INITIAL_STATE;
17 public const int INITIAL_STATE = DFADefinitionBase.INITIAL_STATE;
18 public const int UNREACHEBLE_STATE = DFADefinitionBase.UNREACHEBLE_STATE;
18 public const int UNREACHEBLE_STATE = DFADefinitionBase.UNREACHEBLE_STATE;
19
19
20 protected ContextFrame m_context;
20 protected ContextFrame m_context;
21 Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
21 Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
22
22
23 protected int Level {
23 protected int Level {
24 get { return m_contextStack.Count; }
24 get { return m_contextStack.Count; }
25 }
25 }
26
26
27 protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
27 protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
28 Safe.ArgumentNotNull(states, "states");
28 Safe.ArgumentNotNull(states, "states");
29 Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
29 Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
30
30
31 m_context.states = states;
31 m_context.states = states;
32 m_context.current = startState;
32 m_context.current = startState;
33 m_context.info = info;
33 m_context.info = info;
34 }
34 }
35
35
36 protected void Switch(DFAStateDescriptior[] states, int current, T info) {
36 protected void Switch(DFAStateDescriptior[] states, int current, T info) {
37 Debug.Assert(states != null);
37 Debug.Assert(states != null);
38 Debug.Assert(current >= 0 && current < states.Length);
38 Debug.Assert(current >= 0 && current < states.Length);
39 m_contextStack.Push(m_context);
39 m_contextStack.Push(m_context);
40 m_context. states = states;
40 m_context.states = states;
41 m_context.current = current;
41 m_context.current = current;
42 m_context.info = info;
42 m_context.info = info;
43 }
43 }
44
44
45 protected void Restore() {
45 protected void Restore() {
46 Debug.Assert(m_contextStack.Count > 0);
46 Debug.Assert(m_contextStack.Count > 0);
47
47
48 m_context = m_contextStack.Pop();
48 m_context = m_contextStack.Pop();
49 }
49 }
50
50
51 protected void Move(int input) {
51 protected void Move(int input) {
52 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
52 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
53 m_context.current = m_context.states[m_context.current].transitions[input];
53 m_context.current = m_context.states[m_context.current].transitions[input];
54 }
54 }
55
56 protected bool CanMove(int input) {
57 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
58 return m_context.states[m_context.current].transitions[input] != UNREACHEBLE_STATE;
59 }
55 }
60 }
56 }
61 }
@@ -1,37 +1,32
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
3
8 namespace Implab.Parsing {
4 namespace Implab.Parsing {
9 public class EDFADefinition<T> : DFADefinitionBase where T : struct, IConvertible {
5 public class EDFADefinition<T> : DFADefinitionBase where T : struct, IConvertible {
10 EnumAlphabet<T> m_alphabet;
6 readonly EnumAlphabet<T> m_alphabet;
11
7
12 public EnumAlphabet<T> Alphabet {
8 public EnumAlphabet<T> Alphabet {
13 get { return m_alphabet; }
9 get { return m_alphabet; }
14 }
10 }
15
11
16 public EDFADefinition(EnumAlphabet<T> alphabet)
12 public EDFADefinition(EnumAlphabet<T> alphabet) {
17 : base() {
18 Safe.ArgumentNotNull(alphabet, "alphabet");
13 Safe.ArgumentNotNull(alphabet, "alphabet");
19 m_alphabet = alphabet;
14 m_alphabet = alphabet;
20 }
15 }
21
16
22 public override int AlphabetSize {
17 public override int AlphabetSize {
23 get { return m_alphabet.Count; }
18 get { return m_alphabet.Count; }
24 }
19 }
25
20
26 public EDFADefinition<T> Optimize() {
21 public EDFADefinition<T> Optimize() {
27 var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
22 var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
28 Optimize(optimized, m_alphabet, optimized.Alphabet);
23 Optimize(optimized, m_alphabet, optimized.Alphabet);
29
24
30 return optimized;
25 return optimized;
31 }
26 }
32
27
33 public void PrintDFA() {
28 public void PrintDFA() {
34 PrintDFA(m_alphabet);
29 PrintDFA(m_alphabet);
35 }
30 }
36 }
31 }
37 }
32 }
@@ -1,68 +1,67
1 using Implab;
1 using System;
2 using System;
3 using System.Collections.Generic;
2 using System.Collections.Generic;
4 using System.Diagnostics;
3 using System.Diagnostics;
5 using System.Globalization;
4 using System.Globalization;
6 using System.Linq;
5 using System.Linq;
7 using System.Text;
6 using System.Diagnostics.CodeAnalysis;
8 using System.Threading.Tasks;
9
7
10 namespace Implab.Parsing {
8 namespace Implab.Parsing {
11 /// <summary>
9 /// <summary>
12 /// Алфавит символами ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ элСмСнты пСрСчислСний.
10 /// Алфавит символами ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ элСмСнты пСрСчислСний.
13 /// </summary>
11 /// </summary>
14 /// <typeparam name="T">Π’ΠΈΠΏ пСрСчислСний</typeparam>
12 /// <typeparam name="T">Π’ΠΈΠΏ пСрСчислСний</typeparam>
15 public class EnumAlphabet<T> : AlphabetBase<T> where T : struct, IConvertible {
13 public class EnumAlphabet<T> : AlphabetBase<T> where T : struct, IConvertible {
14 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
16 static readonly T[] _symbols;
15 static readonly T[] _symbols;
17 static readonly EnumAlphabet<T> _fullAlphabet;
16 static readonly EnumAlphabet<T> _fullAlphabet;
18
17
19 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
18 [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
20 static EnumAlphabet() {
19 static EnumAlphabet() {
21 if (!typeof(T).IsEnum)
20 if (!typeof(T).IsEnum)
22 throw new InvalidOperationException("Invalid generic parameter, enumeration is required");
21 throw new InvalidOperationException("Invalid generic parameter, enumeration is required");
23
22
24 if (Enum.GetUnderlyingType(typeof(T)) != typeof(Int32))
23 if (Enum.GetUnderlyingType(typeof(T)) != typeof(Int32))
25 throw new InvalidOperationException("Only enums based on Int32 are supported");
24 throw new InvalidOperationException("Only enums based on Int32 are supported");
26
25
27 _symbols = ((T[])Enum.GetValues(typeof(T)))
26 _symbols = ((T[])Enum.GetValues(typeof(T)))
28 .OrderBy(x => x.ToInt32(CultureInfo.InvariantCulture))
27 .OrderBy(x => x.ToInt32(CultureInfo.InvariantCulture))
29 .ToArray();
28 .ToArray();
30
29
31 if (
30 if (
32 _symbols[_symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= _symbols.Length
31 _symbols[_symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= _symbols.Length
33 || _symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0
32 || _symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0
34 )
33 )
35 throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered");
34 throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered");
36
35
37 _fullAlphabet = new EnumAlphabet<T>(_symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray());
36 _fullAlphabet = new EnumAlphabet<T>(_symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray());
38 }
37 }
39
38
40
39
41
40
42 public static EnumAlphabet<T> FullAlphabet {
41 public static EnumAlphabet<T> FullAlphabet {
43 get {
42 get {
44 return _fullAlphabet;
43 return _fullAlphabet;
45 }
44 }
46 }
45 }
47
46
48
47
49 public EnumAlphabet()
48 public EnumAlphabet()
50 : base(_symbols.Length) {
49 : base(_symbols.Length) {
51 }
50 }
52
51
53 public EnumAlphabet(int[] map)
52 public EnumAlphabet(int[] map)
54 : base(map) {
53 : base(map) {
55 Debug.Assert(map.Length == _symbols.Length);
54 Debug.Assert(map.Length == _symbols.Length);
56 }
55 }
57
56
58
57
59 public override int GetSymbolIndex(T symbol) {
58 public override int GetSymbolIndex(T symbol) {
60 return symbol.ToInt32(CultureInfo.InvariantCulture);
59 return symbol.ToInt32(CultureInfo.InvariantCulture);
61 }
60 }
62
61
63 public override IEnumerable<T> InputSymbols {
62 public override IEnumerable<T> InputSymbols {
64 get { return _symbols; }
63 get { return _symbols; }
65 }
64 }
66
65
67 }
66 }
68 }
67 }
@@ -1,26 +1,18
1 using System.Threading;
1 using System.Threading;
2 using System;
2 using System;
3
3
4 namespace Implab {
4 namespace Implab {
5 public class SyncContextPromise<T> : Promise<T> {
5 public class SyncContextPromise<T> : Promise<T> {
6 readonly SynchronizationContext m_context;
6 readonly SynchronizationContext m_context;
7
7
8 public SyncContextPromise(SynchronizationContext context) {
8 public SyncContextPromise(SynchronizationContext context) {
9 Safe.ArgumentNotNull(context, "context");
9 Safe.ArgumentNotNull(context, "context");
10 m_context = context;
10 m_context = context;
11 }
11 }
12
12
13 protected override void SignalSuccess(Promise<T>.HandlerDescriptor handler) {
13 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
14 m_context.Post(x => base.SignalSuccess(handler), null);
14 m_context.Post(x => base.SignalHandler(handler, signal), null);
15 }
16
17 protected override void SignalError(Promise<T>.HandlerDescriptor handler, Exception error) {
18 m_context.Post(x => base.SignalError(handler, error), null);
19 }
20
21 protected override void SignalCancelled(Promise<T>.HandlerDescriptor handler, Exception reason) {
22 m_context.Post(x => base.SignalCancelled(handler, reason), null);
23 }
15 }
24 }
16 }
25 }
17 }
26
18
@@ -1,41 +1,37
1 using System;
1 using System;
2 using Implab.Diagnostics;
3 using Implab.Parallels;
4 using Implab;
2 using Implab;
5 using System.Collections.Generic;
6 using System.Collections.Concurrent;
7 using System.Threading;
8 using Implab.JSON;
9 using System.IO;
10 using System.Threading.Tasks;
3 using System.Threading.Tasks;
11
4
12 namespace MonoPlay {
5 namespace MonoPlay {
13 class MainClass {
6 class MainClass {
14
7
15
8
16 public static void Main(string[] args) {
9 public static void Main(string[] args) {
17 if (args == null)
10 if (args == null)
18 throw new ArgumentNullException("args");
11 throw new ArgumentNullException("args");
19
12
20 var t1 = Environment.TickCount;
13 var t1 = Environment.TickCount;
21
14
22 DoWork().GetAwaiter().GetResult();
15 DoWork().GetAwaiter().GetResult();
23
16
24 var t2 = Environment.TickCount;
17 var t2 = Environment.TickCount;
25 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
18 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
26
19
27 }
20 }
28
21
29 static IPromise<int> DoItem(int x) {
22 static IPromise<int> DoItem(int x) {
30 return Promise<int>.FromResult(x + 1);
23 //return Promise<int>.FromResult(x + 1);
24 var p = new Promise<int>();
25 p.Resolve(x+1);
26 return p;
31 }
27 }
32
28
33 static async Task<int> DoWork() {
29 static async Task<int> DoWork() {
34 var c = 0;
30 var c = 0;
35 for (int i = 0; i < 10000000; i++)
31 for (int i = 0; i < 10000000; i++)
36 c = await DoItem(c);
32 c = await DoItem(c);
37 return c;
33 return c;
38 }
34 }
39
35
40 }
36 }
41 }
37 }
General Comments 0
You need to be logged in to leave comments. Login now