bool RedFsmAp::alphabetCovered( RedTransList &outRange ) { /* Cannot cover without any out ranges. */ if ( outRange.length() == 0 ) return false; /* If the first range doesn't start at the the lower bound then the * alphabet is not covered. */ RedTransList::Iter rtel = outRange; if ( keyOps->minKey < rtel->lowKey ) return false; /* Check that every range is next to the previous one. */ rtel.increment(); for ( ; rtel.lte(); rtel++ ) { Key highKey = rtel[-1].highKey; highKey.increment(); if ( highKey != rtel->lowKey ) return false; } /* The last must extend to the upper bound. */ RedTransEl *last = &outRange[outRange.length()-1]; if ( last->highKey < keyOps->maxKey ) return false; return true; }
std::ostream &RubyTabCodeGen::KEYS() { START_ARRAY_LINE(); int totalTrans = 0; 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 ), ++totalTrans, false ); } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ ARRAY_ITEM( KEY( rtel->lowKey ), ++totalTrans, false ); /* Upper key. */ ARRAY_ITEM( KEY( rtel->highKey ), ++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 &RubyTabCodeGen::INDICIES() { 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++ ) { ARRAY_ITEM( KEY( stel->value->id ), ++totalTrans, false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { ARRAY_ITEM( KEY( rtel->value->id ), ++totalTrans, false ); } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { ARRAY_ITEM( KEY( st->defTrans->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 &TabCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << stel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { out << rtel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; }
/* Gather various info on the machine. */ void CodeGenData::analyzeMachine() { /* Find the true count of action references. */ findFinalActionRefs(); /* Check if there are any calls in action code. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Record the occurrence of various kinds of actions. */ if ( act->numToStateRefs > 0 ) redFsm->bAnyToStateActions = true; if ( act->numFromStateRefs > 0 ) redFsm->bAnyFromStateActions = true; if ( act->numEofRefs > 0 ) redFsm->bAnyEofActions = true; if ( act->numTransRefs > 0 ) redFsm->bAnyRegActions = true; /* Recurse through the action's parse tree looking for various things. */ analyzeAction( act, act->inlineList ); } /* Analyze reduced action lists. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { for ( GenActionTable::Iter act = redAct->key; act.lte(); act++ ) analyzeActionList( redAct, act->value->inlineList ); } /* Find states that have transitions with actions that have next * statements. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Check any actions out of outSinge. */ for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any actions out of outRange. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any action out of default. */ if ( st->defTrans != 0 && st->defTrans->action != 0 && st->defTrans->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; if ( st->stateCondList.length() > 0 ) redFsm->bAnyConditions = true; if ( st->eofTrans != 0 ) redFsm->bAnyEofTrans = true; } /* Assign ids to actions that are referenced. */ assignActionIds(); /* Set the maximums of various values used for deciding types. */ setValueLimits(); }
std::ostream &TabCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << KEY( stel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ out << KEY( rtel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << KEY( rtel->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; }
std::ostream &JavaTabCodeGen::TRANS_ACTIONS() { 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( INT(TRANS_ACTION( trans )), false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; ARRAY_ITEM( INT(TRANS_ACTION( trans )), false ); } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; ARRAY_ITEM( INT(TRANS_ACTION( trans )), false ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; ARRAY_ITEM( INT(TRANS_ACTION( trans )), 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; }
RedTransAp *RedFsmAp::chooseDefaultNumRanges( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) stateTransSet.insert( rtel->value ); /* For each transition in the find how many ranges use the transition. */ int *numRanges = new int[stateTransSet.length()]; memset( numRanges, 0, sizeof(int) * stateTransSet.length() ); for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* Lookup the transition in the set. */ RedTransAp **inSet = stateTransSet.find( rtel->value ); numRanges[inSet - stateTransSet.data] += 1; } /* Find the max number of ranges. */ RedTransAp *maxTrans = 0; int maxNumRanges = 0; for ( RedTransSet::Iter rtel = stateTransSet; rtel.lte(); rtel++ ) { if ( numRanges[rtel.pos()] > maxNumRanges ) { maxNumRanges = numRanges[rtel.pos()]; maxTrans = *rtel; } } delete[] numRanges; return maxTrans; }
RedTransAp *RedFsmAp::chooseDefaultSpan( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) stateTransSet.insert( rtel->value ); /* For each transition in the find how many alphabet characters the * transition spans. */ unsigned long long *span = new unsigned long long[stateTransSet.length()]; memset( span, 0, sizeof(unsigned long long) * stateTransSet.length() ); for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* Lookup the transition in the set. */ RedTransAp **inSet = stateTransSet.find( rtel->value ); int pos = inSet - stateTransSet.data; span[pos] += keyOps->span( rtel->lowKey, rtel->highKey ); } /* Find the max span, choose it for making the default. */ RedTransAp *maxTrans = 0; unsigned long long maxSpan = 0; for ( RedTransSet::Iter rtel = stateTransSet; rtel.lte(); rtel++ ) { if ( span[rtel.pos()] > maxSpan ) { maxSpan = span[rtel.pos()]; maxTrans = *rtel; } } delete[] span; return maxTrans; }
void CodeGenData::findFinalActionRefs() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Rerence count out of single transitions. */ for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 ) { rtel->value->action->numTransRefs += 1; for ( GenActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } } /* Reference count out of range transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 ) { rtel->value->action->numTransRefs += 1; for ( GenActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } } /* Reference count default transition. */ if ( st->defTrans != 0 && st->defTrans->action != 0 ) { st->defTrans->action->numTransRefs += 1; for ( GenActionTable::Iter item = st->defTrans->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } /* Reference count eof transitions. */ if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) { st->eofTrans->action->numTransRefs += 1; for ( GenActionTable::Iter item = st->eofTrans->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } /* Reference count to state actions. */ if ( st->toStateAction != 0 ) { st->toStateAction->numToStateRefs += 1; for ( GenActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) item->value->numToStateRefs += 1; } /* Reference count from state actions. */ if ( st->fromStateAction != 0 ) { st->fromStateAction->numFromStateRefs += 1; for ( GenActionTable::Iter item = st->fromStateAction->key; item.lte(); item++ ) item->value->numFromStateRefs += 1; } /* Reference count EOF actions. */ if ( st->eofAction != 0 ) { st->eofAction->numEofRefs += 1; for ( GenActionTable::Iter item = st->eofAction->key; item.lte(); item++ ) item->value->numEofRefs += 1; } } }
RedTransAp *RedFsmAp::chooseDefaultGoto( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->targ == state->next ) return rtel->value; } return 0; }
void GraphvizDotGen::writeTransList( RedStateAp *state ) { /* Build the set of unique transitions out of this state. */ RedTransSet stTransSet; for ( RedTransList::Iter tel = state->outRange; tel.lte(); tel++ ) { /* If we haven't seen the transitions before, the move forward * emitting all the transitions on the same character. */ if ( stTransSet.insert( tel->value ) ) { /* Write out the from and to states. */ out << "\t" << state->id << " -> "; if ( tel->value->targ == 0 ) out << "err_" << state->id; else out << tel->value->targ->id; /* Begin the label. */ out << " [ label = \""; ONCHAR( tel->lowKey, tel->highKey ); /* Walk the transition list, finding the same. */ for ( RedTransList::Iter mtel = tel.next(); mtel.lte(); mtel++ ) { if ( mtel->value == tel->value ) { out << ", "; ONCHAR( mtel->lowKey, mtel->highKey ); } } /* Write the action and close the transition. */ TRANS_ACTION( state, tel->value ); out << "\" ];\n"; } } /* Write the default transition. */ if ( state->defTrans != 0 ) { /* Write out the from and to states. */ out << "\t" << state->id << " -> "; if ( state->defTrans->targ == 0 ) out << "err_" << state->id; else out << state->defTrans->targ->id; /* Begin the label. */ out << " [ label = \"DEF"; /* Write the action and close the transition. */ TRANS_ACTION( state, state->defTrans ); out << "\" ];\n"; } }
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 GenCondSpace*[ span ]; memset( st->condList, 0, sizeof(GenCondSpace*)*span ); for ( GenStateCondList::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 &TabCodeGen::TRANS_TARGS() { int totalTrans = 0; out << '\t'; 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; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Add any eof transitions that have not yet been written out above. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; 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; }
std::wostream &CSharpTabCodeGen::TRANS_ACTIONS() { int totalTrans = 0; out << L'\t'; 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; TRANS_ACTION( trans ) << L", "; if ( ++totalTrans % IALL == 0 ) out << L"\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; TRANS_ACTION( trans ) << L", "; if ( ++totalTrans % IALL == 0 ) out << L"\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; TRANS_ACTION( trans ) << L", "; if ( ++totalTrans % IALL == 0 ) out << L"\n\t"; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; TRANS_ACTION( trans ) << L", "; if ( ++totalTrans % IALL == 0 ) out << L"\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << L"\n"; return out; }
/* Set up labelNeeded flag for each state. */ void SplitCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); for ( RedTransList::Iter tel = st->outSingle; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); if ( st->defTrans != 0 ) setLabelsNeeded( st, st->defTrans ); } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->outNeeded = st->labelNeeded; } else { if ( redFsm->errState != 0 ) redFsm->errState->outNeeded = true; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Any state with a transition in that has a break will need an * out label. */ if ( trans->action != 0 && trans->action->anyBreakStmt() ) trans->targ->outNeeded = true; } } }
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 ); } }
std::ostream &JavaTabCodeGen::TRANS_TARGS() { int totalTrans = 0; 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 ), false ); totalTrans++; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; ARRAY_ITEM( KEY( trans->targ->id ), false ); totalTrans++; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; ARRAY_ITEM( KEY( trans->targ->id ), false ); totalTrans++; } } 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 ), 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; }
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"; }