202 */ |
202 */ |
203 QHash<StateId, StateType> states() const; |
203 QHash<StateId, StateType> states() const; |
204 |
204 |
205 /** |
205 /** |
206 * Returns the information of all transitions of the state machine. |
206 * Returns the information of all transitions of the state machine. |
207 */ |
207 * |
208 QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const; |
208 * The implementation is inlined in order to workaround a compiler |
|
209 * bug on Symbian/winscw. |
|
210 */ |
|
211 QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const |
|
212 { |
|
213 return m_transitions; |
|
214 } |
209 |
215 |
210 private: |
216 private: |
211 /** |
217 /** |
212 * Returns the DFA state for the given @p nfaStat from the given @p stateTable. |
218 * Returns the DFA state for the given @p nfaStat from the given @p stateTable. |
213 * If there is no corresponding DFA state yet, a new one is created. |
219 * If there is no corresponding DFA state yet, a new one is created. |
215 StateId dfaStateForNfaState(QSet<StateId> nfaState, QList< QPair< QSet<StateId>, StateId> > &stateTable, XsdStateMachine<TransitionType> &dfa) const; |
221 StateId dfaStateForNfaState(QSet<StateId> nfaState, QList< QPair< QSet<StateId>, StateId> > &stateTable, XsdStateMachine<TransitionType> &dfa) const; |
216 |
222 |
217 /** |
223 /** |
218 * Returns the set of all states that can be reached from the set of @p input states |
224 * Returns the set of all states that can be reached from the set of @p input states |
219 * by the epsilon transition. |
225 * by the epsilon transition. |
220 */ |
226 * |
221 QSet<StateId> epsilonClosure(const QSet<StateId> &input) const; |
227 * The implementation is inlined in order to workaround a compiler |
|
228 * bug on Symbian/winscw. |
|
229 */ |
|
230 QSet<StateId> epsilonClosure(const QSet<StateId> &input) const |
|
231 { |
|
232 // every state can reach itself by epsilon transition, so include the input states |
|
233 // in the result as well |
|
234 QSet<StateId> result = input; |
|
235 |
|
236 // add the input states to the list of to be processed states |
|
237 QList<StateId> workStates = input.toList(); |
|
238 while (!workStates.isEmpty()) { // while there are states to be processed left... |
|
239 |
|
240 // dequeue one state from list |
|
241 const StateId state = workStates.takeFirst(); |
|
242 |
|
243 // get the list of states that can be reached by the epsilon transition |
|
244 // from the current 'state' |
|
245 const QVector<StateId> targetStates = m_epsilonTransitions.value(state); |
|
246 for (int i = 0; i < targetStates.count(); ++i) { |
|
247 // if we have this target state not in our result set yet... |
|
248 if (!result.contains(targetStates.at(i))) { |
|
249 // ... add it to the result set |
|
250 result.insert(targetStates.at(i)); |
|
251 |
|
252 // add the target state to the list of to be processed states as well, |
|
253 // as we want to have the epsilon transitions not only for the first |
|
254 // level of following states |
|
255 workStates.append(targetStates.at(i)); |
|
256 } |
|
257 } |
|
258 } |
|
259 |
|
260 return result; |
|
261 } |
222 |
262 |
223 /** |
263 /** |
224 * Returns the set of all states that can be reached from the set of given @p states |
264 * Returns the set of all states that can be reached from the set of given @p states |
225 * by the given @p input. |
265 * by the given @p input. |
226 */ |
266 * |
227 QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const; |
267 * The implementation is inlined in order to workaround a compiler |
|
268 * bug on Symbian/winscw. |
|
269 */ |
|
270 QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const |
|
271 { |
|
272 QSet<StateId> result; |
|
273 |
|
274 QSetIterator<StateId> it(states); |
|
275 while (it.hasNext()) { // iterate over all given states |
|
276 const StateId state = it.next(); |
|
277 |
|
278 // get the transition table for the current state |
|
279 const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state); |
|
280 |
|
281 // get the target states for the given input |
|
282 const QVector<StateId> targetStates = transitions.value(input); |
|
283 |
|
284 // add all target states to the result |
|
285 for (int i = 0; i < targetStates.size(); ++i) |
|
286 result.insert(targetStates.at(i)); |
|
287 } |
|
288 |
|
289 return result; |
|
290 } |
228 |
291 |
229 NamePool::Ptr m_namePool; |
292 NamePool::Ptr m_namePool; |
230 QHash<StateId, StateType> m_states; |
293 QHash<StateId, StateType> m_states; |
231 QHash<StateId, QHash<TransitionType, QVector<StateId> > > m_transitions; |
294 QHash<StateId, QHash<TransitionType, QVector<StateId> > > m_transitions; |
232 QHash<StateId, QVector<StateId> > m_epsilonTransitions; |
295 QHash<StateId, QVector<StateId> > m_epsilonTransitions; |