333 stateTable.append(qMakePair<QSet<StateId>, StateId>(nfaState, dfaState)); |
333 stateTable.append(qMakePair<QSet<StateId>, StateId>(nfaState, dfaState)); |
334 |
334 |
335 return dfaState; |
335 return dfaState; |
336 } |
336 } |
337 |
337 |
338 |
|
339 template <typename TransitionType> |
|
340 QSet<typename XsdStateMachine<TransitionType>::StateId> XsdStateMachine<TransitionType>::epsilonClosure(const QSet<StateId> &input) const |
|
341 { |
|
342 // every state can reach itself by epsilon transition, so include the input states |
|
343 // in the result as well |
|
344 QSet<StateId> result = input; |
|
345 |
|
346 // add the input states to the list of to be processed states |
|
347 QList<StateId> workStates = input.toList(); |
|
348 while (!workStates.isEmpty()) { // while there are states to be processed left... |
|
349 |
|
350 // dequeue one state from list |
|
351 const StateId state = workStates.takeFirst(); |
|
352 |
|
353 // get the list of states that can be reached by the epsilon transition |
|
354 // from the current 'state' |
|
355 const QVector<StateId> targetStates = m_epsilonTransitions.value(state); |
|
356 for (int i = 0; i < targetStates.count(); ++i) { |
|
357 // if we have this target state not in our result set yet... |
|
358 if (!result.contains(targetStates.at(i))) { |
|
359 // ... add it to the result set |
|
360 result.insert(targetStates.at(i)); |
|
361 |
|
362 // add the target state to the list of to be processed states as well, |
|
363 // as we want to have the epsilon transitions not only for the first |
|
364 // level of following states |
|
365 workStates.append(targetStates.at(i)); |
|
366 } |
|
367 } |
|
368 } |
|
369 |
|
370 return result; |
|
371 } |
|
372 |
|
373 template <typename TransitionType> |
|
374 QSet<typename XsdStateMachine<TransitionType>::StateId> XsdStateMachine<TransitionType>::move(const QSet<StateId> &states, TransitionType input) const |
|
375 { |
|
376 QSet<StateId> result; |
|
377 |
|
378 QSetIterator<StateId> it(states); |
|
379 while (it.hasNext()) { // iterate over all given states |
|
380 const StateId state = it.next(); |
|
381 |
|
382 // get the transition table for the current state |
|
383 const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state); |
|
384 |
|
385 // get the target states for the given input |
|
386 const QVector<StateId> targetStates = transitions.value(input); |
|
387 |
|
388 // add all target states to the result |
|
389 for (int i = 0; i < targetStates.size(); ++i) |
|
390 result.insert(targetStates.at(i)); |
|
391 } |
|
392 |
|
393 return result; |
|
394 } |
|
395 |
|
396 template <typename TransitionType> |
338 template <typename TransitionType> |
397 XsdStateMachine<TransitionType> XsdStateMachine<TransitionType>::toDFA() const |
339 XsdStateMachine<TransitionType> XsdStateMachine<TransitionType>::toDFA() const |
398 { |
340 { |
399 XsdStateMachine<TransitionType> dfa(m_namePool); |
341 XsdStateMachine<TransitionType> dfa(m_namePool); |
400 dfa.m_counter = 100; |
342 dfa.m_counter = 100; |
467 template <typename TransitionType> |
409 template <typename TransitionType> |
468 QHash<typename XsdStateMachine<TransitionType>::StateId, typename XsdStateMachine<TransitionType>::StateType> XsdStateMachine<TransitionType>::states() const |
410 QHash<typename XsdStateMachine<TransitionType>::StateId, typename XsdStateMachine<TransitionType>::StateType> XsdStateMachine<TransitionType>::states() const |
469 { |
411 { |
470 return m_states; |
412 return m_states; |
471 } |
413 } |
472 |
|
473 template <typename TransitionType> |
|
474 QHash<typename XsdStateMachine<TransitionType>::StateId, QHash<TransitionType, QVector<typename XsdStateMachine<TransitionType>::StateId> > > XsdStateMachine<TransitionType>::transitions() const |
|
475 { |
|
476 return m_transitions; |
|
477 } |
|