From f0d3bd96b1036498f04714502b3dc924ee20fbbd Mon Sep 17 00:00:00 2001 From: thurston Date: Sun, 20 Apr 2008 23:16:19 +0000 Subject: [PATCH] Bug fix for eofTrans. When not using indicies we can't use a transitions's id to identify the transition to take. Instead add the transition to the end of the list and store it's position in a new var called pos. The pos var is then used as the index. git-svn-id: http://svn.complang.org/ragel/trunk@437 052ea7fc-9027-0410-9066-f65837a77df0 --- redfsm/redfsm.h | 3 ++- rlgen-cd/flatcodegen.cpp | 11 ++++++++--- rlgen-cd/fsmcodegen.h | 4 ++-- rlgen-cd/tabcodegen.cpp | 34 +++++++++++++++++++++++++++++++--- rlgen-csharp/flatcodegen.cpp | 11 ++++++++--- rlgen-csharp/fsmcodegen.h | 4 ++-- rlgen-csharp/tabcodegen.cpp | 31 ++++++++++++++++++++++++++++--- rlgen-java/javacodegen.cpp | 30 +++++++++++++++++++++++++++--- rlgen-java/javacodegen.h | 4 ++-- rlgen-ruby/ruby-codegen.h | 4 ++-- rlgen-ruby/ruby-flatcodegen.cpp | 11 ++++++++--- rlgen-ruby/ruby-tabcodegen.cpp | 26 +++++++++++++++++++++++--- test/scan2.rl | 34 ++++++++++++++++++++++++++++++++++ test/scan3.rl | 32 ++++++++++++++++++++++++++++++++ 14 files changed, 209 insertions(+), 30 deletions(-) create mode 100644 test/scan2.rl create mode 100644 test/scan3.rl diff --git a/redfsm/redfsm.h b/redfsm/redfsm.h index 8e53b9e..47906f7 100644 --- a/redfsm/redfsm.h +++ b/redfsm/redfsm.h @@ -217,11 +217,12 @@ struct RedTransAp public AvlTreeEl { RedTransAp( RedStateAp *targ, RedAction *action, int id ) - : targ(targ), action(action), id(id), labelNeeded(true) { } + : targ(targ), action(action), id(id), pos(-1), labelNeeded(true) { } RedStateAp *targ; RedAction *action; int id; + int pos; bool partitionBoundary; bool labelNeeded; }; diff --git a/rlgen-cd/flatcodegen.cpp b/rlgen-cd/flatcodegen.cpp index 783cde3..7195bc8 100644 --- a/rlgen-cd/flatcodegen.cpp +++ b/rlgen-cd/flatcodegen.cpp @@ -236,8 +236,10 @@ std::ostream &FlatCodeGen::EOF_TRANS() /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } out << trans; if ( !st.last() ) { @@ -394,8 +396,11 @@ std::ostream &FlatCodeGen::TRANS_TARGS() out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; diff --git a/rlgen-cd/fsmcodegen.h b/rlgen-cd/fsmcodegen.h index 7390448..9088370 100644 --- a/rlgen-cd/fsmcodegen.h +++ b/rlgen-cd/fsmcodegen.h @@ -116,8 +116,8 @@ protected: string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } - string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; } - string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; } + string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } + string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } diff --git a/rlgen-cd/tabcodegen.cpp b/rlgen-cd/tabcodegen.cpp index 94d5c08..977ec63 100644 --- a/rlgen-cd/tabcodegen.cpp +++ b/rlgen-cd/tabcodegen.cpp @@ -334,8 +334,10 @@ std::ostream &TabCodeGen::EOF_TRANS() for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } out << trans; if ( !st.last() ) { @@ -489,6 +491,18 @@ std::ostream &TabCodeGen::TRANS_TARGS() } } + /* 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"; @@ -526,6 +540,17 @@ std::ostream &TabCodeGen::TRANS_ACTIONS() } } + /* 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_ACTION( trans ) << ", "; + 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"; @@ -543,8 +568,11 @@ std::ostream &TabCodeGen::TRANS_TARGS_WI() out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; diff --git a/rlgen-csharp/flatcodegen.cpp b/rlgen-csharp/flatcodegen.cpp index f939c02..bf3ba24 100644 --- a/rlgen-csharp/flatcodegen.cpp +++ b/rlgen-csharp/flatcodegen.cpp @@ -236,8 +236,10 @@ std::ostream &CSharpFlatCodeGen::EOF_TRANS() /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } out << trans; if ( !st.last() ) { @@ -394,8 +396,11 @@ std::ostream &CSharpFlatCodeGen::TRANS_TARGS() out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; diff --git a/rlgen-csharp/fsmcodegen.h b/rlgen-csharp/fsmcodegen.h index 439187e..d29d551 100644 --- a/rlgen-csharp/fsmcodegen.h +++ b/rlgen-csharp/fsmcodegen.h @@ -117,8 +117,8 @@ protected: string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } - string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; } - string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; } + string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } + string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } diff --git a/rlgen-csharp/tabcodegen.cpp b/rlgen-csharp/tabcodegen.cpp index 0e65568..9233246 100644 --- a/rlgen-csharp/tabcodegen.cpp +++ b/rlgen-csharp/tabcodegen.cpp @@ -334,8 +334,10 @@ std::ostream &CSharpTabCodeGen::EOF_TRANS() for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } out << trans; if ( !st.last() ) { @@ -489,6 +491,17 @@ std::ostream &CSharpTabCodeGen::TRANS_TARGS() } } + 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"; @@ -526,6 +539,15 @@ std::ostream &CSharpTabCodeGen::TRANS_ACTIONS() } } + for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { + if ( st->eofTrans != 0 ) { + RedTransAp *trans = st->eofTrans; + TRANS_ACTION( trans ) << ", "; + 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"; @@ -543,8 +565,11 @@ std::ostream &CSharpTabCodeGen::TRANS_TARGS_WI() out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; diff --git a/rlgen-java/javacodegen.cpp b/rlgen-java/javacodegen.cpp index e70a7b7..fdce2b3 100644 --- a/rlgen-java/javacodegen.cpp +++ b/rlgen-java/javacodegen.cpp @@ -611,8 +611,10 @@ std::ostream &JavaTabCodeGen::EOF_TRANS() for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } /* Write any eof action. */ ARRAY_ITEM( INT(trans), st.last() ); @@ -705,23 +707,35 @@ std::ostream &JavaTabCodeGen::INDICIES() 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 ); } } @@ -754,6 +768,13 @@ std::ostream &JavaTabCodeGen::TRANS_ACTIONS() } } + 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 ); @@ -769,8 +790,11 @@ std::ostream &JavaTabCodeGen::TRANS_TARGS_WI() /* Keep a count of the num of items in the array written. */ for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ ARRAY_ITEM( INT(trans->targ->id), ( t >= redFsm->transSet.length()-1 ) ); } delete[] transPtrs; diff --git a/rlgen-java/javacodegen.h b/rlgen-java/javacodegen.h index 9ee24c6..2626153 100644 --- a/rlgen-java/javacodegen.h +++ b/rlgen-java/javacodegen.h @@ -150,8 +150,8 @@ public: string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } - string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; } - string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; } + string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } + string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } diff --git a/rlgen-ruby/ruby-codegen.h b/rlgen-ruby/ruby-codegen.h index af56318..21034ff 100644 --- a/rlgen-ruby/ruby-codegen.h +++ b/rlgen-ruby/ruby-codegen.h @@ -84,8 +84,8 @@ protected: string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } - string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; } - string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; } + string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } + string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } diff --git a/rlgen-ruby/ruby-flatcodegen.cpp b/rlgen-ruby/ruby-flatcodegen.cpp index 71dbc9d..a8e7469 100644 --- a/rlgen-ruby/ruby-flatcodegen.cpp +++ b/rlgen-ruby/ruby-flatcodegen.cpp @@ -215,8 +215,10 @@ std::ostream &RubyFlatCodeGen::EOF_TRANS() for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } /* Write any eof action. */ ARRAY_ITEM( INT(trans), ++totalStateNum, st.last() ); @@ -237,8 +239,11 @@ std::ostream &RubyFlatCodeGen::TRANS_TARGS() int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ ARRAY_ITEM( INT( trans->targ->id ), ++totalStates, t >= redFsm->transSet.length()-1 ); } END_ARRAY_LINE(); diff --git a/rlgen-ruby/ruby-tabcodegen.cpp b/rlgen-ruby/ruby-tabcodegen.cpp index 6ad01c6..8b97697 100644 --- a/rlgen-ruby/ruby-tabcodegen.cpp +++ b/rlgen-ruby/ruby-tabcodegen.cpp @@ -673,8 +673,10 @@ std::ostream &RubyTabCodeGen::EOF_TRANS() for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; - if ( st->eofTrans != 0 ) - trans = st->eofTrans->id+1; + if ( st->eofTrans != 0 ) { + assert( st->eofTrans->pos >= 0 ); + trans = st->eofTrans->pos+1; + } /* Write any eof action. */ ARRAY_ITEM( INT(trans), ++totalStateNum, st.last() ); @@ -801,6 +803,14 @@ std::ostream &RubyTabCodeGen::TRANS_TARGS() } } + 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 ); @@ -833,6 +843,13 @@ std::ostream &RubyTabCodeGen::TRANS_ACTIONS() } } + for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { + if ( st->eofTrans != 0 ) { + RedTransAp *trans = st->eofTrans; + ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++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 ); @@ -851,8 +868,11 @@ std::ostream &RubyTabCodeGen::TRANS_TARGS_WI() START_ARRAY_LINE(); int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { - /* Write out the target state. */ + /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; + trans->pos = t; + + /* Write out the target state. */ ARRAY_ITEM( INT(trans->targ->id), ++totalStates, ( t >= redFsm->transSet.length()-1 ) ); } END_ARRAY_LINE(); diff --git a/test/scan2.rl b/test/scan2.rl new file mode 100644 index 0000000..a1ae959 --- /dev/null +++ b/test/scan2.rl @@ -0,0 +1,34 @@ +/* + * @LANG: indep + */ +ptr ts; +ptr te; +int act; +int token; +%% +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + prints "pat1\n"; + }; + + [ab]+ . 'c' => { + prints "pat2\n"; + }; + + any => { + prints "any\n"; + }; + *|; +}%% +/* _____INPUT_____ +"a" +_____INPUT_____ */ +/* _____OUTPUT_____ +pat1 +ACCEPT +_____OUTPUT_____ */ diff --git a/test/scan3.rl b/test/scan3.rl new file mode 100644 index 0000000..ca1a136 --- /dev/null +++ b/test/scan3.rl @@ -0,0 +1,32 @@ +/* + * @LANG: indep + */ +ptr ts; +ptr te; +int act; +int token; +%% +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + prints "pat1\n"; + }; + 'b' => { + prints "pat2\n"; + }; + [ab] any* => { + prints "pat3\n"; + }; + *|; +}%% +/* _____INPUT_____ +"ab89" +_____INPUT_____ */ +/* _____OUTPUT_____ +pat3 +ACCEPT +_____OUTPUT_____ */ -- 2.7.4