void RedFsmAp::makeFlat() { for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { if ( st->stateCondList.length() == 0 ) { st->condLowKey = 0; st->condHighKey = 0; } else { st->condLowKey = st->stateCondList.head->lowKey; st->condHighKey = st->stateCondList.tail->highKey; unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); st->condList = new CondSpace*[ span ]; memset( st->condList, 0, sizeof(CondSpace*)*span ); for ( StateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ ) { unsigned long long base, trSpan; base = keyOps->span( st->condLowKey, sci->lowKey )-1; trSpan = keyOps->span( sci->lowKey, sci->highKey ); for ( unsigned long long pos = 0; pos < trSpan; pos++ ) st->condList[base+pos] = sci->condSpace; } } if ( st->outRange.length() == 0 ) { st->lowKey = st->highKey = 0; st->transList = 0; } else { st->lowKey = st->outRange[0].lowKey; st->highKey = st->outRange[st->outRange.length()-1].highKey; unsigned long long span = keyOps->span( st->lowKey, st->highKey ); st->transList = new RedTransAp*[ span ]; memset( st->transList, 0, sizeof(RedTransAp*)*span ); for ( RedTransList::Iter trans = st->outRange; trans.lte(); trans++ ) { unsigned long long base, trSpan; base = keyOps->span( st->lowKey, trans->lowKey )-1; trSpan = keyOps->span( trans->lowKey, trans->highKey ); for ( unsigned long long pos = 0; pos < trSpan; pos++ ) st->transList[base+pos] = trans->value; } /* Fill in the gaps with the default transition. */ for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->transList[pos] == 0 ) st->transList[pos] = st->defTrans; } } } }
std::ostream &RubyTabCodeGen::TRANS_TARGS() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; }
std::ostream &JavaTabCodeGen::KEYS() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { ARRAY_ITEM( KEY( stel->lowKey ), false ); } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ ARRAY_ITEM( KEY( rtel->lowKey ), false ); /* Upper key. */ ARRAY_ITEM( KEY( rtel->highKey ), false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), true ); return out; }
std::ostream &JavaTabCodeGen::INDICIES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { ARRAY_ITEM( KEY( stel->value->id ), false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { ARRAY_ITEM( KEY( rtel->value->id ), false ); } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { ARRAY_ITEM( KEY( st->defTrans->id ), false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), true ); return out; }
/* A default transition has been picked, move it from the outRange to the * default pointer. */ void RedFsmAp::moveToDefault( RedTransAp *defTrans, RedStateAp *state ) { /* Rewrite the outRange, omitting any ranges that use * the picked default. */ RedTransList outRange; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* If it does not take the default, copy it over. */ if ( rtel->value != defTrans ) outRange.append( *rtel ); } /* Save off the range we just created into the state's range. */ state->outRange.transfer( outRange ); /* Store the default. */ state->defTrans = defTrans; }
void RedFsmAp::depthFirstOrdering( RedStateAp *state ) { /* Nothing to do if the state is already on the list. */ if ( state->onStateList ) return; /* Doing depth first, put state on the list. */ state->onStateList = true; stateList.append( state ); /* At this point transitions should only be in ranges. */ assert( state->outSingle.length() == 0 ); assert( state->defTrans == 0 ); /* Recurse on everything ranges. */ for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->targ != 0 ) depthFirstOrdering( rtel->value->targ ); } }
void GraphvizDotGen::writeDotFile( ) { out << "digraph " << fsmName << " {\n" " rankdir=LR;\n"; /* Define the psuedo states. Transitions will be done after the states * have been defined as either final or not final. */ out << " node [ shape = point ];\n"; if ( redFsm->startState != 0 ) out << " ENTRY;\n"; /* Psuedo states for entry points in the entry map. */ for ( EntryIdVect::Iter en = entryPointIds; en.lte(); en++ ) { RedStateAp *state = allStates + *en; out << " en_" << state->id << ";\n"; } /* Psuedo states for final states with eof actions. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) out << " eof_" << st->id << ";\n"; if ( st->eofAction != 0 ) out << " eof_" << st->id << ";\n"; } out << " node [ shape = circle, height = 0.2 ];\n"; /* Psuedo states for states whose default actions go to error. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { bool needsErr = false; if ( st->defTrans != 0 && st->defTrans->targ == 0 ) needsErr = true; else { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) { if ( tel->value->targ == 0 ) { needsErr = true; break; } } } if ( needsErr ) out << " err_" << st->id << " [ label=\"\"];\n"; } /* Attributes common to all nodes, plus double circle for final states. */ out << " node [ fixedsize = true, height = 0.65, shape = doublecircle ];\n"; /* List Final states. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->isFinal ) out << " " << st->id << ";\n"; } /* List transitions. */ out << " node [ shape = circle ];\n"; /* Walk the states. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) writeTransList( st ); /* Transitions into the start state. */ if ( redFsm->startState != 0 ) out << " ENTRY -> " << redFsm->startState->id << " [ label = \"IN\" ];\n"; /* Transitions into the entry points. */ for ( EntryIdVect::Iter en = entryPointIds; en.lte(); en++ ) { RedStateAp *state = allStates + *en; char *name = entryPointNames[en.pos()]; out << " en_" << state->id << " -> " << state->id << " [ label = \"" << name << "\" ];\n"; } /* Out action transitions. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) { out << " " << st->id << " -> eof_" << st->id << " [ label = \"EOF"; ACTION( st->eofTrans->action ) << "\" ];\n"; } if ( st->eofAction != 0 ) { out << " " << st->id << " -> eof_" << st->id << " [ label = \"EOF"; ACTION( st->eofAction ) << "\" ];\n"; } } out << "}\n"; }