"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/ipgoto.cc" between
ragel-7.0.0.11.tar.gz and ragel-7.0.0.12.tar.gz

About: Ragel compiles executable finite state machines from regular languages (C, C++, Obj-C, C#, D, Java, Go and Ruby). Development version.

ipgoto.cc  (ragel-7.0.0.11):ipgoto.cc  (ragel-7.0.0.12)
skipping to change at line 86 skipping to change at line 86
{ {
return redFsm->anyActionRets() || return redFsm->anyActionRets() ||
redFsm->anyActionByValControl() || redFsm->anyActionByValControl() ||
redFsm->anyRegNextStmt(); redFsm->anyRegNextStmt();
} }
void IpGoto::EOF_CHECK( ostream &ret, int gotoDest ) void IpGoto::EOF_CHECK( ostream &ret, int gotoDest )
{ {
ret << ret <<
" if ( " << P() << " == " << PE() << " )\n" " if ( " << P() << " == " << PE() << " )\n"
" goto _test_eof" << gotoDest << ";\n"; " goto " << eofLabel[gotoDest].reference() << ";\n"
;
testEofUsed = true;
} }
void IpGoto::GOTO( ostream &ret, int gotoDest, bool inFinish ) void IpGoto::GOTO( ostream &ret, int gotoDest, bool inFinish )
{ {
ret << OPEN_GEN_BLOCK(); ret << OPEN_GEN_BLOCK();
if ( inFinish && !noEnd ) if ( inFinish && !noEnd )
EOF_CHECK( ret, gotoDest ); EOF_CHECK( ret, gotoDest );
ret << "goto st" << gotoDest << ";"; ret << "goto " << stLabel[gotoDest].reference() << ";";
ret << CLOSE_GEN_BLOCK(); ret << CLOSE_GEN_BLOCK();
} }
void IpGoto::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) void IpGoto::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
{ {
ret << OPEN_GEN_BLOCK() << vCS() << " = " << OPEN_HOST_EXPR(); ret << OPEN_GEN_BLOCK() << vCS() << " = " << OPEN_HOST_EXPR();
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
ret << CLOSE_HOST_EXPR() << ";"; ret << CLOSE_HOST_EXPR() << ";";
/* Since we are setting CS above and can select on it, call the all-state /* Since we are setting CS above and can select on it, call the all-state
* test_eof. */ * test_eof. */
if ( inFinish && !noEnd ) if ( inFinish && !noEnd )
CodeGen::EOF_CHECK( ret ); Goto::EOF_CHECK( ret );
ret << " goto _again;"; ret << " goto " << _again << ";";
ret << CLOSE_GEN_BLOCK(); ret << CLOSE_GEN_BLOCK();
} }
void IpGoto::CALL( ostream &ret, int callDest, int targState, bool inFinish ) void IpGoto::CALL( ostream &ret, int callDest, int targState, bool inFinish )
{ {
ret << OPEN_GEN_BLOCK(); ret << OPEN_GEN_BLOCK();
if ( red->prePushExpr != 0 ) { if ( red->prePushExpr != 0 ) {
ret << OPEN_HOST_BLOCK( red->prePushExpr ); ret << OPEN_HOST_BLOCK( red->prePushExpr );
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ;
ret << CLOSE_HOST_BLOCK(); ret << CLOSE_HOST_BLOCK();
} }
ret << STACK() << "[" << TOP() << "] = " << targState << ret << STACK() << "[" << TOP() << "] = " << targState <<
"; " << TOP() << "+= 1; "; "; " << TOP() << "+= 1; ";
if ( inFinish && !noEnd ) if ( inFinish && !noEnd )
EOF_CHECK( ret, callDest ); EOF_CHECK( ret, callDest );
ret << "goto st" << callDest << ";"; ret << "goto " << stLabel[callDest].reference() << ";";
ret << CLOSE_GEN_BLOCK(); ret << CLOSE_GEN_BLOCK();
} }
void IpGoto::NCALL( ostream &ret, int callDest, int targState, bool inFinish ) void IpGoto::NCALL( ostream &ret, int callDest, int targState, bool inFinish )
{ {
ret << OPEN_GEN_BLOCK(); ret << OPEN_GEN_BLOCK();
if ( red->prePushExpr != 0 ) { if ( red->prePushExpr != 0 ) {
ret << OPEN_HOST_BLOCK( red->prePushExpr ); ret << OPEN_HOST_BLOCK( red->prePushExpr );
skipping to change at line 173 skipping to change at line 171
} }
ret << STACK() << "[" << TOP() << "] = " << targState << "; " << TOP() << "+= 1;" << ret << STACK() << "[" << TOP() << "] = " << targState << "; " << TOP() << "+= 1;" <<
vCS() << " = " << OPEN_HOST_EXPR(); vCS() << " = " << OPEN_HOST_EXPR();
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
ret << CLOSE_HOST_EXPR() << ";"; ret << CLOSE_HOST_EXPR() << ";";
/* Since we are setting CS above and can select on it, call the all-state /* Since we are setting CS above and can select on it, call the all-state
* test_eof. */ * test_eof. */
if ( inFinish && !noEnd ) if ( inFinish && !noEnd )
CodeGen::EOF_CHECK( ret ); Goto::EOF_CHECK( ret );
ret << " goto _again;"; ret << " goto " << _again << ";";
ret << CLOSE_GEN_BLOCK(); ret << CLOSE_GEN_BLOCK();
} }
void IpGoto::NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, boo l inFinish ) void IpGoto::NCALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, boo l inFinish )
{ {
ret << OPEN_GEN_BLOCK(); ret << OPEN_GEN_BLOCK();
if ( red->prePushExpr != 0 ) { if ( red->prePushExpr != 0 ) {
ret << OPEN_HOST_BLOCK( red->prePushExpr ); ret << OPEN_HOST_BLOCK( red->prePushExpr );
skipping to change at line 208 skipping to change at line 206
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = "
<< STACK() << "[" << TOP() << "];"; << STACK() << "[" << TOP() << "];";
if ( red->postPopExpr != 0 ) { if ( red->postPopExpr != 0 ) {
ret << OPEN_HOST_BLOCK( red->postPopExpr ); ret << OPEN_HOST_BLOCK( red->postPopExpr );
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ;
ret << CLOSE_HOST_BLOCK(); ret << CLOSE_HOST_BLOCK();
} }
if ( inFinish && !noEnd ) if ( inFinish && !noEnd )
CodeGen::EOF_CHECK( ret ); Goto::EOF_CHECK( ret );
ret << "goto _again;" << CLOSE_GEN_BLOCK(); ret << "goto " << _again << ";" << CLOSE_GEN_BLOCK();
} }
void IpGoto::NRET( ostream &ret, bool inFinish ) void IpGoto::NRET( ostream &ret, bool inFinish )
{ {
ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = " ret << OPEN_GEN_BLOCK() << TOP() << " -= 1;" << vCS() << " = "
<< STACK() << "[" << TOP() << "];"; << STACK() << "[" << TOP() << "];";
if ( red->postPopExpr != 0 ) { if ( red->postPopExpr != 0 ) {
ret << OPEN_HOST_BLOCK( red->postPopExpr ); ret << OPEN_HOST_BLOCK( red->postPopExpr );
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ;
skipping to change at line 241 skipping to change at line 239
void IpGoto::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) void IpGoto::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish )
{ {
ret << vCS() << " = ("; ret << vCS() << " = (";
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); INLINE_LIST( ret, ilItem->children, 0, inFinish, false );
ret << ");"; ret << ");";
} }
void IpGoto::CURS( ostream &ret, bool inFinish ) void IpGoto::CURS( ostream &ret, bool inFinish )
{ {
ret << "(_ps)"; ret << "(" << ps << ")";
} }
void IpGoto::TARGS( ostream &ret, bool inFinish, int targState ) void IpGoto::TARGS( ostream &ret, bool inFinish, int targState )
{ {
ret << targState; ret << targState;
} }
void IpGoto::BREAK( ostream &ret, int targState, bool csForced ) void IpGoto::BREAK( ostream &ret, int targState, bool csForced )
{ {
outLabelUsed = true;
ret << "{" << P() << "+= 1; "; ret << "{" << P() << "+= 1; ";
if ( !csForced ) if ( !csForced )
ret << vCS() << " = " << targState << "; "; ret << vCS() << " = " << targState << "; ";
ret << "goto _out;}"; ret << "goto " << _out << ";}";
} }
void IpGoto::NBREAK( ostream &ret, int targState, bool csForced ) void IpGoto::NBREAK( ostream &ret, int targState, bool csForced )
{ {
outLabelUsed = true;
ret << "{" << P() << "+= 1; "; ret << "{" << P() << "+= 1; ";
if ( !csForced ) if ( !csForced )
ret << vCS() << " = " << targState << "; "; ret << vCS() << " = " << targState << "; ";
ret << "_nbreak = 1;}"; ret << nbreak << " = 1;}";
} }
void IpGoto::NFA_PUSH_ACTION( RedNfaTarg *targ ) void IpGoto::NFA_PUSH_ACTION( RedNfaTarg *targ )
{ {
int act = 0; int act = 0;
if ( targ->push != 0 ) if ( targ->push != 0 )
act = targ->push->actListId+1; act = targ->push->actListId+1;
nfaPushActions.value( act ); nfaPushActions.value( act );
} }
skipping to change at line 296 skipping to change at line 292
/* Emit any transitions that have actions and that go to this state. */ /* Emit any transitions that have actions and that go to this state. */
for ( int it = 0; it < state->numInConds; it++ ) { for ( int it = 0; it < state->numInConds; it++ ) {
RedCondPair *trans = state->inConds[it]; RedCondPair *trans = state->inConds[it];
if ( trans->action != 0 ) { if ( trans->action != 0 ) {
/* Remember that we wrote an action so we know to write t he /* Remember that we wrote an action so we know to write t he
* line directive for going back to the output. */ * line directive for going back to the output. */
anyWritten = true; anyWritten = true;
/* Write the label for the transition so it can be jumped to. */ /* Write the label for the transition so it can be jumped to. */
out << "ctr" << trans->id << ":\n"; if ( ctrLabel[trans->id].isReferenced )
out << "_ctr" << trans->id << ":\n";
/* If the action contains a next, then we must preload th e current /* If the action contains a next, then we must preload th e current
* state since the action may or may not set it. */ * state since the action may or may not set it. */
if ( trans->action->anyNextStmt() ) if ( trans->action->anyNextStmt() )
out << " " << vCS() << " = " << trans->tar g->id << ";\n"; out << " " << vCS() << " = " << trans->tar g->id << ";\n";
if ( redFsm->anyRegNbreak() ) if ( redFsm->anyRegNbreak() )
out << "_nbreak = 0;\n"; out << nbreak << " = 0;\n";
/* Write each action in the list. */ /* Write each action in the list. */
for ( GenActionTable::Iter item = trans->action->key; ite m.lte(); item++ ) { for ( GenActionTable::Iter item = trans->action->key; ite m.lte(); item++ ) {
ACTION( out, item->value, IlOpts( trans->targ->id , false, ACTION( out, item->value, IlOpts( trans->targ->id , false,
trans->action->anyNextStmt() ) ); trans->action->anyNextStmt() ) );
out << "\n"; out << "\n";
} }
if ( redFsm->anyRegNbreak() ) { if ( redFsm->anyRegNbreak() ) {
out << out <<
"if ( _nbreak == 1 )\n" "if ( " << nbreak << " == 1 )\n"
" goto _out;\n"; " goto " << _out << ";\n";
outLabelUsed = true;
} }
/* If the action contains a next then we need to reload, otherwise /* If the action contains a next then we need to reload, otherwise
* jump directly to the target state. */ * jump directly to the target state. */
if ( trans->action->anyNextStmt() ) if ( trans->action->anyNextStmt() )
out << "\n\tgoto _again;\n"; out << "goto " << _again << ";\n";
else else
out << "\n\tgoto st" << trans->targ->id << ";\n"; out << "goto " << stLabel[trans->targ->id].refere nce() << ";\n";
} }
} }
return anyWritten; return anyWritten;
} }
/* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for each /* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for each
* state. */ * state. */
void IpGoto::GOTO_HEADER( RedStateAp *state ) void IpGoto::GOTO_HEADER( RedStateAp *state )
{ {
IN_TRANS_ACTIONS( state ); IN_TRANS_ACTIONS( state );
if ( state->labelNeeded ) if ( stLabel[state->id].isReferenced )
out << "st" << state->id << ":\n"; out << "_st" << state->id << ":\n";
/* need to do this if the transition is an eof transition, or if the acti
on
* contains fexec. Otherwise, no need. */
if ( redFsm->anyEofActivity() ) {
out <<
"if ( " << P() << " == " << vEOF() << " ) {\n"
" if ( " << vCS() << " >= " << FIRST_FINAL_STATE()
<< " )\n"
" goto " << _out << ";\n"
" else\n"
" goto " << _pop << ";\n"
"}\n";
}
if ( state->toStateAction != 0 ) { if ( state->toStateAction != 0 ) {
/* Write every action in the list. */ /* Write every action in the list. */
for ( GenActionTable::Iter item = state->toStateAction->key; item .lte(); item++ ) { for ( GenActionTable::Iter item = state->toStateAction->key; item .lte(); item++ ) {
ACTION( out, item->value, IlOpts( state->id, false, ACTION( out, item->value, IlOpts( state->id, false,
state->toStateAction->anyNextStmt() ) ); state->toStateAction->anyNextStmt() ) );
out << "\n"; out << "\n";
} }
} }
/* Advance and test buffer pos. */ /* Advance and test buffer pos. */
if ( state->labelNeeded ) { if ( state->labelNeeded ) {
if ( !noEnd ) { if ( !noEnd ) {
out << out <<
" " << P() << "+= 1;\n" P() << "+= 1;\n"
" if ( " << P() << " == " << PE() << " )\n" "if ( " << P() << " == " << PE() << " )\n"
" goto _test_eof" << state->id << " " goto " << eofLabel[state->id].reference()
;\n"; << ";\n";
} }
else { else {
out << out <<
" " << P() << " += 1;\n"; P() << " += 1;\n";
} }
} }
/* Give the state a switch case. */ /* Give the state a switch case. */
out << "st_case_" << state->id << ":\n"; out << "st_case_" << state->id << ":\n";
if ( state->fromStateAction != 0 ) { if ( state->fromStateAction != 0 ) {
/* Write every action in the list. */ /* Write every action in the list. */
for ( GenActionTable::Iter item = state->fromStateAction->key; it em.lte(); item++ ) { for ( GenActionTable::Iter item = state->fromStateAction->key; it em.lte(); item++ ) {
ACTION( out, item->value, IlOpts( state->id, false, ACTION( out, item->value, IlOpts( state->id, false,
state->fromStateAction->anyNextStmt() ) ) ; state->fromStateAction->anyNextStmt() ) ) ;
out << "\n"; out << "\n";
} }
} }
/* Record the prev state if necessary. */ /* Record the prev state if necessary. */
if ( state->anyRegCurStateRef() ) if ( state->anyRegCurStateRef() )
out << " _ps = " << state->id << ";\n"; out << ps << " = " << state->id << ";\n";
} }
void IpGoto::STATE_GOTO_ERROR() void IpGoto::STATE_GOTO_ERROR()
{ {
/* In the error state we need to emit some stuff that usually goes into /* In the error state we need to emit some stuff that usually goes into
* the header. */ * the header. */
RedStateAp *state = redFsm->errState; RedStateAp *state = redFsm->errState;
IN_TRANS_ACTIONS( state ); IN_TRANS_ACTIONS( state );
out << "st_case_" << state->id << ":\n"; out << "st_case_" << state->id << ":\n";
if ( state->labelNeeded ) if ( stLabel[state->id].isReferenced )
out << "st" << state->id << ":\n"; out << "_st" << state->id << ":\n";
/* Break out here. */ /* Break out here. */
outLabelUsed = true;
out << vCS() << " = " << state->id << ";\n"; out << vCS() << " = " << state->id << ";\n";
out << " goto _out;\n"; out << "goto " << _pop << ";\n";
} }
/* Emit the goto to take for a given transition. */ /* Emit the goto to take for a given transition. */
std::ostream &IpGoto::TRANS_GOTO( RedTransAp *trans, int level ) std::ostream &IpGoto::TRANS_GOTO( RedTransAp *trans )
{ {
if ( trans->condSpace == 0 || trans->condSpace->condSet.length() == 0 ) { if ( trans->condSpace == 0 || trans->condSpace->condSet.length() == 0 ) {
/* Existing. */ /* Existing. */
assert( trans->numConds() == 1 ); assert( trans->numConds() == 1 );
RedCondPair *cond = trans->outCond( 0 ); RedCondPair *cond = trans->outCond( 0 );
if ( cond->action != 0 ) { if ( cond->action != 0 ) {
/* Go to the transition which will go to the state. */ /* Go to the transition which will go to the state. */
out << TABS(level) << "goto ctr" << cond->id << ";"; out << "goto " << ctrLabel[trans->p.id].reference() << "; ";
} }
else { else {
/* Go directly to the target state. */ /* Go directly to the target state. */
out << TABS(level) << "goto st" << cond->targ->id << ";"; out << "goto " << stLabel[cond->targ->id].reference() << ";";
} }
} }
else { else {
out << TABS(level) << "int ck = 0;\n"; out << ck << " = 0;\n";
for ( GenCondSet::Iter csi = trans->condSpace->condSet; csi.lte() ; csi++ ) { for ( GenCondSet::Iter csi = trans->condSpace->condSet; csi.lte() ; csi++ ) {
out << TABS(level) << "if ( "; out << "if ( ";
CONDITION( out, *csi ); CONDITION( out, *csi );
Size condValOffset = (1 << csi.pos()); Size condValOffset = (1 << csi.pos());
out << " ) ck += " << condValOffset << ";\n"; out << " )\n" << ck << " += " << condValOffset << ";\n";
} }
CondKey lower = 0; CondKey lower = 0;
CondKey upper = trans->condFullSize() - 1; CondKey upper = trans->condFullSize() - 1;
COND_B_SEARCH( trans, 1, lower, upper, 0, trans->numConds() - 1 ) ; COND_B_SEARCH( trans, lower, upper, 0, trans->numConds() - 1 );
if ( trans->errCond() != 0 ) { if ( trans->errCond() != 0 ) {
COND_GOTO( trans->errCond(), level+1 ) << "\n"; COND_GOTO( trans->errCond() ) << "\n";
} }
} }
return out; return out;
} }
/* Emit the goto to take for a given transition. */ /* Emit the goto to take for a given transition. */
std::ostream &IpGoto::COND_GOTO( RedCondPair *cond, int level ) std::ostream &IpGoto::COND_GOTO( RedCondPair *cond )
{ {
/* Existing. */ /* Existing. */
if ( cond->action != 0 ) { if ( cond->action != 0 ) {
/* Go to the transition which will go to the state. */ /* Go to the transition which will go to the state. */
out << TABS(level) << "goto ctr" << cond->id << ";"; out << "goto " << ctrLabel[cond->id].reference() << ";";
} }
else { else {
/* Go directly to the target state. */ /* Go directly to the target state. */
out << TABS(level) << "goto st" << cond->targ->id << ";"; out << "goto " << stLabel[cond->targ->id].reference() << ";";
} }
return out; return out;
} }
std::ostream &IpGoto::EXIT_STATES() std::ostream &IpGoto::EXIT_STATES()
{ {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st->outNeeded ) { if ( eofLabel[st->id].isReferenced ) {
testEofUsed = true; out << eofLabel[st->id].define() << ": " << vCS() << " =
out << " _test_eof" << st->id << ": " << vCS() << " <<
" = " << st->id << "; goto " << _test_eof << "; \n
st->id << "; goto _test_eof; \n"; ";
} }
} }
return out; return out;
} }
std::ostream &IpGoto::AGAIN_CASES() std::ostream &IpGoto::AGAIN_CASES()
{ {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
out << out <<
" case " << st->id << ": goto st" << st->id << ";\n"; "case " << st->id << ": goto " << stLabel[st->id].referen ce() << ";\n";
} }
return out; return out;
} }
std::ostream &IpGoto::STATE_GOTO_CASES() std::ostream &IpGoto::STATE_GOTO_CASES()
{ {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
out << TABS(1) << "case " << st->id << ":\n"; out << "case " << st->id << ":\n";
out << TABS(2) << "goto st_case_" << st->id << ";\n"; out << "goto st_case_" << st->id << ";\n";
} }
return out; return out;
} }
void IpGoto::NFA_PUSH( RedStateAp *state ) void IpGoto::NFA_PUSH( RedStateAp *state )
{ {
std::stringstream ss; std::stringstream ss;
ss << state->id; ss << state->id;
CodeGen::NFA_PUSH( ss.str() ); std::string _state = ss.str();
if ( redFsm->anyNfaStates() ) {
if ( state->nfaTargs != 0 ) {
out <<
"if ( " << ARR_REF( nfaOffsets ) << "[" << _state
<< "] ) {\n"
" " << new_recs << " = " << state->nfaTargs
->length() << ";\n";
if ( red->nfaPrePushExpr != 0 ) {
out << OPEN_HOST_BLOCK( red->nfaPrePushExpr );
INLINE_LIST( out, red->nfaPrePushExpr->inlineList
, 0, false, false );
out << CLOSE_HOST_BLOCK();
}
int alt = 0;
for ( RedNfaTargs::Iter nt = *state->nfaTargs; nt.lte();
nt++ ) {
out <<
" nfa_bp[nfa_len].state = " << nt->
state->id << ";\n"
" nfa_bp[nfa_len].p = " << P() << "
;\n";
if ( nt->popTest != 0 ) {
out <<
" nfa_bp[nfa_len].popTrans
= " << (nt->popTest->actListId+1) << ";\n";
}
else if ( redFsm->bAnyNfaPops ) {
out <<
" nfa_bp[nfa_len].popTrans
= 0;\n";
}
if ( nt->push != 0 ) {
for ( GenActionTable::Iter item = nt->pus
h->key; item.lte(); item++ )
ACTION( out, item->value, IlOpts(
0, false, false ) );
}
out <<
" nfa_len += 1;\n";
alt += 1;
}
out <<
"}\n";
}
}
} }
std::ostream &IpGoto::STATE_GOTOS() std::ostream &IpGoto::STATE_GOTOS()
{ {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st == redFsm->errState ) if ( st == redFsm->errState )
STATE_GOTO_ERROR(); STATE_GOTO_ERROR();
else { else {
/* Writing code above state gotos. */ /* Writing code above state gotos. */
GOTO_HEADER( st ); GOTO_HEADER( st );
NFA_PUSH( st ); NFA_PUSH( st );
/* Try singles. */ /* Try singles. */
if ( st->outSingle.length() > 0 ) if ( st->outSingle.length() > 0 )
SINGLE_SWITCH( st ); SINGLE_SWITCH( st );
/* Default case is to binary search for the ranges, if th at fails then */ /* Default case is to binary search for the ranges, if th at fails then */
if ( st->outRange.length() > 0 ) { if ( st->outRange.length() > 0 ) {
RANGE_B_SEARCH( st, 1, keyOps->minKey, keyOps->ma xKey, RANGE_B_SEARCH( st, keyOps->minKey, keyOps->maxKe y,
0, st->outRange.length() - 1 ); 0, st->outRange.length() - 1 );
} }
/* Write the default transition. */ /* Write the default transition. */
out << "{\n"; out << "{\n";
TRANS_GOTO( st->defTrans, 1 ) << "\n"; TRANS_GOTO( st->defTrans ) << "\n";
out << "}\n"; out << "}\n";
} }
} }
return out; return out;
} }
std::ostream &IpGoto::FINISH_CASES() std::ostream &IpGoto::FINISH_CASES()
{ {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st->eofAction != 0 ) {
if ( st->eofAction->eofRefs == 0 )
st->eofAction->eofRefs = new IntSet;
st->eofAction->eofRefs->insert( st->id );
}
}
for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ )
{
if ( act->eofRefs != 0 ) {
for ( IntSet::Iter pst = *act->eofRefs; pst.lte(); pst++
) {
out << " case " << *pst << ": \n";
if ( ! pst.last() )
out << " " << FALLTHROUGH(
) << "\n";
}
/* Write each action in the eof action list. */
for ( GenActionTable::Iter item = act->key; item.lte(); i
tem++ )
ACTION( out, item->value, IlOpts( STATE_ERR_STATE
, true, false ) );
out << "\n\tbreak;\n";
}
}
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st->eofTrans != 0 ) { if ( st->eofTrans != 0 ) {
RedCondPair *cond = st->eofTrans->outCond( 0 ); out <<
out << " case " << st->id << ": goto ctr" << cond- "case " << st->id << ":\n";
>id << ";\n";
TRANS_GOTO( st->eofTrans );
} }
} }
return out; return out;
} }
void IpGoto::setLabelsNeeded( GenInlineList *inlineList ) void IpGoto::setLabelsNeeded( GenInlineList *inlineList )
{ {
for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) {
switch ( item->type ) { switch ( item->type ) {
case GenInlineItem::Goto: case GenInlineItem::Call: case GenInlineItem::Goto:
case GenInlineItem::Ncall: { case GenInlineItem::Call:
/* Mark the target as needing a label. */ case GenInlineItem::Ncall: {
item->targState->labelNeeded = true; /* Mark the target as needing a label. */
break; item->targState->labelNeeded = true;
} break;
default: break; }
default: break;
} }
if ( item->children != 0 ) if ( item->children != 0 )
setLabelsNeeded( item->children ); setLabelsNeeded( item->children );
} }
} }
void IpGoto::setLabelsNeeded( RedCondPair *pair ) void IpGoto::setLabelsNeeded( RedCondPair *pair )
{ {
/* If there is no action with a next statement, then the label will be /* If there is no action with a next statement, then the label will be
skipping to change at line 617 skipping to change at line 647
for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ ) for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ )
setLabelsNeeded( &cond->p ); setLabelsNeeded( &cond->p );
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st->eofAction != 0 ) { if ( st->eofAction != 0 ) {
for ( GenActionTable::Iter item = st->eofAction-> key; item.lte(); item++ ) for ( GenActionTable::Iter item = st->eofAction-> key; item.lte(); item++ )
setLabelsNeeded( item->value->inlineList ); setLabelsNeeded( item->value->inlineList );
} }
} }
} }
if ( !noEnd ) {
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ )
{
if ( st != redFsm->errState )
st->outNeeded = st->labelNeeded;
}
}
} }
void IpGoto::writeData() void IpGoto::writeData()
{ {
STATE_IDS(); STATE_IDS();
taNfaTargs(); taNfaTargs();
taNfaOffsets(); taNfaOffsets();
taNfaPushActions(); taNfaPushActions();
taNfaPopTrans(); taNfaPopTrans();
} }
void IpGoto::NFA_FROM_STATE_ACTION_EXEC() void IpGoto::NFA_FROM_STATE_ACTION_EXEC()
{ {
if ( redFsm->anyFromStateActions() ) { // if ( redFsm->anyFromStateActions() ) {
/* Unimplemented feature. Don't have the from state actions array // /* Unimplemented feature. Don't have the from state actions array
in in
* this mode. Need to add it, or to alter the NFA pop codegen to // * this mode. Need to add it, or to alter the NFA pop codegen to
be be
* consistent with the mode. */ // * consistent with the mode. */
assert( false ); // assert( false );
} // }
} }
void IpGoto::writeExec() void IpGoto::writeExec()
{ {
int maxCtrId = redFsm->nextCondId > redFsm->nextTransId ? redFsm->nextCon
dId : redFsm->nextTransId;
stLabel = allocateLabels( stLabel, IpLabel::St, redFsm->nextStateId );
eofLabel = allocateLabels( eofLabel, IpLabel::TestEof, redFsm->nextStateI
d );
ctrLabel = allocateLabels( ctrLabel, IpLabel::Ctr, maxCtrId );
/* Must set labels immediately before writing because we may depend on th e /* Must set labels immediately before writing because we may depend on th e
* noend write option. */ * noend write option. */
setLabelsNeeded(); setLabelsNeeded();
testEofUsed = false;
outLabelUsed = false;
out << " {\n";
if ( redFsm->anyRegNbreak() ) out << "{\n";
out << " int _nbreak;\n";
if ( redFsm->anyRegCurStateRef() ) DECLARE( INT(), cpc );
out << " int _ps = 0;\n"; DECLARE( INT(), ck );
DECLARE( INT(), pop_test );
DECLARE( INT(), nbreak );
DECLARE( INT(), ps );
DECLARE( INT(), new_recs );
DECLARE( INT(), alt );
if ( !noEnd ) { if ( !noEnd ) {
testEofUsed = true;
out << out <<
" if ( " << P() << " == " << PE() << " )\n" " if ( " << P() << " == " << PE() << " )\n"
" goto _test_eof;\n"; " goto " << _test_eof << ";\n";
} }
if ( useAgainLabel() ) { if ( _again.isReferenced ) {
out <<
" goto " << _resume << ";\n"
"\n";
out << EMIT_LABEL( _again );
out << out <<
" goto _resume;\n"
"\n"
"_again:\n"
" switch ( " << vCS() << " ) {\n"; " switch ( " << vCS() << " ) {\n";
AGAIN_CASES() << AGAIN_CASES() <<
" }\n" " }\n"
"\n"; "\n";
} }
if ( useAgainLabel() || redFsm->anyNfaStates() ) out << EMIT_LABEL( _resume );
out << "_resume:\n";
out << out <<
" switch ( " << vCS() << " )\n" " switch ( " << vCS() << " ) {\n";
" {\n";
STATE_GOTO_CASES() << STATE_GOTO_CASES() <<
" }\n" " }\n"
" goto st_out;\n"; " goto st_out;\n";
STATE_GOTOS() << STATE_GOTOS() <<
" st_out:\n"; " st_out:\n";
EXIT_STATES() << EXIT_STATES() <<
"\n"; "\n";
if ( testEofUsed ) out << EMIT_LABEL( _test_eof );
out << " _test_eof: {}\n";
if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { if ( redFsm->anyEofActivity() ) {
out << out <<
" if ( " << P() << " == " << vEOF() << " )\n" " if ( " << P() << " == " << vEOF() << " ) {\n";
" {\n";
out << out <<
" switch ( " << vCS() << " ) {\n"; " switch ( " << vCS() << " ) {\n";
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
out << " case " << st->id << ": {\n"; out << "case " << st->id << ": {\n";
NFA_PUSH( st ); NFA_PUSH( st );
out << "\n\t" << CEND() << "}\n"; FROM_STATE_ACTION_EMIT( st );
out << "break;\n}\n";
} }
out << out <<
" }\n"; " }\n";
out << out <<
" switch ( " << vCS() << " ) {\n"; " switch ( " << vCS() << " ) {\n";
bool okeydokey = false; bool okeydokey = false;
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
if ( st->outCondSpace != 0 ) { if ( st->outCondSpace != 0 ) {
out << " case " << st->id << ": {\n"; out << "case " << st->id << ": {\n";
out << "int ck = 0;\n"; out << ck << " = 0;\n";
for ( GenCondSet::Iter csi = st->outCondSpace->co ndSet; csi.lte(); csi++ ) { for ( GenCondSet::Iter csi = st->outCondSpace->co ndSet; csi.lte(); csi++ ) {
out << "if ( "; out << "if ( ";
CONDITION( out, *csi ); CONDITION( out, *csi );
Size condValOffset = (1 << csi.pos()); Size condValOffset = (1 << csi.pos());
out << " ) ck += " << condValOffset << "; \n"; out << " )\n" << ck << " += " << condValO ffset << ";\n";
} }
out << " switch ( ck ) {\n"; out << "switch ( " << ck << " ) {\n";
for ( CondKeySet::Iter k = st->outCondKeys; k.lte (); k++ ) { for ( CondKeySet::Iter k = st->outCondKeys; k.lte (); k++ ) {
out << "case " << *k << ": goto _okeydoke y;\n"; out << "case " << *k << ": goto _okeydoke y;\n";
okeydokey = true; okeydokey = true;
} }
out << "}\n"; out << "}\n";
out << vCS() << " = " << ERROR_STATE() << ";\n"; out << vCS() << " = " << ERROR_STATE() << ";\n";
out << "goto _out;\n"; out << "goto " << _pop << ";\n";
out << "}\n"; out << "}\n";
} }
} }
out << out <<
" }\n"; " }\n";
if ( okeydokey ) { if ( okeydokey ) {
out << out <<
"_okeydokey: {}\n"; "_okeydokey: {}\n";
} }
out << out <<
" switch ( " << vCS() << " ) {\n"; " switch ( " << vCS() << " ) {\n";
FINISH_CASES() << FINISH_CASES() <<
" }\n" " }\n";
out <<
" }\n" " }\n"
"\n"; "\n";
} }
if ( outLabelUsed ) out <<
out << " _out: {}\n"; "if ( " << vCS() << " >= " << FIRST_FINAL_STATE() << " )\n"
" goto " << _out << "; ";
out << EMIT_LABEL( _pop );
if ( redFsm->anyNfaStates() ) {
out <<
"if ( nfa_len == 0 )\n"
" goto " << _out << ";\n"
"\n";
out <<
"nfa_count += 1;\n"
"nfa_len -= 1;\n" <<
P() << " = nfa_bp[nfa_len].p;\n";
if ( redFsm->bAnyNfaPops ) {
NFA_FROM_STATE_ACTION_EXEC();
NFA_POP_TEST_EXEC();
out <<
"if ( " << pop_test << " )\n"
" " << vCS() << " = nfa_bp[nfa_len].state;\
n"
"else\n"
" " << vCS() << " = " << ERROR_STATE() << "
;\n";
}
else {
out <<
vCS() << " = nfa_bp[nfa_len].state;\n";
}
NFA_POST_POP();
out << "goto " << _resume << ";\n";
}
NFA_POP(); out << EMIT_LABEL( _out );
out << out <<
" }\n"; "}\n";
} }
 End of changes. 76 change blocks. 
150 lines changed or deleted 228 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)