summaryrefslogtreecommitdiff
path: root/ragel
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2014-12-01 17:14:41 -0500
committerAdrian Thurston <thurston@complang.org>2014-12-01 17:19:04 -0500
commitb83970cf53552833f5a037e83f263ed07a78e1cf (patch)
tree7f42758f59199b9807281e036c735788b338b1d7 /ragel
parent0d113943c37e1d361986cdcc6abbce5159afe94c (diff)
downloadragel-b83970cf53552833f5a037e83f263ed07a78e1cf.tar.gz
added default coverage statistics to -s option
This shows how much of the flat space is occupied by default transitions. This includes the full key space (before first and after last transition). refs #23
Diffstat (limited to 'ragel')
-rw-r--r--ragel/cdcodegen.cpp6
-rw-r--r--ragel/redfsm.cpp58
-rw-r--r--ragel/redfsm.h2
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();