void FsmAp::fillGaps( StateAp *state ) { if ( state->outList.length() == 0 ) { /* Add the range on the lower and upper bound. */ attachNewTrans( state, 0, keyOps->minKey, keyOps->maxKey ); } else { TransList srcList; srcList.transfer( state->outList ); /* Check for a gap at the beginning. */ TransList::Iter trans = srcList, next; if ( keyOps->minKey < trans->lowKey ) { /* Make the high key and append. */ Key highKey = trans->lowKey; highKey.decrement(); attachNewTrans( state, 0, keyOps->minKey, highKey ); } /* Write the transition. */ next = trans.next(); state->outList.append( trans ); /* Keep the last high end. */ Key lastHigh = trans->highKey; /* Loop each source range. */ for ( trans = next; trans.lte(); trans = next ) { /* Make the next key following the last range. */ Key nextKey = lastHigh; nextKey.increment(); /* Check for a gap from last up to here. */ if ( nextKey < trans->lowKey ) { /* Make the high end of the range that fills the gap. */ Key highKey = trans->lowKey; highKey.decrement(); attachNewTrans( state, 0, nextKey, highKey ); } /* Reduce the transition. If it reduced to anything then add it. */ next = trans.next(); state->outList.append( trans ); /* Keep the last high end. */ lastHigh = trans->highKey; } /* Now check for a gap on the end to fill. */ if ( lastHigh < keyOps->maxKey ) { /* Get a copy of the default. */ lastHigh.increment(); attachNewTrans( state, 0, lastHigh, keyOps->maxKey ); } } }
/* Detach a state from the graph. Detaches and deletes transitions in and out * of the state. Empties inList and outList. Removes the state from the final * state set. A detached state becomes useless and should be deleted. */ void FsmAp::detachState( StateAp *state ) { /* Detach the in transitions from the inList list of transitions. */ while ( state->inList.head != 0 ) { /* Get pointers to the trans and the state. */ TransAp *trans = state->inList.head; StateAp *fromState = trans->fromState; /* Detach the transitions from the source state. */ detachTrans( fromState, state, trans ); /* Ok to delete the transition. */ fromState->outList.detach( trans ); delete trans; } /* Remove the entry points in on the machine. */ while ( state->entryIds.length() > 0 ) unsetEntry( state->entryIds[0], state ); /* Detach out range transitions. */ for ( TransList::Iter trans = state->outList; trans.lte(); ) { TransList::Iter next = trans.next(); detachTrans( state, trans->toState, trans ); delete trans; trans = next; } /* Delete all of the out range pointers. */ state->outList.abandon(); /* Unset final stateness before detaching from graph. */ if ( state->stateBits & SB_ISFINAL ) finStateSet.remove( state ); }
/* Merge neighboring transitions go to the same state and have the same * transitions data. */ void FsmAp::compressTransitions() { for ( StateList::Iter st = stateList; st.lte(); st++ ) { if ( st->outList.length() > 1 ) { for ( TransList::Iter trans = st->outList, next = trans.next(); next.lte(); ) { Key nextLow = next->lowKey; nextLow.decrement(); if ( trans->highKey == nextLow && trans->toState == next->toState && CmpActionTable::compare( trans->actionTable, next->actionTable ) == 0 ) { trans->highKey = next->highKey; st->outList.detach( next ); detachTrans( next->fromState, next->toState, next ); delete next; next = trans.next(); } else { trans.increment(); next.increment(); } } } } }