diff options
Diffstat (limited to 'ragel')
-rw-r--r-- | ragel/cdcodegen.cpp | 6 | ||||
-rw-r--r-- | ragel/redfsm.cpp | 58 | ||||
-rw-r--r-- | ragel/redfsm.h | 2 |
3 files changed, 66 insertions, 0 deletions
diff --git a/ragel/cdcodegen.cpp b/ragel/cdcodegen.cpp index bc19ab88..30b14546 100644 --- a/ragel/cdcodegen.cpp +++ b/ragel/cdcodegen.cpp @@ -1030,6 +1030,12 @@ void FsmCodeGen::finishRagelDef() else redFsm->chooseSingle(); + if ( printStatistics ) { + std::cout << "fsm-name\t" << fsmName << std::endl; + redFsm->percentageDefault(); + std::cout << std::endl; + } + /* If any errors have occured in the input file then don't write anything. */ if ( gblErrorCount > 0 ) return; diff --git a/ragel/redfsm.cpp b/ragel/redfsm.cpp index 9a58752b..615bffdd 100644 --- a/ragel/redfsm.cpp +++ b/ragel/redfsm.cpp @@ -24,6 +24,7 @@ #include "mergesort.h" #include <iostream> #include <sstream> +#include <iomanip> using std::ostringstream; @@ -437,6 +438,63 @@ void RedFsmAp::chooseDefaultSpan() } } +void RedFsmAp::percentageDefault() +{ + /* Flat Tables: how much of the index space is is not covered my non-default + * transitions. Runs only if stats are requested. */ + Size uncovered = 0; + + for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { + if ( st->outRange.length() == 0 ) { + uncovered += keyOps->alphSize(); + } + else { + /* Count span before first. */ + RedTransList::Iter rtel = st->outRange; + if ( keyOps->minKey < rtel->lowKey ) { + /* High is one below the first range. */ + Key highGap = rtel->lowKey; + highGap.decrement(); + uncovered += keyOps->span( keyOps->minKey, highGap ); + } + + /* Count the transition if it goes to default. */ + if ( rtel->value == st->defTrans ) + uncovered += keyOps->span( rtel->lowKey, rtel->highKey ); + + /* Count gaps. */ + rtel.increment(); + for ( ; rtel.lte(); rtel++ ) { + /* Low is one above the previous' high. */ + Key lowKey = rtel[-1].highKey; + lowKey.increment(); + if ( lowKey < rtel->lowKey ) + uncovered += keyOps->span( lowKey, rtel->lowKey ); + + /* Count the transition if it goes to default. */ + if ( rtel->value == st->defTrans ) + uncovered += keyOps->span( rtel->lowKey, rtel->highKey ); + } + + /* Count the span after the last. */ + RedTransList::Iter last = st->outRange.last(); + if ( last->highKey < keyOps->maxKey ) { + Key lowGap = last->lowKey; + lowGap.increment(); + uncovered += keyOps->span( lowGap, keyOps->maxKey ); + } + } + } + + long long total = keyOps->alphSize() * stateList.length(); + double percentage = 100.0 * ( (double)uncovered / (double)total ); + + std::cout << "default-indicies\t" << uncovered << std::endl; + std::cout << "total-indicies\t" << total << std::endl; + std::cout << "percentage-default\t" << std::setprecision( 6 ) << + percentage << "%" << std::endl; +} + RedTransAp *RedFsmAp::chooseDefaultGoto( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ diff --git a/ragel/redfsm.h b/ragel/redfsm.h index 2e7ad7c1..332c1639 100644 --- a/ragel/redfsm.h +++ b/ragel/redfsm.h @@ -489,6 +489,8 @@ struct RedFsmAp RedTransAp *chooseDefaultGoto( RedStateAp *state ); void chooseDefaultGoto(); + void percentageDefault(); + /* Ordering states by transition connections. */ void optimizeStateOrdering( RedStateAp *state ); void optimizeStateOrdering(); |