diff options
-rw-r--r-- | colm/colm.h | 4 | ||||
-rw-r--r-- | colm/dotgen.cpp | 310 | ||||
-rw-r--r-- | colm/fsmcodegen.cpp | 1 | ||||
-rw-r--r-- | colm/main.cpp | 29 | ||||
-rw-r--r-- | colm/parsedata.cpp | 11 | ||||
-rw-r--r-- | colm/parsedata.h | 11 |
6 files changed, 62 insertions, 304 deletions
diff --git a/colm/colm.h b/colm/colm.h index b3a99e0d..721529bd 100644 --- a/colm/colm.h +++ b/colm/colm.h @@ -35,9 +35,7 @@ #define PROGNAME "colm" /* IO filenames and stream. */ -extern bool printPrintables; -extern bool graphvizDone; - +extern bool genGraphviz; extern int gblErrorCount; std::ostream &error(); diff --git a/colm/dotgen.cpp b/colm/dotgen.cpp index fd8af6b8..2fd9bf09 100644 --- a/colm/dotgen.cpp +++ b/colm/dotgen.cpp @@ -20,272 +20,13 @@ */ -#include "dotgen.h" +#include "colm.h" #include "parsedata.h" -#include "pdacodegen.h" using namespace std; -#if 0 -std::ostream &GraphvizDotGen::KEY( Key key ) -{ - if ( printPrintables && key.isPrintable() ) { - // Output values as characters, ensuring we escape the quote (") character - char cVal = (char) key.getVal(); - out << "'"; - switch ( cVal ) { - case '"': case '\\': - out << "\\" << cVal; - break; - default: - out << cVal; - break; - } - out << "'"; - } - else { - if ( keyOps->isSigned ) - out << key.getVal(); - else - out << (unsigned long) key.getVal(); - } - - return out; -} - -std::ostream &GraphvizDotGen::TRANS_ACTION( RedState *fromState, RedTrans *trans ) -{ - int n = 0; - RedAction *actions[3]; - - if ( fromState->fromStateAction != 0 ) - actions[n++] = fromState->fromStateAction; - if ( trans->action != 0 ) - actions[n++] = trans->action; - if ( trans->targ != 0 && trans->targ->toStateAction != 0 ) - actions[n++] = trans->targ->toStateAction; - - if ( n > 0 ) - out << " / "; - - /* Loop the existing actions and write out what's there. */ - for ( int a = 0; a < n; a++ ) { - for ( GenActionTable::Iter actIt = actions[a]->key.first(); actIt.lte(); actIt++ ) { - GenAction *action = actIt->value; - out << action->nameOrLoc(); - if ( a < n-1 || !actIt.last() ) - out << ", "; - } - } - return out; -} - -std::ostream &GraphvizDotGen::ACTION( RedAction *action ) -{ - /* The action. */ - out << " / "; - for ( GenActionTable::Iter actIt = action->key.first(); actIt.lte(); actIt++ ) { - GenAction *action = actIt->value; - if ( action->name != 0 ) - out << action->name; - else - out << action->loc.line << ":" << action->loc.col; - if ( !actIt.last() ) - out << ", "; - } - return out; -} - -std::ostream &GraphvizDotGen::ONCHAR( Key lowKey, Key highKey ) -{ - if ( lowKey > keyOps->maxKey ) { - GenCondSpace *condSpace = redFsm->findCondSpace( lowKey, highKey ); - Key values = ( lowKey - condSpace->baseKey ) / keyOps->alphSize(); - - lowKey = keyOps->minKey + - (lowKey - condSpace->baseKey - keyOps->alphSize() * values.getVal()); - highKey = keyOps->minKey + - (highKey - condSpace->baseKey - keyOps->alphSize() * values.getVal()); - KEY( lowKey ); - if ( lowKey != highKey ) { - out << ".."; - KEY( highKey ); - } - out << "("; - - for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { - bool set = values & (1 << csi.pos()); - if ( !set ) - out << "!"; - out << (*csi)->nameOrLoc(); - if ( !csi.last() ) - out << ", "; - } - out << ")"; - } - else { - /* Output the key. Possibly a range. */ - KEY( lowKey ); - if ( highKey != lowKey ) { - out << ".."; - KEY( highKey ); - } - } - return out; -} - -void GraphvizDotGen::writeTransList( RedState *state ) -{ - /* Build the set of unique transitions out of this state. */ - RedTransPtrSet stTransSet; - for ( RedTransList::Iter tel = state->outRange; tel.lte(); tel++ ) { - /* If we haven't seen the transitions before, the move forward - * emitting all the transitions on the same character. */ - if ( stTransSet.insert( tel->value ) ) { - /* Write out the from and to states. */ - out << "\t" << state->id << " -> "; - - if ( tel->value->targ == 0 ) - out << "err_" << state->id; - else - out << tel->value->targ->id; - - /* Begin the label. */ - out << " [ label = \""; - ONCHAR( tel->lowKey, tel->highKey ); - - /* Walk the transition list, finding the same. */ - for ( RedTransList::Iter mtel = tel.next(); mtel.lte(); mtel++ ) { - if ( mtel->value == tel->value ) { - out << ", "; - ONCHAR( mtel->lowKey, mtel->highKey ); - } - } - - /* Write the action and close the transition. */ - TRANS_ACTION( state, tel->value ); - out << "\" ];\n"; - } - } - - /* Write the default transition. */ - if ( state->defTrans != 0 ) { - /* Write out the from and to states. */ - out << "\t" << state->id << " -> "; - - if ( state->defTrans->targ == 0 ) - out << "err_" << state->id; - else - out << state->defTrans->targ->id; - - /* Begin the label. */ - out << " [ label = \"DEF"; - - /* Write the action and close the transition. */ - TRANS_ACTION( state, state->defTrans ); - out << "\" ];\n"; - } -} -void GraphvizDotGen::writeDotFile( ) -{ - out << - "digraph " << fsmName << " {\n" - " rankdir=LR;\n"; - - /* Define the psuedo states. Transitions will be done after the states - * have been defined as either final or not final. */ - out << " node [ shape = point ];\n"; - out << " ENTRY;\n"; - - /* Psuedo states for entry points in the entry map. */ - for ( EntryIdVect::Iter en = redFsm->entryPointIds; en.lte(); en++ ) { - RedState *state = redFsm->allStates + *en; - out << " en_" << state->id << ";\n"; - } - - /* Psuedo states for final states with eof actions. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - if ( st->eofAction != 0 ) - out << " eof_" << st->id << ";\n"; - } - - out << " node [ shape = circle, height = 0.2 ];\n"; - - /* Psuedo states for states whose default actions go to error. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - bool needsErr = false; - if ( st->defTrans != 0 && st->defTrans->targ == 0 ) - needsErr = true; - else { - for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) { - if ( tel->value->targ == 0 ) { - needsErr = true; - break; - } - } - } - - if ( needsErr ) - out << " err_" << st->id << " [ label=\"\"];\n"; - } - - /* Attributes common to all nodes, plus double circle for final states. */ - out << " node [ fixedsize = true, height = 0.65, shape = doublecircle ];\n"; - - /* List Final states. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - if ( st->isFinal ) - out << " " << st->id << ";\n"; - } - - /* List transitions. */ - out << " node [ shape = circle ];\n"; - - /* Walk the states. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) - writeTransList( st ); - - /* Transitions into the start state. */ - out << " ENTRY -> " << redFsm->startState->id << " [ label = \"IN"; - out << "\" ];\n"; - - /* Transitions into the entry points. */ - for ( EntryIdVect::Iter en = redFsm->entryPointIds; en.lte(); en++ ) { - RedState *state = redFsm->allStates + *en; - char *name = redFsm->entryPointNames[en.pos()]; - out << " en_" << state->id << " -> " << state->id << - " [ label = \"" << name << "\" ];\n"; - } - - /* Out action transitions. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - if ( st->eofAction != 0 ) { - out << " " << st->id << " -> eof_" << - st->id << " [ label = \"EOF"; - ACTION( st->eofAction ) << "\" ];\n"; - } - } - - out << - "}\n"; -} - -void GraphvizDotGen::finishRagelDef() -{ - if ( !graphvizDone ) { - graphvizDone = true; - - /* For dot file generation we want to pick default transitions. */ - redFsm->chooseDefaultSpan(); - - /* Write out with it. */ - writeDotFile(); - } -} - - -void PdaCodeGen::writeTransList( PdaState *state ) +void ParseData::writeTransList( PdaState *state ) { for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) { /* Write out the from and to states. */ @@ -294,9 +35,9 @@ void PdaCodeGen::writeTransList( PdaState *state ) /* Begin the label. */ out << " [ label = \""; long key = trans->key; - KlangEl *lel = pd->langElIndex[key]; + KlangEl *lel = langElIndex[key]; if ( lel != 0 ) - out << lel->data; + out << lel->name; else out << (char)key; @@ -308,12 +49,12 @@ void PdaCodeGen::writeTransList( PdaState *state ) out << "S(" << trans->value->actOrds[act.pos()] << ")"; break; case 2: { - out << "R(" << pd->prodIdIndex[(*act >> 2)]->data << + out << "R(" << prodIdIndex[(*act >> 2)]->data << ", " << trans->value->actOrds[act.pos()] << ")"; break; } case 3: { - out << "SR(" << pd->prodIdIndex[(*act >> 2)]->data << + out << "SR(" << prodIdIndex[(*act >> 2)]->data << ", " << trans->value->actOrds[act.pos()] << ")"; break; }} @@ -326,44 +67,45 @@ void PdaCodeGen::writeTransList( PdaState *state ) } } -void PdaCodeGen::writeDotFile( PdaGraph *graph ) +void ParseData::writeDotFile( PdaGraph *graph ) { out << "digraph " << parserName << " {\n" - " rankdir=LR;\n"; + " rankdir=LR;\n" + " ranksep=\"0\"\n" + " nodesep=\"0.25\"\n" + "\n"; /* Define the psuedo states. Transitions will be done after the states * have been defined as either final or not final. */ - out << " node [ shape = point ];\n"; - out << " ENTRY;\n"; - - out << " node [ shape = circle, height = 0.2 ];\n"; - - /* Attributes common to all nodes, plus double circle for final states. */ - out << " node [ fixedsize = true, height = 0.65, shape = doublecircle ];\n"; + out << + " node [ shape = point ];\n" + " ENTRY [ label = \"\" ];\n" + "\n" + " node [ shape = circle, fixedsize = true, height = 0.2 ];\n"; - /* List Final states. */ - for ( PdaStateSet::Iter st = graph->finStateSet; st.lte(); st++ ) - out << " " << (*st)->stateNum << ";\n"; + /* Walk the states. */ + for ( PdaStateList::Iter st = graph->stateList; st.lte(); st++ ) + out << " " << st->stateNum << " [ label = \"\" ];\n"; - /* List transitions. */ - out << " node [ shape = circle ];\n"; + out << "\n"; /* Walk the states. */ for ( PdaStateList::Iter st = graph->stateList; st.lte(); st++ ) writeTransList( st ); /* Transitions into the start state. */ - out << " ENTRY -> " << graph->startState->stateNum << " [ label = \"START\" ];\n"; + out << " ENTRY -> " << graph->startState->stateNum << " [ label = \"\" ];\n"; out << "}\n"; } -void PdaCodeGen::writeDotFile( ) +void ParseData::writeDotFile() { - writeDotFile( pd->pdaGraph ); + for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) { + if ( lel->parserId >= 0 ) + writeDotFile( lel->pdaGraph ); + } } -#endif - diff --git a/colm/fsmcodegen.cpp b/colm/fsmcodegen.cpp index 29d840ee..e0eb3d9d 100644 --- a/colm/fsmcodegen.cpp +++ b/colm/fsmcodegen.cpp @@ -22,7 +22,6 @@ #include "parsedata.h" #include "fsmcodegen.h" #include "redfsm.h" -#include "dotgen.h" #include "bstmap.h" #include "fsmrun.h" #include <sstream> diff --git a/colm/main.cpp b/colm/main.cpp index fd403313..a6170f0d 100644 --- a/colm/main.cpp +++ b/colm/main.cpp @@ -37,7 +37,6 @@ #include "vector.h" #include "version.h" #include "fsmcodegen.h" -#include "dotgen.h" using std::istream; using std::ifstream; @@ -49,9 +48,7 @@ using std::cerr; using std::endl; /* Graphviz dot file generation. */ -bool graphvizDone = false; - -bool printPrintables = false; +bool genGraphviz = false; using std::ostream; using std::istream; @@ -308,7 +305,7 @@ void compileOutput( const char *argv0 ) void process_args( int argc, const char **argv ) { - ParamCheck pc( "vlio:S:M:vHh?-:s", argc, argv ); + ParamCheck pc( "vlio:S:M:vHh?-:sV", argc, argv ); while ( pc.check() ) { switch ( pc.state ) { @@ -341,6 +338,9 @@ void process_args( int argc, const char **argv ) case 's': printStatistics = true; break; + case 'V': + generateGraphviz = true; + break; case '-': if ( strcasecmp(pc.parameterArg, "help") == 0 ) { usage(); @@ -429,10 +429,21 @@ int main(int argc, const char **argv) /* Initiate a compile following a parse. */ scanner.parser->pd->semanticAnalysis(); - if ( outStream != 0 ) - delete outStream; - - compileOutput( argv[0] ); + /* + * Write output. + */ + if ( generateGraphviz ) { + outStream = &cout; + scanner.parser->pd->writeDotFile(); + } + else { + openOutput(); + scanner.parser->pd->generateOutput(); + + if ( outStream != 0 ) + delete outStream; + compileOutput( argv[0] ); + } return 0; } diff --git a/colm/parsedata.cpp b/colm/parsedata.cpp index 1ed0403d..ba7f14cd 100644 --- a/colm/parsedata.cpp +++ b/colm/parsedata.cpp @@ -1747,7 +1747,7 @@ void ParseData::semanticAnalysis() /* Make the reduced fsm. */ RedFsmBuild reduce( sectionName, this, fsmGraph ); - RedFsm *redFsm = reduce.reduceMachine(); + redFsm = reduce.reduceMachine(); /* Build the parsers used for patterns and replacements. */ makePatternParsers(); @@ -1774,13 +1774,10 @@ void ParseData::semanticAnalysis() /* Parse patterns and replacements. */ parsePatterns(); +} - /* - * Write output. - */ - - openOutput(); - +void ParseData::generateOutput() +{ FsmCodeGen *fsmGen = new FsmCodeGen("<INPUT>", sectionName, *outStream, redFsm, fsmTables ); diff --git a/colm/parsedata.h b/colm/parsedata.h index 9bf464b4..f2c382f5 100644 --- a/colm/parsedata.h +++ b/colm/parsedata.h @@ -743,6 +743,15 @@ struct ParseData void resolveUses(); void createDefaultScanner(); void semanticAnalysis(); + void generateOutput(); + + /* + * Graphviz Generation + */ + void writeTransList( PdaState *state ); + void writeDotFile( PdaGraph *graph ); + void writeDotFile( ); + /* * Data collected during the parse. @@ -885,6 +894,8 @@ struct ParseData ObjFieldMap *objFieldMap; bool revertOn; + + RedFsm *redFsm; }; void afterOpMinimize( FsmGraph *fsm, bool lastInSeq = true ); |