binvarloop.cc (ragel-7.0.0.9) | : | binvarloop.cc (ragel-7.0.0.10) | ||
---|---|---|---|---|
/* | /* | |||
* Copyright 2001-2014 Adrian Thurston <thurston@complang.org> | * Copyright 2004-2014 Adrian Thurston <thurston@colm.net> | |||
*/ | ||||
/* This file is part of Ragel. | ||||
* | * | |||
* Ragel is free software; you can redistribute it and/or modify | * Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* it under the terms of the GNU General Public License as published by | * of this software and associated documentation files (the "Software"), to | |||
* the Free Software Foundation; either version 2 of the License, or | * deal in the Software without restriction, including without limitation the | |||
* (at your option) any later version. | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |||
* sell copies of the Software, and to permit persons to whom the Software is | ||||
* furnished to do so, subject to the following conditions: | ||||
* | * | |||
* Ragel is distributed in the hope that it will be useful, | * The above copyright notice and this permission notice shall be included in al | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | l | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * copies or substantial portions of the Software. | |||
* GNU General Public License for more details. | ||||
* | * | |||
* You should have received a copy of the GNU General Public License | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* along with Ragel; if not, write to the Free Software | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
* SOFTWARE. | ||||
*/ | */ | |||
#include "ragel.h" | #include "ragel.h" | |||
#include "binvarloop.h" | #include "flatloop.h" | |||
#include "redfsm.h" | #include "redfsm.h" | |||
#include "gendata.h" | #include "gendata.h" | |||
#include "parsedata.h" | #include "parsedata.h" | |||
#include "inputdata.h" | #include "inputdata.h" | |||
BinaryLoopVar::BinaryLoopVar( const CodeGenArgs &args ) | void FlatLoopGoto::tableDataPass() | |||
: | { | |||
BinaryVar( args ) | if ( redFsm->anyActions() ) | |||
{} | taActions(); | |||
taKeys(); | ||||
/* Determine if we should use indicies or not. */ | taCharClass(); | |||
void BinaryLoopVar::calcIndexSize() | taFlatIndexOffset(); | |||
{ | ||||
// long long sizeWithInds = | ||||
// indicies.size() + | ||||
// transCondSpacesWi.size() + | ||||
// transOffsetsWi.size() + | ||||
// transLengthsWi.size(); | ||||
// long long sizeWithoutInds = | ||||
// transCondSpaces.size() + | ||||
// transOffsets.size() + | ||||
// transLengths.size(); | ||||
///* If using indicies reduces the size, use them. */ | ||||
//useIndicies = sizeWithInds < sizeWithoutInds; | ||||
useIndicies = false; | ||||
} | ||||
void BinaryLoopVar::tableDataPass() | ||||
{ | ||||
taActions(); | ||||
taKeyOffsets(); | ||||
taSingleLens(); | ||||
taRangeLens(); | ||||
taIndexOffsets(); | ||||
taIndicies(); | ||||
taTransCondSpacesWi(); | ||||
taTransOffsetsWi(); | ||||
taTransLengthsWi(); | ||||
taIndicies(); | ||||
taIndexDefaults(); | ||||
taTransCondSpaces(); | taTransCondSpaces(); | |||
taTransOffsets(); | if ( red->condSpaceList.length() > 0 ) | |||
taTransLengths(); | taTransOffsets(); | |||
taCondTargs(); | taCondTargs(); | |||
taCondActions(); | taCondActions(); | |||
taToStateActions(); | taToStateActions(); | |||
taFromStateActions(); | taFromStateActions(); | |||
taEofActions(); | taEofActions(); | |||
taEofTrans(); | ||||
taEofTransDirect(); | ||||
taEofTransIndexed(); | ||||
taKeys(); | ||||
taCondKeys(); | ||||
taNfaTargs(); | taNfaTargs(); | |||
taNfaOffsets(); | taNfaOffsets(); | |||
taNfaPushActions(); | taNfaPushActions(); | |||
taNfaPopTrans(); | taNfaPopTrans(); | |||
} | } | |||
void BinaryLoopVar::genAnalysis() | void FlatLoopGoto::genAnalysis() | |||
{ | { | |||
redFsm->sortByStateId(); | redFsm->sortByStateId(); | |||
/* Choose default transitions and the single transition. */ | /* Choose default transitions and the single transition. */ | |||
redFsm->chooseDefaultSpan(); | redFsm->chooseDefaultSpan(); | |||
/* Choose the singles. */ | /* Do flat expand. */ | |||
redFsm->moveSelectTransToSingle(); | redFsm->makeFlatClass(); | |||
/* If any errors have occured in the input file then don't write anything . */ | /* If any errors have occured in the input file then don't write anything . */ | |||
if ( red->id->errorCount > 0 ) | if ( red->id->errorCount > 0 ) | |||
return; | return; | |||
/* Anlayze Machine will find the final action reference counts, among oth er | /* Anlayze Machine will find the final action reference counts, among oth er | |||
* things. We will use these in reporting the usage of fsm directives in | * things. We will use these in reporting the usage of fsm directives in | |||
* action code. */ | * action code. */ | |||
red->analyzeMachine(); | red->analyzeMachine(); | |||
setKeyType(); | setKeyType(); | |||
/* Run the analysis pass over the table data. */ | /* Run the analysis pass over the table data. */ | |||
setTableState( TableArray::AnalyzePass ); | setTableState( TableArray::AnalyzePass ); | |||
tableDataPass(); | tableDataPass(); | |||
/* Determine if we should use indicies. */ | ||||
calcIndexSize(); | ||||
/* Switch the tables over to the code gen mode. */ | /* Switch the tables over to the code gen mode. */ | |||
setTableState( TableArray::GeneratePass ); | setTableState( TableArray::GeneratePass ); | |||
} | } | |||
void BinaryLoopVar::COND_ACTION( RedCondPair *cond ) | std::ostream &FlatLoopGoto::TO_STATE_ACTION_SWITCH() | |||
{ | ||||
int act = 0; | ||||
if ( cond->action != 0 ) | ||||
act = cond->action->location+1; | ||||
condActions.value( act ); | ||||
} | ||||
void BinaryLoopVar::TO_STATE_ACTION( RedStateAp *state ) | ||||
{ | ||||
int act = 0; | ||||
if ( state->toStateAction != 0 ) | ||||
act = state->toStateAction->location+1; | ||||
toStateActions.value( act ); | ||||
} | ||||
void BinaryLoopVar::FROM_STATE_ACTION( RedStateAp *state ) | ||||
{ | ||||
int act = 0; | ||||
if ( state->fromStateAction != 0 ) | ||||
act = state->fromStateAction->location+1; | ||||
fromStateActions.value( act ); | ||||
} | ||||
void BinaryLoopVar::EOF_ACTION( RedStateAp *state ) | ||||
{ | ||||
int act = 0; | ||||
if ( state->eofAction != 0 ) | ||||
act = state->eofAction->location+1; | ||||
eofActions.value( act ); | ||||
} | ||||
std::ostream &BinaryLoopVar::TO_STATE_ACTION_SWITCH() | ||||
{ | { | |||
/* Walk the list of functions, printing the cases. */ | /* Walk the list of functions, printing the cases. */ | |||
for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | |||
/* Write out referenced actions. */ | /* Write out referenced actions. */ | |||
if ( act->numToStateRefs > 0 ) { | if ( act->numToStateRefs > 0 ) { | |||
/* Write the case label, the action and the case break. * | /* Write the case label, the action and the case break */ | |||
/ | out << "\t " << CASE( STR( act->actionId ) ) << " {\n"; | |||
out << "\t" << CASE( STR( act->actionId ) ) << " {\n"; | ||||
ACTION( out, act, IlOpts( 0, false, false ) ); | ACTION( out, act, IlOpts( 0, false, false ) ); | |||
out << "\n\t" << CEND() << "}\n"; | out << "\n\t" << CEND() << "}\n"; | |||
} | } | |||
} | } | |||
return out; | return out; | |||
} | } | |||
std::ostream &BinaryLoopVar::FROM_STATE_ACTION_SWITCH() | std::ostream &FlatLoopGoto::FROM_STATE_ACTION_SWITCH() | |||
{ | { | |||
/* Walk the list of functions, printing the cases. */ | /* Walk the list of functions, printing the cases. */ | |||
for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | |||
/* Write out referenced actions. */ | /* Write out referenced actions. */ | |||
if ( act->numFromStateRefs > 0 ) { | if ( act->numFromStateRefs > 0 ) { | |||
/* Write the case label, the action and the case break. * | /* Write the case label, the action and the case break */ | |||
/ | out << "\t " << CASE( STR( act->actionId ) ) << " {\n"; | |||
out << "\t" << CASE( STR( act->actionId ) ) << " {\n"; | ||||
ACTION( out, act, IlOpts( 0, false, false ) ); | ACTION( out, act, IlOpts( 0, false, false ) ); | |||
out << "\n\t" << CEND() << "}\n"; | out << "\n\t" << CEND() << "}\n"; | |||
} | } | |||
} | } | |||
return out; | return out; | |||
} | } | |||
std::ostream &BinaryLoopVar::EOF_ACTION_SWITCH() | std::ostream &FlatLoopGoto::EOF_ACTION_SWITCH() | |||
{ | { | |||
/* Walk the list of functions, printing the cases. */ | /* Walk the list of functions, printing the cases. */ | |||
for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | |||
/* Write out referenced actions. */ | /* Write out referenced actions. */ | |||
if ( act->numEofRefs > 0 ) { | if ( act->numEofRefs > 0 ) { | |||
/* Write the case label, the action and the case break. * | /* Write the case label, the action and the case break */ | |||
/ | out << "\t " << CASE( STR( act->actionId ) ) << " {\n"; | |||
out << "\t" << CASE( STR( act->actionId ) ) << " {\n"; | ||||
ACTION( out, act, IlOpts( 0, true, false ) ); | ACTION( out, act, IlOpts( 0, true, false ) ); | |||
out << "\n\t" << CEND() << "}\n"; | out << "\n\t" << CEND() << "}\n"; | |||
} | } | |||
} | } | |||
return out; | return out; | |||
} | } | |||
std::ostream &BinaryLoopVar::ACTION_SWITCH() | std::ostream &FlatLoopGoto::ACTION_SWITCH() | |||
{ | { | |||
/* Walk the list of functions, printing the cases. */ | /* Walk the list of functions, printing the cases. */ | |||
for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | for ( GenActionList::Iter act = red->actionList; act.lte(); act++ ) { | |||
/* Write out referenced actions. */ | /* Write out referenced actions. */ | |||
if ( act->numTransRefs > 0 ) { | if ( act->numTransRefs > 0 ) { | |||
/* Write the case label, the action and the case break. * | /* Write the case label, the action and the case break */ | |||
/ | out << "\t " << CASE( STR( act->actionId ) ) << " {\n"; | |||
out << "\t" << CASE( STR( act->actionId ) ) << " {\n"; | ||||
ACTION( out, act, IlOpts( 0, false, false ) ); | ACTION( out, act, IlOpts( 0, false, false ) ); | |||
out << "\n\t" << CEND() << "}\n"; | out << "\n\t" << CEND() << "}\n"; | |||
} | } | |||
} | } | |||
return out; | return out; | |||
} | } | |||
void BinaryLoopVar::writeData() | void FlatLoopGoto::writeData() | |||
{ | { | |||
/* If there are any transtion functions then output the array. If there | /* If there are any transtion functions then output the array. If there | |||
* are none, don't bother emitting an empty array that won't be used. */ | * are none, don't bother emitting an empty array that won't be used. */ | |||
if ( redFsm->anyActions() ) | if ( redFsm->anyActions() ) | |||
taActions(); | taActions(); | |||
taKeyOffsets(); | ||||
taKeys(); | taKeys(); | |||
taSingleLens(); | taCharClass(); | |||
taRangeLens(); | taFlatIndexOffset(); | |||
taIndexOffsets(); | ||||
if ( useIndicies ) { | ||||
taIndicies(); | ||||
taTransCondSpacesWi(); | ||||
taTransOffsetsWi(); | ||||
taTransLengthsWi(); | ||||
} | ||||
else { | ||||
taTransCondSpaces(); | ||||
taTransOffsets(); | ||||
taTransLengths(); | ||||
} | ||||
taCondKeys(); | ||||
taIndicies(); | ||||
taIndexDefaults(); | ||||
taTransCondSpaces(); | ||||
if ( red->condSpaceList.length() > 0 ) | ||||
taTransOffsets(); | ||||
taCondTargs(); | taCondTargs(); | |||
taCondActions(); | taCondActions(); | |||
if ( redFsm->anyToStateActions() ) | if ( redFsm->anyToStateActions() ) | |||
taToStateActions(); | taToStateActions(); | |||
if ( redFsm->anyFromStateActions() ) | if ( redFsm->anyFromStateActions() ) | |||
taFromStateActions(); | taFromStateActions(); | |||
if ( redFsm->anyEofActions() ) | if ( redFsm->anyEofActions() ) | |||
taEofActions(); | taEofActions(); | |||
if ( redFsm->anyEofTrans() ) { | if ( redFsm->anyEofTrans() ) | |||
taEofTransIndexed(); | taEofTrans(); | |||
taEofTransDirect(); | ||||
} | ||||
taNfaTargs(); | taNfaTargs(); | |||
taNfaOffsets(); | taNfaOffsets(); | |||
taNfaPushActions(); | taNfaPushActions(); | |||
taNfaPopTrans(); | taNfaPopTrans(); | |||
STATE_IDS(); | STATE_IDS(); | |||
} | } | |||
void BinaryLoopVar::NFA_PUSH_ACTION( RedNfaTarg *targ ) | void FlatLoopGoto::NFA_FROM_STATE_ACTION_EXEC() | |||
{ | ||||
int act = 0; | ||||
if ( targ->push != 0 ) | ||||
act = targ->push->actListId+1; | ||||
nfaPushActions.value( act ); | ||||
} | ||||
void BinaryLoopVar::NFA_POP_TEST( RedNfaTarg *targ ) | ||||
{ | ||||
int act = 0; | ||||
if ( targ->popTest != 0 ) | ||||
act = targ->popTest->actListId+1; | ||||
nfaPopTrans.value( act ); | ||||
} | ||||
void BinaryLoopVar::NFA_FROM_STATE_ACTION_EXEC() | ||||
{ | { | |||
if ( redFsm->anyFromStateActions() ) { | if ( redFsm->anyFromStateActions() ) { | |||
out << | out << | |||
" _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( fromStateActions ) + "[nfa_bp[nfa_len].state]" ) << ";\n" | " _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( fromStateActions ) + "[nfa_bp[nfa_len].state]" ) << ";\n" | |||
" _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a ctions ), "_acts" ) << ";\n" | " _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a ctions ), "_acts" ) << ";\n" | |||
" _acts += 1;\n" | " _acts += 1;\n" | |||
" while ( _nacts > 0 ) {\n" | " while ( _nacts > 0 ) {\n" | |||
" switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | " switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | |||
FROM_STATE_ACTION_SWITCH() << | FROM_STATE_ACTION_SWITCH() << | |||
" }\n" | " }\n" | |||
" _nacts -= 1;\n" | " _nacts -= 1;\n" | |||
" _acts += 1;\n" | " _acts += 1;\n" | |||
" }\n" | " }\n" | |||
"\n"; | "\n"; | |||
} | } | |||
} | } | |||
void BinaryLoopVar::writeExec() | void FlatLoopGoto::writeExec() | |||
{ | { | |||
testEofUsed = false; | testEofUsed = false; | |||
outLabelUsed = false; | outLabelUsed = false; | |||
matchCondLabelUsed = false; | ||||
if ( redFsm->anyNfaStates() ) { | ||||
out << | ||||
"{\n" | ||||
" " << UINT() << " _nfa_cont = 1;\n" | ||||
" " << UINT() << " _nfa_repeat = 1;\n" | ||||
" while ( _nfa_cont != 0 )\n"; | ||||
} | ||||
out << | out << | |||
" {\n" | " {\n"; | |||
" int _klen;\n"; | ||||
if ( redFsm->anyRegCurStateRef() ) | if ( redFsm->anyRegCurStateRef() ) | |||
out << " int _ps;\n"; | out << " int _ps;\n"; | |||
out << | out << | |||
" " << UINT() << " _trans = 0;\n" << | " int _trans = 0;\n"; | |||
" " << UINT() << " _cond = 0;\n" | ||||
" " << UINT() << " _have = 0;\n" | ||||
" " << UINT() << " _cont = 1;\n"; | ||||
if ( redFsm->anyToStateActions() || redFsm->anyRegActions() | if ( red->condSpaceList.length() > 0 ) { | |||
|| redFsm->anyFromStateActions() ) | out << | |||
" " << UINT() << " _cond = 0;\n"; | ||||
} | ||||
if ( redFsm->anyToStateActions() || | ||||
redFsm->anyRegActions() || redFsm->anyFromStateActions() | ||||
) | ||||
{ | { | |||
out << | out << | |||
" " << INDEX( ARR_TYPE( actions ), "_acts" ) << ";\ n" | " " << INDEX( ARR_TYPE( actions ), "_acts" ) << ";\ n" | |||
" " << UINT() << " _nacts;\n"; | " " << UINT() << " _nacts;\n"; | |||
} | } | |||
out << | if ( redFsm->classMap != 0 ) { | |||
" " << INDEX( ALPH_TYPE(), "_keys" ) << ";\n" | ||||
" " << INDEX( ARR_TYPE( condKeys ), "_ckeys" ) << ";\n" | ||||
" int _cpc;\n" | ||||
" while ( _cont == 1 ) {\n" | ||||
"\n"; | ||||
if ( redFsm->errState != 0 ) { | ||||
outLabelUsed = true; | ||||
out << | out << | |||
" if ( " << vCS() << " == " << redFsm->errState->id | " " << INDEX( ALPH_TYPE(), "_keys" ) << ";\n" | |||
<< " )\n" | " " << INDEX( ARR_TYPE( indicies ), "_inds" ) << "; | |||
" _cont = 0;\n"; | \n"; | |||
} | } | |||
out << | if ( red->condSpaceList.length() > 0 ) | |||
// "label _resume {\n" | out << " int _cpc;\n"; | |||
"_have = 0;\n"; | ||||
if ( !noEnd ) { | ||||
out << | ||||
" if ( " << P() << " == " << PE() << " ) {\n"; | ||||
if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { | if ( redFsm->anyRegNbreak() ) | |||
out << | out << " int _nbreak;\n"; | |||
" if ( " << P() << " == " << vEOF() << " )\ | ||||
n" | ||||
" {\n"; | ||||
if ( redFsm->anyEofTrans() ) { | out << | |||
TableArray &eofTrans = useIndicies ? eofTransInde | " " << ENTRY() << " {\n"; | |||
xed : eofTransDirect; | ||||
out << | ||||
" if ( " << ARR_REF( eofTrans ) << | ||||
"[" << vCS() << "] > 0 ) {\n" | ||||
" _trans = " << CAST( UINT( | ||||
) ) << ARR_REF( eofTrans ) << "[" << vCS() << "] - 1;\n" | ||||
" _cond = " << CAST( UINT() | ||||
) << ARR_REF( transOffsets ) << "[_trans];\n" | ||||
" _have = 1;\n" | ||||
" }\n"; | ||||
matchCondLabelUsed = true; | ||||
} | ||||
out << "if ( _have == 0 ) {\n"; | ||||
if ( redFsm->anyEofActions() ) { | ||||
out << | ||||
" " << INDEX( ARR_TYPE( actions ), | ||||
"__acts" ) << ";\n" | ||||
" " << UINT() << " __nacts;\n" | ||||
" __acts = " << OFFSET( ARR_REF( ac | ||||
tions ), | ||||
ARR_REF( eofActions ) + " | ||||
[" + vCS() + "]" ) << ";\n" | ||||
" __nacts = " << CAST( UINT() ) << | ||||
DEREF( ARR_REF( actions ), "__acts" ) << ";\n" | ||||
" __acts += 1;\n" | ||||
" while ( __nacts > 0 ) {\n" | ||||
" switch ( " << DEREF( ARR_ | ||||
REF( actions ), "__acts" ) << " ) {\n"; | ||||
EOF_ACTION_SWITCH() << | ||||
" }\n" | ||||
" __nacts -= 1;\n" | ||||
" __acts += 1;\n" | ||||
" }\n"; | ||||
} | ||||
out << "}\n"; | out << "\n"; | |||
out << | ||||
" }\n" | ||||
"\n"; | ||||
} | ||||
if ( !noEnd ) { | ||||
testEofUsed = true; | ||||
out << | out << | |||
" if ( _have == 0 )\n" | " if ( " << P() << " == " << PE() << " )\n" | |||
" _cont = 0;\n" | " goto _test_eof;\n"; | |||
" }\n"; | } | |||
if ( redFsm->errState != 0 ) { | ||||
outLabelUsed = true; | ||||
out << | ||||
" if ( " << vCS() << " == " << redFsm->errState->id | ||||
<< " )\n" | ||||
" goto _out;\n"; | ||||
} | } | |||
out << | out << LABEL( "_resume" ) << " {\n"; | |||
" if ( _cont == 1 ) {\n" | ||||
" if ( _have == 0 ) {\n"; | ||||
if ( redFsm->anyFromStateActions() ) { | if ( redFsm->anyFromStateActions() ) { | |||
out << | out << | |||
" _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( | " _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( | |||
fromStateActions ) + | fromStateActions ) + "[" + vCS() + "]" ) << ";\n" | |||
"[" + vCS() + "]" ) << ";\n" | ||||
" _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a ctions ), "_acts" ) << ";\n" | " _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a ctions ), "_acts" ) << ";\n" | |||
" _acts += 1;\n" | " _acts += 1;\n" | |||
" while ( _nacts > 0 ) {\n" | " while ( _nacts > 0 ) {\n" | |||
" switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | " switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | |||
FROM_STATE_ACTION_SWITCH() << | FROM_STATE_ACTION_SWITCH() << | |||
" }\n" | " }\n" | |||
" _nacts -= 1;\n" | " _nacts -= 1;\n" | |||
" _acts += 1;\n" | " _acts += 1;\n" | |||
" }\n" | " }\n" | |||
"\n"; | "\n"; | |||
} | } | |||
NFA_PUSH(); | NFA_PUSH(); | |||
LOCATE_TRANS(); | LOCATE_TRANS(); | |||
if ( useIndicies ) | string cond = "_cond"; | |||
out << " _trans = " << ARR_REF( indicies ) << "[_trans];\n | if ( red->condSpaceList.length() == 0 ) | |||
"; | cond = "_trans"; | |||
LOCATE_COND(); | out << "}\n" << LABEL( "_match_cond" ) << " {\n"; | |||
out << "}\n"; | ||||
out << "if ( _cont == 1 ) {\n"; | ||||
if ( redFsm->anyRegCurStateRef() ) | if ( redFsm->anyRegCurStateRef() ) | |||
out << " _ps = " << vCS() << ";\n"; | out << " _ps = " << vCS() << ";\n"; | |||
out << | out << | |||
" " << vCS() << " = " << CAST("int") << ARR_REF( condTargs ) << "[_cond];\n" | " " << vCS() << " = " << CAST("int") << ARR_REF( condTargs ) << "[" << cond << "];\n" | |||
"\n"; | "\n"; | |||
if ( redFsm->anyRegActions() ) { | if ( redFsm->anyRegActions() ) { | |||
out << | out << | |||
" if ( " << ARR_REF( condActions ) << "[_cond] != 0 | " if ( " << ARR_REF( condActions ) << "[" << cond < | |||
) {\n" | < "] == 0 )\n" | |||
" _acts = " << OFFSET( ARR_REF( actions ), | " goto _again;\n" | |||
ARR_REF( condActions ) + "[_cond]" ) << ";\n" | "\n"; | |||
" _nacts = " << CAST( UINT() ) << DEREF( AR | ||||
R_REF( actions ), "_acts" ) << ";\n" | if ( redFsm->anyRegNbreak() ) | |||
" _acts += 1;\n" | out << " _nbreak = 0;\n"; | |||
" while ( _nacts > 0 )\n {\n" | ||||
" switch ( " << DEREF( ARR_REF( act | out << | |||
ions ), "_acts" ) << " )\n" | " _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( | |||
" {\n"; | condActions ) + "[" + cond + "]" ) << ";\n" | |||
" _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a | ||||
ctions ), "_acts" ) << ";\n" | ||||
" _acts += 1;\n" | ||||
" while ( _nacts > 0 ) {\n" | ||||
" switch ( " << DEREF( ARR_REF( actions ), | ||||
"_acts" ) << " )\n" | ||||
" {\n"; | ||||
ACTION_SWITCH() << | ACTION_SWITCH() << | |||
" }\n" | ||||
" _nacts -= 1;\n" | ||||
" _acts += 1;\n" | ||||
" }\n" | " }\n" | |||
" _nacts -= 1;\n" | ||||
" _acts += 1;\n" | ||||
" }\n" | " }\n" | |||
"\n"; | "\n"; | |||
if ( redFsm->anyRegNbreak() ) { | ||||
out << | ||||
" if ( _nbreak == 1 )\n" | ||||
" goto _out;\n"; | ||||
outLabelUsed = true; | ||||
} | ||||
out << | ||||
"\n"; | ||||
} | } | |||
// if ( /*redFsm->anyRegActions() || */ redFsm->anyActionGotos() || | if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || | |||
// redFsm->anyActionCalls() || redFsm->anyActionRets() ) | redFsm->anyActionCalls() || redFsm->anyActionRets() ) | |||
// { | out << "}\n" << LABEL( "_again" ) << " {\n"; | |||
// out << "}\n"; | ||||
// out << "label _again {\n"; | ||||
// } | ||||
if ( redFsm->anyToStateActions() ) { | if ( redFsm->anyToStateActions() ) { | |||
out << | out << | |||
" _acts = " << OFFSET( ARR_REF( actions ), ARR_REF | " _acts = " << OFFSET( ARR_REF( actions ), ARR_REF( | |||
( toStateActions ) + | toStateActions ) + "[" + vCS() + "]" ) << ";\n" | |||
"[" + vCS() + "]" ) << ";\n" | " _nacts = " << CAST( UINT() ) << DEREF( ARR_REF ( | |||
" _nacts = " << CAST( UINT() ) << DEREF( ARR_REF( a | actions ), "_acts" ) << "; _acts += 1;\n" | |||
ctions ), "_acts" ) << ";\n" | ||||
" _acts += 1;\n" | ||||
" while ( _nacts > 0 ) {\n" | " while ( _nacts > 0 ) {\n" | |||
" switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | " switch ( " << DEREF( ARR_REF( actions ), "_acts" ) << " ) {\n"; | |||
TO_STATE_ACTION_SWITCH() << | TO_STATE_ACTION_SWITCH() << | |||
" }\n" | " }\n" | |||
" _nacts -= 1;\n" | " _nacts -= 1;\n" | |||
" _acts += 1;\n" | " _acts += 1;\n" | |||
" }\n" | " }\n" | |||
"\n"; | "\n"; | |||
} | } | |||
if ( redFsm->errState != 0 ) { | if ( redFsm->errState != 0 ) { | |||
outLabelUsed = true; | outLabelUsed = true; | |||
out << | out << | |||
" if ( " << vCS() << " == " << redFsm->errState->id << " )\n" | " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" | |||
" _cont = 0;\n"; | " goto _out;\n"; | |||
} | } | |||
out << | if ( !noEnd ) { | |||
" if ( _cont == 1 )\n" | out << | |||
" " << P() << " += 1;\n" | " " << P() << " += 1;\n" | |||
"\n" | " if ( " << P() << " != " << PE() << " )\n" | |||
"}\n"; | " goto _resume;\n"; | |||
} | ||||
else { | ||||
out << | ||||
" " << P() << " += 1;\n" | ||||
" goto _resume;\n"; | ||||
} | ||||
out << | if ( testEofUsed ) | |||
"}\n"; | out << "}\n" << LABEL( "_test_eof" ) << " { {}\n"; | |||
if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { | ||||
out << | ||||
" if ( " << P() << " == " << vEOF() << " )\n" | ||||
" {\n"; | ||||
if ( redFsm->anyEofTrans() ) { | ||||
out << | ||||
" if ( " << ARR_REF( eofTrans ) << "[" << v | ||||
CS() << "] > 0 ) {\n" | ||||
" _trans = " << CAST("int") << ARR_ | ||||
REF( eofTrans ) << "[" << vCS() << "] - 1;\n"; | ||||
if ( red->condSpaceList.length() > 0 ) { | ||||
out << | ||||
" _cond = " << CAST( UINT() | ||||
) << ARR_REF( transOffsets ) << "[_trans];\n"; | ||||
} | ||||
out << | ||||
" goto _match_cond;\n" | ||||
" }\n"; | ||||
} | ||||
if ( redFsm->anyEofActions() ) { | ||||
out << | ||||
" " << INDEX( ARR_TYPE( actions ), "__acts" | ||||
) << ";\n" | ||||
" " << UINT() << " __nacts;\n" | ||||
" __acts = " << OFFSET( ARR_REF( actions ), | ||||
ARR_REF( eofActions ) + "[" + vCS() + "]" ) << ";\n" | ||||
" __nacts = " << CAST( UINT() ) << DEREF( A | ||||
RR_REF( actions ), "__acts" ) << "; __acts += 1;\n" | ||||
" while ( __nacts > 0 ) {\n" | ||||
" switch ( " << DEREF( ARR_REF( act | ||||
ions ), "__acts" ) << " ) {\n"; | ||||
EOF_ACTION_SWITCH() << | ||||
" }\n" | ||||
" __nacts -= 1;\n" | ||||
" __acts += 1;\n" | ||||
" }\n"; | ||||
} | ||||
out << "}\n"; | out << | |||
" }\n" | ||||
"\n"; | ||||
} | ||||
if ( outLabelUsed ) | ||||
out << "}\n" << LABEL( "_out" ) << " { {}\n"; | ||||
/* The entry loop. */ | ||||
out << "}\n}\n"; | ||||
NFA_POP(); | NFA_POP(); | |||
out << "}\n"; | out << " }\n"; | |||
} | ||||
void FlatLoopGoto::TO_STATE_ACTION( RedStateAp *state ) | ||||
{ | ||||
int act = 0; | ||||
if ( state->toStateAction != 0 ) | ||||
act = state->toStateAction->location+1; | ||||
toStateActions.value( act ); | ||||
} | ||||
void FlatLoopGoto::FROM_STATE_ACTION( RedStateAp *state ) | ||||
{ | ||||
int act = 0; | ||||
if ( state->fromStateAction != 0 ) | ||||
act = state->fromStateAction->location+1; | ||||
fromStateActions.value( act ); | ||||
} | ||||
if ( redFsm->anyNfaStates() ) | void FlatLoopGoto::EOF_ACTION( RedStateAp *state ) | |||
out << "}\n"; | { | |||
int act = 0; | ||||
if ( state->eofAction != 0 ) | ||||
act = state->eofAction->location+1; | ||||
eofActions.value( act ); | ||||
} | ||||
void FlatLoopGoto::COND_ACTION( RedCondPair *cond ) | ||||
{ | ||||
/* If there are actions, emit them. Otherwise emit zero. */ | ||||
int act = 0; | ||||
if ( cond->action != 0 ) | ||||
act = cond->action->location+1; | ||||
condActions.value( act ); | ||||
} | ||||
void FlatLoopGoto::NFA_PUSH_ACTION( RedNfaTarg *targ ) | ||||
{ | ||||
int act = 0; | ||||
if ( targ->push != 0 ) | ||||
act = targ->push->actListId+1; | ||||
nfaPushActions.value( act ); | ||||
} | ||||
void FlatLoopGoto::NFA_POP_TEST( RedNfaTarg *targ ) | ||||
{ | ||||
int act = 0; | ||||
if ( targ->popTest != 0 ) | ||||
act = targ->popTest->actListId+1; | ||||
nfaPopTrans.value( act ); | ||||
} | } | |||
End of changes. 57 change blocks. | ||||
298 lines changed or deleted | 249 lines changed or added |