/* 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(); }
/* Assign ids to referenced actions. */ void CodeGenData::assignActionIds() { int nextActionId = 0; for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Only ever interested in referenced actions. */ if ( act->numRefs() > 0 ) act->actionId = nextActionId++; } }
void CodeGenData::closeMachine() { for ( GenActionList::Iter a = actionList; a.lte(); a++ ) resolveTargetStates( a->inlineList ); /* Note that even if we want a complete graph we do not give the error * state a default transition. All machines break out of the processing * loop when in the error state. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( GenStateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ ) st->stateCondVect.append( sci ); } }
std::ostream &RubyTabCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "when " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; }
std::ostream &OCamlTabCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, true ); } } genLineDirective( out ); return out; }
std::ostream &TabCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; }