tizen 2.3.1 release
[external/ragel.git] / ragel / xmlcodegen.cpp
index 94443f1..9a9c388 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2005-2007 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2005-2007 Adrian Thurston <thurston@complang.org>
  */
 
 /*  This file is part of Ragel.
 #include "xmlcodegen.h"
 #include "parsedata.h"
 #include "fsmgraph.h"
+#include "gendata.h"
+#include "inputdata.h"
 #include <string.h>
+#include "rlparse.h"
+#include "version.h"
 
 using namespace std;
 
-XMLCodeGen::XMLCodeGen( char *fsmName, ParseData *pd, FsmAp *fsm, 
-               std::ostream &out )
+GenBase::GenBase( char *fsmName, ParseData *pd, FsmAp *fsm )
 :
        fsmName(fsmName),
        pd(pd),
        fsm(fsm),
-       out(out),
        nextActionTableId(0)
 {
 }
 
+void GenBase::appendTrans( TransListVect &outList, Key lowKey, 
+               Key highKey, TransAp *trans )
+{
+       if ( trans->toState != 0 || trans->actionTable.length() > 0 )
+               outList.append( TransEl( lowKey, highKey, trans ) );
+}
+
+void GenBase::reduceActionTables()
+{
+       /* Reduce the actions tables to a set. */
+       for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) {
+               RedActionTable *actionTable = 0;
+
+               /* Reduce To State Actions. */
+               if ( st->toStateActionTable.length() > 0 ) {
+                       if ( actionTableMap.insert( st->toStateActionTable, &actionTable ) )
+                               actionTable->id = nextActionTableId++;
+               }
+
+               /* Reduce From State Actions. */
+               if ( st->fromStateActionTable.length() > 0 ) {
+                       if ( actionTableMap.insert( st->fromStateActionTable, &actionTable ) )
+                               actionTable->id = nextActionTableId++;
+               }
+
+               /* Reduce EOF actions. */
+               if ( st->eofActionTable.length() > 0 ) {
+                       if ( actionTableMap.insert( st->eofActionTable, &actionTable ) )
+                               actionTable->id = nextActionTableId++;
+               }
+
+               /* Loop the transitions and reduce their actions. */
+               for ( TransList::Iter trans = st->outList; trans.lte(); trans++ ) {
+                       if ( trans->actionTable.length() > 0 ) {
+                               if ( actionTableMap.insert( trans->actionTable, &actionTable ) )
+                                       actionTable->id = nextActionTableId++;
+                       }
+               }
+       }
+}
+
+XMLCodeGen::XMLCodeGen( char *fsmName, ParseData *pd, FsmAp *fsm, std::ostream &out )
+:
+       GenBase(fsmName, pd, fsm),
+       out(out)
+{
+}
+
 
 void XMLCodeGen::writeActionList()
 {
@@ -82,47 +132,6 @@ void XMLCodeGen::writeActionTableList()
        delete[] tables;
 }
 
-void XMLCodeGen::reduceActionTables()
-{
-       /* Reduce the actions tables to a set. */
-       for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) {
-               RedActionTable *actionTable = 0;
-
-               /* Reduce To State Actions. */
-               if ( st->toStateActionTable.length() > 0 ) {
-                       if ( actionTableMap.insert( st->toStateActionTable, &actionTable ) )
-                               actionTable->id = nextActionTableId++;
-               }
-
-               /* Reduce From State Actions. */
-               if ( st->fromStateActionTable.length() > 0 ) {
-                       if ( actionTableMap.insert( st->fromStateActionTable, &actionTable ) )
-                               actionTable->id = nextActionTableId++;
-               }
-
-               /* Reduce EOF actions. */
-               if ( st->eofActionTable.length() > 0 ) {
-                       if ( actionTableMap.insert( st->eofActionTable, &actionTable ) )
-                               actionTable->id = nextActionTableId++;
-               }
-
-               /* Loop the transitions and reduce their actions. */
-               for ( TransList::Iter trans = st->outList; trans.lte(); trans++ ) {
-                       if ( trans->actionTable.length() > 0 ) {
-                               if ( actionTableMap.insert( trans->actionTable, &actionTable ) )
-                                       actionTable->id = nextActionTableId++;
-                       }
-               }
-       }
-}
-
-void XMLCodeGen::appendTrans( TransListVect &outList, Key lowKey, 
-               Key highKey, TransAp *trans )
-{
-       if ( trans->toState != 0 || trans->actionTable.length() > 0 )
-               outList.append( TransEl( lowKey, highKey, trans ) );
-}
-
 void XMLCodeGen::writeKey( Key key )
 {
        if ( keyOps->isSigned )
@@ -175,26 +184,24 @@ void XMLCodeGen::writeTransList( StateAp *state )
        out << "      </trans_list>\n";
 }
 
-void XMLCodeGen::writeLmSwitch( InlineItem *item )
+void XMLCodeGen::writeEofTrans( StateAp *state )
 {
-       LongestMatch *longestMatch = item->longestMatch;
-
-       out << "<lm_switch";
-       if ( longestMatch->lmSwitchHandlesError )
-               out << " handles_error=\"t\"";
-       out << ">\n";
+       RedActionTable *eofActions = 0;
+       if ( state->eofActionTable.length() > 0 )
+               eofActions = actionTableMap.find( state->eofActionTable );
        
-       for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) {
-               if ( lmi->inLmSelect && lmi->action != 0 ) {
-                       /* Open the action. Write it with the context that sets up _p 
-                        * when doing control flow changes from inside the machine. */
-                       out << "      <sub_action id=\"" << lmi->longestMatchId << "\">";
-                       writeInlineList( lmi->action->inlineList, item );
-                       out << "</sub_action>\n";
-               }
-       }
+       /* The <eof_t> is used when there is an eof target, otherwise the eof
+        * action goes into state actions. */
+       if ( state->eofTarget != 0 ) {
+               out << "      <eof_t>" << state->eofTarget->alg.stateNum;
+
+               if ( eofActions != 0 )
+                       out << " " << eofActions->id;
+               else
+                       out << " x"; 
 
-       out << "    </lm_switch><exec><get_tokend></get_tokend></exec>";
+               out << "</eof_t>" << endl;
+       }
 }
 
 void XMLCodeGen::writeText( InlineItem *item )
@@ -206,82 +213,7 @@ void XMLCodeGen::writeText( InlineItem *item )
                out << "</text>";
 }
 
-bool isLmItem( InlineItem *context )
-{
-       return context != 0 && (
-               context->type == InlineItem::LmOnLast ||
-               context->type == InlineItem::LmOnNext ||
-               context->type == InlineItem::LmOnLagBehind ||
-               context->type == InlineItem::LmSwitch );
-}
-
-void XMLCodeGen::writeCtrlFlow( InlineItem *item, InlineItem *context )
-{
-       if ( isLmItem( context ) ) {
-               out << "<sub_action>";
-               out << "<exec><get_tokend></get_tokend></exec>";
-       }
-
-       switch ( item->type ) {
-       case InlineItem::Goto:
-               writeGoto( item, context );
-               break;
-       case InlineItem::GotoExpr:
-               writeGotoExpr( item, context );
-               break;
-       case InlineItem::Call:
-               writeCall( item, context );
-               break;
-       case InlineItem::CallExpr:
-               writeCallExpr( item, context );
-               break;
-       case InlineItem::Next:
-               writeNext( item, context );
-               break;
-       case InlineItem::NextExpr:
-               writeNextExpr( item, context );
-               break;
-       case InlineItem::Break:
-               out << "<break></break>";
-               break;
-       case InlineItem::Ret: 
-               out << "<ret></ret>";
-               break;
-       default: break;
-       }
-
-       if ( isLmItem( context ) )
-               out << "</sub_action>";
-}
-
-void XMLCodeGen::writePtrMod( InlineItem *item, InlineItem *context )
-{
-       if ( isLmItem( context ) ) {
-               switch ( item->type ) {
-               case InlineItem::Hold:
-                       out << "<holdte></holdte>";
-                       break;
-               case InlineItem::Exec:
-                       writeActionExecTE( item );
-                       break;
-               default: break;
-               }
-       }
-       else {
-               switch ( item->type ) {
-               case InlineItem::Hold:
-                       out << "<hold></hold>";
-                       break;
-               case InlineItem::Exec:
-                       writeActionExec( item );
-                       break;
-               default: break;
-               }
-       }
-}
-
-
-void XMLCodeGen::writeGoto( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeGoto( InlineItem *item )
 {
        if ( pd->generatingSectionSubset )
                out << "<goto>-1</goto>";
@@ -291,7 +223,7 @@ void XMLCodeGen::writeGoto( InlineItem *item, InlineItem *context )
        }
 }
 
-void XMLCodeGen::writeCall( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeCall( InlineItem *item )
 {
        if ( pd->generatingSectionSubset )
                out << "<call>-1</call>";
@@ -301,7 +233,7 @@ void XMLCodeGen::writeCall( InlineItem *item, InlineItem *context )
        }
 }
 
-void XMLCodeGen::writeNext( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeNext( InlineItem *item )
 {
        if ( pd->generatingSectionSubset )
                out << "<next>-1</next>";
@@ -311,28 +243,28 @@ void XMLCodeGen::writeNext( InlineItem *item, InlineItem *context )
        }
 }
 
-void XMLCodeGen::writeGotoExpr( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeGotoExpr( InlineItem *item )
 {
        out << "<goto_expr>";
-       writeInlineList( item->children, 0 );
+       writeInlineList( item->children );
        out << "</goto_expr>";
 }
 
-void XMLCodeGen::writeCallExpr( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeCallExpr( InlineItem *item )
 {
        out << "<call_expr>";
-       writeInlineList( item->children, 0 );
+       writeInlineList( item->children );
        out << "</call_expr>";
 }
 
-void XMLCodeGen::writeNextExpr( InlineItem *item, InlineItem *context )
+void XMLCodeGen::writeNextExpr( InlineItem *item )
 {
        out << "<next_expr>";
-       writeInlineList( item->children, 0 );
+       writeInlineList( item->children );
        out << "</next_expr>";
 }
 
-void XMLCodeGen::writeEntry( InlineItem * item )
+void XMLCodeGen::writeEntry( InlineItem *item )
 {
        if ( pd->generatingSectionSubset )
                out << "<entry>-1</entry>";
@@ -345,62 +277,118 @@ void XMLCodeGen::writeEntry( InlineItem * item )
 void XMLCodeGen::writeActionExec( InlineItem *item )
 {
        out << "<exec>";
-       writeInlineList( item->children, 0 );
+       writeInlineList( item->children );
        out << "</exec>";
 }
 
-void XMLCodeGen::writeActionExecTE( InlineItem *item )
-{
-       out << "<execte>";
-       writeInlineList( item->children, 0 );
-       out << "</execte>";
-}
-
 void XMLCodeGen::writeLmOnLast( InlineItem *item )
 {
        out << "<set_tokend>1</set_tokend>";
+
        if ( item->longestMatchPart->action != 0 ) {
                out << "<sub_action>";
-               writeInlineList( item->longestMatchPart->action->inlineList, item );
+               writeInlineList( item->longestMatchPart->action->inlineList );
                out << "</sub_action>";
        }
-       out << "<exec><get_tokend></get_tokend></exec>";
 }
 
 void XMLCodeGen::writeLmOnNext( InlineItem *item )
 {
        out << "<set_tokend>0</set_tokend>";
+       out << "<hold></hold>";
+
        if ( item->longestMatchPart->action != 0 ) {
                out << "<sub_action>";
-               writeInlineList( item->longestMatchPart->action->inlineList, item );
+               writeInlineList( item->longestMatchPart->action->inlineList );
                out << "</sub_action>";
        }
-       out << "<exec><get_tokend></get_tokend></exec>";
 }
 
 void XMLCodeGen::writeLmOnLagBehind( InlineItem *item )
 {
+       out << "<exec><get_tokend></get_tokend></exec>";
+
        if ( item->longestMatchPart->action != 0 ) {
                out << "<sub_action>";
-               writeInlineList( item->longestMatchPart->action->inlineList, item );
+               writeInlineList( item->longestMatchPart->action->inlineList );
                out << "</sub_action>";
        }
-       out << "<exec><get_tokend></get_tokend></exec>";
 }
 
+void XMLCodeGen::writeLmSwitch( InlineItem *item )
+{
+       LongestMatch *longestMatch = item->longestMatch;
+       out << "<lm_switch>\n";
+
+       /* We can't put the <exec> here because we may need to handle the error
+        * case and in that case p should not be changed. Instead use a default
+        * label in the switch to adjust p when user actions are not set. An id of
+        * -1 indicates the default. */
+
+       if ( longestMatch->lmSwitchHandlesError ) {
+               /* If the switch handles error then we should have also forced the
+                * error state. */
+               assert( fsm->errState != 0 );
+
+               out << "        <sub_action id=\"0\">";
+               out << "<goto>" << fsm->errState->alg.stateNum << "</goto>";
+               out << "</sub_action>\n";
+       }
+       
+       bool needDefault = false;
+       for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) {
+               if ( lmi->inLmSelect ) {
+                       if ( lmi->action == 0 )
+                               needDefault = true;
+                       else {
+                               /* Open the action. Write it with the context that sets up _p 
+                                * when doing control flow changes from inside the machine. */
+                               out << "        <sub_action id=\"" << lmi->longestMatchId << "\">";
+                               out << "<exec><get_tokend></get_tokend></exec>";
+                               writeInlineList( lmi->action->inlineList );
+                               out << "</sub_action>\n";
+                       }
+               }
+       }
+
+       if ( needDefault ) {
+               out << "        <sub_action id=\"-1\"><exec><get_tokend>"
+                               "</get_tokend></exec></sub_action>\n";
+       }
+
+       out << "    </lm_switch>";
+}
 
-void XMLCodeGen::writeInlineList( InlineList *inlineList, InlineItem *context )
+void XMLCodeGen::writeInlineList( InlineList *inlineList )
 {
        for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) {
                switch ( item->type ) {
                case InlineItem::Text:
                        writeText( item );
                        break;
-               case InlineItem::Goto: case InlineItem::GotoExpr:
-               case InlineItem::Call: case InlineItem::CallExpr:
-               case InlineItem::Next: case InlineItem::NextExpr:
-               case InlineItem::Break: case InlineItem::Ret: 
-                       writeCtrlFlow( item, context );
+               case InlineItem::Goto:
+                       writeGoto( item );
+                       break;
+               case InlineItem::GotoExpr:
+                       writeGotoExpr( item );
+                       break;
+               case InlineItem::Call:
+                       writeCall( item );
+                       break;
+               case InlineItem::CallExpr:
+                       writeCallExpr( item );
+                       break;
+               case InlineItem::Next:
+                       writeNext( item );
+                       break;
+               case InlineItem::NextExpr:
+                       writeNextExpr( item );
+                       break;
+               case InlineItem::Break:
+                       out << "<break></break>";
+                       break;
+               case InlineItem::Ret: 
+                       out << "<ret></ret>";
                        break;
                case InlineItem::PChar:
                        out << "<pchar></pchar>";
@@ -419,13 +407,12 @@ void XMLCodeGen::writeInlineList( InlineList *inlineList, InlineItem *context )
                        break;
 
                case InlineItem::Hold:
+                       out << "<hold></hold>";
+                       break;
                case InlineItem::Exec:
-                       writePtrMod( item, context );
+                       writeActionExec( item );
                        break;
 
-               case InlineItem::LmSwitch: 
-                       writeLmSwitch( item );
-                       break;
                case InlineItem::LmSetActId:
                        out << "<set_act>" << 
                                        item->longestMatchPart->longestMatchId << 
@@ -434,6 +421,7 @@ void XMLCodeGen::writeInlineList( InlineList *inlineList, InlineItem *context )
                case InlineItem::LmSetTokEnd:
                        out << "<set_tokend>1</set_tokend>";
                        break;
+
                case InlineItem::LmOnLast:
                        writeLmOnLast( item );
                        break;
@@ -443,6 +431,10 @@ void XMLCodeGen::writeInlineList( InlineList *inlineList, InlineItem *context )
                case InlineItem::LmOnLagBehind:
                        writeLmOnLagBehind( item );
                        break;
+               case InlineItem::LmSwitch: 
+                       writeLmSwitch( item );
+                       break;
+
                case InlineItem::LmInitAct:
                        out << "<init_act></init_act>";
                        break;
@@ -456,100 +448,366 @@ void XMLCodeGen::writeInlineList( InlineList *inlineList, InlineItem *context )
        }
 }
 
-void XMLCodeGen::writeAction( Action *action )
+BackendGen::BackendGen( char *fsmName, ParseData *pd, FsmAp *fsm, CodeGenData *cgd )
+:
+       GenBase(fsmName, pd, fsm),
+       cgd(cgd)
 {
-       out << "      <action id=\"" << action->actionId << "\"";
-       if ( action->name != 0 ) 
-               out << " name=\"" << action->name << "\"";
-       out << " line=\"" << action->loc.line << "\" col=\"" << action->loc.col << "\">";
-       writeInlineList( action->inlineList, 0 );
-       out << "</action>\n";
 }
 
-void xmlEscapeHost( std::ostream &out, char *data, long len )
+
+void BackendGen::makeText( GenInlineList *outList, InlineItem *item )
 {
-       char *end = data + len;
-       while ( data != end ) {
-               switch ( *data ) {
-               case '<': out << "&lt;"; break;
-               case '>': out << "&gt;"; break;
-               case '&': out << "&amp;"; break;
-               default: out << *data; break;
-               }
-               data += 1;
-       }
+       GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Text );
+       inlineItem->data = item->data;
+
+       outList->append( inlineItem );
 }
 
-void XMLCodeGen::writeStateActions( StateAp *state )
+void BackendGen::makeTargetItem( GenInlineList *outList, NameInst *nameTarg, 
+               GenInlineItem::Type type )
 {
-       RedActionTable *toStateActions = 0;
-       if ( state->toStateActionTable.length() > 0 )
-               toStateActions = actionTableMap.find( state->toStateActionTable );
+       long targetState;
+       if ( pd->generatingSectionSubset )
+               targetState = -1;
+       else {
+               EntryMapEl *targ = fsm->entryPoints.find( nameTarg->id );
+               targetState = targ->value->alg.stateNum;
+       }
 
-       RedActionTable *fromStateActions = 0;
-       if ( state->fromStateActionTable.length() > 0 )
-               fromStateActions = actionTableMap.find( state->fromStateActionTable );
+       /* Make the item. */
+       GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), type );
+       inlineItem->targId = targetState;
+       outList->append( inlineItem );
+}
 
-       RedActionTable *eofActions = 0;
-       if ( state->eofActionTable.length() > 0 )
-               eofActions = actionTableMap.find( state->eofActionTable );
-       
-       if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) {
-               out << "      <state_actions>";
-               if ( toStateActions != 0 )
-                       out << toStateActions->id;
-               else
-                       out << "x";
+/* Make a sublist item with a given type. */
+void BackendGen::makeSubList( GenInlineList *outList, 
+               InlineList *inlineList, GenInlineItem::Type type )
+{
+       /* Fill the sub list. */
+       GenInlineList *subList = new GenInlineList;
+       makeGenInlineList( subList, inlineList );
+
+       /* Make the item. */
+       GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), type );
+       inlineItem->children = subList;
+       outList->append( inlineItem );
+}
 
-               if ( fromStateActions != 0 )
-                       out << " " << fromStateActions->id;
-               else
-                       out << " x";
+void BackendGen::makeLmOnLast( GenInlineList *outList, InlineItem *item )
+{
+       makeSetTokend( outList, 1 );
 
-               if ( eofActions != 0 )
-                       out << " " << eofActions->id;
-               else
-                       out << " x"; out << "</state_actions>\n";
+       if ( item->longestMatchPart->action != 0 ) {
+               makeSubList( outList, 
+                               item->longestMatchPart->action->inlineList, 
+                               GenInlineItem::SubAction );
        }
 }
 
-void XMLCodeGen::writeStateConditions( StateAp *state )
+void BackendGen::makeLmOnNext( GenInlineList *outList, InlineItem *item )
 {
-       if ( state->stateCondList.length() > 0 ) {
-               out << "      <cond_list length=\"" << state->stateCondList.length() << "\">\n";
-               for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) {
-                       out << "        <c>";
-                       writeKey( scdi->lowKey );
-                       out << " ";
-                       writeKey( scdi->highKey );
-                       out << " ";
-                       out << scdi->condSpace->condSpaceId;
-                       out << "</c>\n";
-               }
-               out << "      </cond_list>\n";
+       makeSetTokend( outList, 0 );
+       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Hold ) );
+
+       if ( item->longestMatchPart->action != 0 ) {
+               makeSubList( outList, 
+                       item->longestMatchPart->action->inlineList,
+                       GenInlineItem::SubAction );
        }
 }
 
-void XMLCodeGen::writeStateList()
+void BackendGen::makeExecGetTokend( GenInlineList *outList )
 {
-       /* Write the list of states. */
-       out << "    <state_list length=\"" << fsm->stateList.length() << "\">\n";
-       for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) {
-               out << "      <state id=\"" << st->alg.stateNum << "\"";
-               if ( st->isFinState() )
-                       out << " final=\"t\"";
-               out << ">\n";
+       /* Make the Exec item. */
+       GenInlineItem *execItem = new GenInlineItem( InputLoc(), GenInlineItem::Exec );
+       execItem->children = new GenInlineList;
 
-               writeStateActions( st );
-               writeStateConditions( st );
-               writeTransList( st );
+       /* Make the GetTokEnd */
+       GenInlineItem *getTokend = new GenInlineItem( InputLoc(), GenInlineItem::LmGetTokEnd );
+       execItem->children->append( getTokend );
 
-               out << "      </state>\n";
+       outList->append( execItem );
+}
 
-               if ( !st.last() )
-                       out << "\n";
+void BackendGen::makeLmOnLagBehind( GenInlineList *outList, InlineItem *item )
+{
+       /* Jump to the tokend. */
+       makeExecGetTokend( outList );
+
+       if ( item->longestMatchPart->action != 0 ) {
+               makeSubList( outList,
+                       item->longestMatchPart->action->inlineList,
+                       GenInlineItem::SubAction );
        }
-       out << "    </state_list>\n";
+}
+
+void BackendGen::makeLmSwitch( GenInlineList *outList, InlineItem *item )
+{
+       GenInlineItem *lmSwitch = new GenInlineItem( InputLoc(), GenInlineItem::LmSwitch );
+       GenInlineList *lmList = lmSwitch->children = new GenInlineList;
+       LongestMatch *longestMatch = item->longestMatch;
+
+       /* We can't put the <exec> here because we may need to handle the error
+        * case and in that case p should not be changed. Instead use a default
+        * label in the switch to adjust p when user actions are not set. An id of
+        * -1 indicates the default. */
+
+       if ( longestMatch->lmSwitchHandlesError ) {
+               /* If the switch handles error then we should have also forced the
+                * error state. */
+               assert( fsm->errState != 0 );
+
+               GenInlineItem *errCase = new GenInlineItem( InputLoc(), GenInlineItem::SubAction );
+               errCase->lmId = 0;
+               errCase->children = new GenInlineList;
+
+               /* Make the item. */
+               GenInlineItem *gotoItem = new GenInlineItem( InputLoc(), GenInlineItem::Goto );
+               gotoItem->targId = fsm->errState->alg.stateNum;
+               errCase->children->append( gotoItem );
+
+               lmList->append( errCase );
+       }
+       
+       bool needDefault = false;
+       for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) {
+               if ( lmi->inLmSelect ) {
+                       if ( lmi->action == 0 )
+                               needDefault = true;
+                       else {
+                               /* Open the action. Write it with the context that sets up _p 
+                                * when doing control flow changes from inside the machine. */
+                               GenInlineItem *lmCase = new GenInlineItem( InputLoc(), 
+                                               GenInlineItem::SubAction );
+                               lmCase->lmId = lmi->longestMatchId;
+                               lmCase->children = new GenInlineList;
+
+                               makeExecGetTokend( lmCase->children );
+                               makeGenInlineList( lmCase->children, lmi->action->inlineList );
+
+                               lmList->append( lmCase );
+                       }
+               }
+       }
+
+       if ( needDefault ) {
+               GenInlineItem *defCase = new GenInlineItem( InputLoc(), 
+                               GenInlineItem::SubAction );
+               defCase->lmId = -1;
+               defCase->children = new GenInlineList;
+
+               makeExecGetTokend( defCase->children );
+
+               lmList->append( defCase );
+       }
+
+       outList->append( lmSwitch );
+}
+
+void BackendGen::makeSetTokend( GenInlineList *outList, long offset )
+{
+       GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokEnd );
+       inlineItem->offset = offset;
+       outList->append( inlineItem );
+}
+
+void BackendGen::makeSetAct( GenInlineList *outList, long lmId )
+{
+       GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetActId );
+       inlineItem->lmId = lmId;
+       outList->append( inlineItem );
+}
+
+void BackendGen::makeGenInlineList( GenInlineList *outList, InlineList *inList )
+{
+       for ( InlineList::Iter item = *inList; item.lte(); item++ ) {
+               switch ( item->type ) {
+               case InlineItem::Text:
+                       makeText( outList, item );
+                       break;
+               case InlineItem::Goto:
+                       makeTargetItem( outList, item->nameTarg, GenInlineItem::Goto );
+                       break;
+               case InlineItem::GotoExpr:
+                       makeSubList( outList, item->children, GenInlineItem::GotoExpr );
+                       break;
+               case InlineItem::Call:
+                       makeTargetItem( outList, item->nameTarg, GenInlineItem::Call );
+                       break;
+               case InlineItem::CallExpr:
+                       makeSubList( outList, item->children, GenInlineItem::CallExpr );
+                       break;
+               case InlineItem::Next:
+                       makeTargetItem( outList, item->nameTarg, GenInlineItem::Next );
+                       break;
+               case InlineItem::NextExpr:
+                       makeSubList( outList, item->children, GenInlineItem::NextExpr );
+                       break;
+               case InlineItem::Break:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Break ) );
+                       break;
+               case InlineItem::Ret: 
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Ret ) );
+                       break;
+               case InlineItem::PChar:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::PChar ) );
+                       break;
+               case InlineItem::Char: 
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Char ) );
+                       break;
+               case InlineItem::Curs: 
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Curs ) );
+                       break;
+               case InlineItem::Targs: 
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Targs ) );
+                       break;
+               case InlineItem::Entry:
+                       makeTargetItem( outList, item->nameTarg, GenInlineItem::Entry );
+                       break;
+
+               case InlineItem::Hold:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Hold ) );
+                       break;
+               case InlineItem::Exec:
+                       makeSubList( outList, item->children, GenInlineItem::Exec );
+                       break;
+
+               case InlineItem::LmSetActId:
+                       makeSetAct( outList, item->longestMatchPart->longestMatchId );
+                       break;
+               case InlineItem::LmSetTokEnd:
+                       makeSetTokend( outList, 1 );
+                       break;
+
+               case InlineItem::LmOnLast:
+                       makeLmOnLast( outList, item );
+                       break;
+               case InlineItem::LmOnNext:
+                       makeLmOnNext( outList, item );
+                       break;
+               case InlineItem::LmOnLagBehind:
+                       makeLmOnLagBehind( outList, item );
+                       break;
+               case InlineItem::LmSwitch: 
+                       makeLmSwitch( outList, item );
+                       break;
+
+               case InlineItem::LmInitAct:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmInitAct ) );
+                       break;
+               case InlineItem::LmInitTokStart:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmInitTokStart ) );
+                       break;
+               case InlineItem::LmSetTokStart:
+                       outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokStart ) );
+                       cgd->hasLongestMatch = true;
+                       break;
+               }
+       }
+}
+
+
+void XMLCodeGen::writeAction( Action *action )
+{
+       out << "      <action id=\"" << action->actionId << "\"";
+       if ( action->name != 0 ) 
+               out << " name=\"" << action->name << "\"";
+       out << " line=\"" << action->loc.line << "\" col=\"" << action->loc.col << "\">";
+       writeInlineList( action->inlineList );
+       out << "</action>\n";
+}
+
+void xmlEscapeHost( std::ostream &out, char *data, long len )
+{
+       char *end = data + len;
+       while ( data != end ) {
+               switch ( *data ) {
+               case '<': out << "&lt;"; break;
+               case '>': out << "&gt;"; break;
+               case '&': out << "&amp;"; break;
+               default: out << *data; break;
+               }
+               data += 1;
+       }
+}
+
+void XMLCodeGen::writeStateActions( StateAp *state )
+{
+       RedActionTable *toStateActions = 0;
+       if ( state->toStateActionTable.length() > 0 )
+               toStateActions = actionTableMap.find( state->toStateActionTable );
+
+       RedActionTable *fromStateActions = 0;
+       if ( state->fromStateActionTable.length() > 0 )
+               fromStateActions = actionTableMap.find( state->fromStateActionTable );
+
+       /* EOF actions go out here only if the state has no eof target. If it has
+        * an eof target then an eof transition will be used instead. */
+       RedActionTable *eofActions = 0;
+       if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 )
+               eofActions = actionTableMap.find( state->eofActionTable );
+       
+       if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) {
+               out << "      <state_actions>";
+               if ( toStateActions != 0 )
+                       out << toStateActions->id;
+               else
+                       out << "x";
+
+               if ( fromStateActions != 0 )
+                       out << " " << fromStateActions->id;
+               else
+                       out << " x";
+
+               if ( eofActions != 0 )
+                       out << " " << eofActions->id;
+               else
+                       out << " x";
+
+               out << "</state_actions>\n";
+       }
+}
+
+void XMLCodeGen::writeStateConditions( StateAp *state )
+{
+       if ( state->stateCondList.length() > 0 ) {
+               out << "      <cond_list length=\"" << state->stateCondList.length() << "\">\n";
+               for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) {
+                       out << "        <c>";
+                       writeKey( scdi->lowKey );
+                       out << " ";
+                       writeKey( scdi->highKey );
+                       out << " ";
+                       out << scdi->condSpace->condSpaceId;
+                       out << "</c>\n";
+               }
+               out << "      </cond_list>\n";
+       }
+}
+
+void XMLCodeGen::writeStateList()
+{
+       /* Write the list of states. */
+       out << "    <state_list length=\"" << fsm->stateList.length() << "\">\n";
+       for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) {
+               out << "      <state id=\"" << st->alg.stateNum << "\"";
+               if ( st->isFinState() )
+                       out << " final=\"t\"";
+               out << ">\n";
+
+               writeStateActions( st );
+               writeEofTrans( st );
+               writeStateConditions( st );
+               writeTransList( st );
+
+               out << "      </state>\n";
+
+               if ( !st.last() )
+                       out << "\n";
+       }
+       out << "    </state_list>\n";
 }
 
 bool XMLCodeGen::writeNameInst( NameInst *nameInst )
@@ -661,69 +919,95 @@ void XMLCodeGen::writeXML()
        /* Getkey expression. */
        if ( pd->getKeyExpr != 0 ) {
                out << "  <getkey>";
-               writeInlineList( pd->getKeyExpr, 0 );
+               writeInlineList( pd->getKeyExpr );
                out << "</getkey>\n";
        }
 
        /* Access expression. */
        if ( pd->accessExpr != 0 ) {
                out << "  <access>";
-               writeInlineList( pd->accessExpr, 0 );
+               writeInlineList( pd->accessExpr );
                out << "</access>\n";
        }
 
+       /* PrePush expression. */
+       if ( pd->prePushExpr != 0 ) {
+               out << "  <prepush>";
+               writeInlineList( pd->prePushExpr );
+               out << "</prepush>\n";
+       }
+
+       /* PostPop expression. */
+       if ( pd->postPopExpr != 0 ) {
+               out << "  <postpop>";
+               writeInlineList( pd->postPopExpr );
+               out << "</postpop>\n";
+       }
+
        /*
         * Variable expressions.
         */
 
        if ( pd->pExpr != 0 ) {
                out << "  <p_expr>";
-               writeInlineList( pd->pExpr, 0 );
+               writeInlineList( pd->pExpr );
                out << "</p_expr>\n";
        }
        
        if ( pd->peExpr != 0 ) {
                out << "  <pe_expr>";
-               writeInlineList( pd->peExpr, 0 );
+               writeInlineList( pd->peExpr );
                out << "</pe_expr>\n";
        }
+
+       if ( pd->eofExpr != 0 ) {
+               out << "  <eof_expr>";
+               writeInlineList( pd->eofExpr );
+               out << "</eof_expr>\n";
+       }
        
        if ( pd->csExpr != 0 ) {
                out << "  <cs_expr>";
-               writeInlineList( pd->csExpr, 0 );
+               writeInlineList( pd->csExpr );
                out << "</cs_expr>\n";
        }
        
        if ( pd->topExpr != 0 ) {
                out << "  <top_expr>";
-               writeInlineList( pd->topExpr, 0 );
+               writeInlineList( pd->topExpr );
                out << "</top_expr>\n";
        }
        
        if ( pd->stackExpr != 0 ) {
                out << "  <stack_expr>";
-               writeInlineList( pd->stackExpr, 0 );
+               writeInlineList( pd->stackExpr );
                out << "</stack_expr>\n";
        }
        
        if ( pd->actExpr != 0 ) {
                out << "  <act_expr>";
-               writeInlineList( pd->actExpr, 0 );
+               writeInlineList( pd->actExpr );
                out << "</act_expr>\n";
        }
        
        if ( pd->tokstartExpr != 0 ) {
                out << "  <tokstart_expr>";
-               writeInlineList( pd->tokstartExpr, 0 );
+               writeInlineList( pd->tokstartExpr );
                out << "</tokstart_expr>\n";
        }
        
        if ( pd->tokendExpr != 0 ) {
                out << "  <tokend_expr>";
-               writeInlineList( pd->tokendExpr, 0 );
+               writeInlineList( pd->tokendExpr );
                out << "</tokend_expr>\n";
        }
        
+       if ( pd->dataExpr != 0 ) {
+               out << "  <data_expr>";
+               writeInlineList( pd->dataExpr );
+               out << "</data_expr>\n";
+       }
+       
        writeExports();
        
        writeMachine();
@@ -732,3 +1016,411 @@ void XMLCodeGen::writeXML()
                "</ragel_def>\n";
 }
 
+void BackendGen::makeExports()
+{
+       for ( ExportList::Iter exp = pd->exportList; exp.lte(); exp++ )
+               cgd->exportList.append( new Export( exp->name, exp->key ) );
+}
+
+void BackendGen::makeAction( Action *action )
+{
+       GenInlineList *genList = new GenInlineList;
+       makeGenInlineList( genList, action->inlineList );
+
+       cgd->newAction( curAction++, action->name, action->loc, genList );
+}
+
+
+void BackendGen::makeActionList()
+{
+       /* Determine which actions to write. */
+       int nextActionId = 0;
+       for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) {
+               if ( act->numRefs() > 0 || act->numCondRefs > 0 )
+                       act->actionId = nextActionId++;
+       }
+
+       /* Write the list. */
+       cgd->initActionList( nextActionId );
+       curAction = 0;
+
+       for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) {
+               if ( act->actionId >= 0 )
+                       makeAction( act );
+       }
+}
+
+void BackendGen::makeActionTableList()
+{
+       /* Must first order the action tables based on their id. */
+       int numTables = nextActionTableId;
+       RedActionTable **tables = new RedActionTable*[numTables];
+       for ( ActionTableMap::Iter at = actionTableMap; at.lte(); at++ )
+               tables[at->id] = at;
+
+       cgd->initActionTableList( numTables );
+       curActionTable = 0;
+
+       for ( int t = 0; t < numTables; t++ ) {
+               long length = tables[t]->key.length();
+
+               /* Collect the action table. */
+               RedAction *redAct = cgd->allActionTables + curActionTable;
+               redAct->actListId = curActionTable;
+               redAct->key.setAsNew( length );
+
+               for ( ActionTable::Iter atel = tables[t]->key; atel.lte(); atel++ ) {
+                       redAct->key[atel.pos()].key = 0;
+                       redAct->key[atel.pos()].value = cgd->allActions + 
+                                       atel->value->actionId;
+               }
+
+               /* Insert into the action table map. */
+               cgd->redFsm->actionMap.insert( redAct );
+
+               curActionTable += 1;
+       }
+
+       delete[] tables;
+}
+
+void BackendGen::makeConditions()
+{
+       if ( condData->condSpaceMap.length() > 0 ) {
+               long nextCondSpaceId = 0;
+               for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ )
+                       cs->condSpaceId = nextCondSpaceId++;
+
+               long listLength = condData->condSpaceMap.length();
+               cgd->initCondSpaceList( listLength );
+               curCondSpace = 0;
+
+               for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) {
+                       long id = cs->condSpaceId;
+                       cgd->newCondSpace( curCondSpace, id, cs->baseKey );
+                       for ( CondSet::Iter csi = cs->condSet; csi.lte(); csi++ )
+                               cgd->condSpaceItem( curCondSpace, (*csi)->actionId );
+                       curCondSpace += 1;
+               }
+       }
+}
+
+bool BackendGen::makeNameInst( std::string &res, NameInst *nameInst )
+{
+       bool written = false;
+       if ( nameInst->parent != 0 )
+               written = makeNameInst( res, nameInst->parent );
+       
+       if ( nameInst->name != 0 ) {
+               if ( written )
+                       res += '_';
+               res += nameInst->name;
+               written = true;
+       }
+
+       return written;
+}
+
+void BackendGen::makeEntryPoints()
+{
+       /* List of entry points other than start state. */
+       if ( fsm->entryPoints.length() > 0 || pd->lmRequiresErrorState ) {
+               if ( pd->lmRequiresErrorState )
+                       cgd->setForcedErrorState();
+
+               for ( EntryMap::Iter en = fsm->entryPoints; en.lte(); en++ ) {
+                       /* Get the name instantiation from nameIndex. */
+                       NameInst *nameInst = pd->nameIndex[en->key];
+                       std::string name;
+                       makeNameInst( name, nameInst );
+                       StateAp *state = en->value;
+                       cgd->addEntryPoint( strdup(name.c_str()), state->alg.stateNum );
+               }
+       }
+}
+
+void BackendGen::makeStateActions( StateAp *state )
+{
+       RedActionTable *toStateActions = 0;
+       if ( state->toStateActionTable.length() > 0 )
+               toStateActions = actionTableMap.find( state->toStateActionTable );
+
+       RedActionTable *fromStateActions = 0;
+       if ( state->fromStateActionTable.length() > 0 )
+               fromStateActions = actionTableMap.find( state->fromStateActionTable );
+
+       /* EOF actions go out here only if the state has no eof target. If it has
+        * an eof target then an eof transition will be used instead. */
+       RedActionTable *eofActions = 0;
+       if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 )
+               eofActions = actionTableMap.find( state->eofActionTable );
+       
+       if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) {
+               long to = -1;
+               if ( toStateActions != 0 )
+                       to = toStateActions->id;
+
+               long from = -1;
+               if ( fromStateActions != 0 )
+                       from = fromStateActions->id;
+
+               long eof = -1;
+               if ( eofActions != 0 )
+                       eof = eofActions->id;
+
+               cgd->setStateActions( curState, to, from, eof );
+       }
+}
+
+void BackendGen::makeEofTrans( StateAp *state )
+{
+       RedActionTable *eofActions = 0;
+       if ( state->eofActionTable.length() > 0 )
+               eofActions = actionTableMap.find( state->eofActionTable );
+       
+       /* The EOF trans is used when there is an eof target, otherwise the eof
+        * action goes into state actions. */
+       if ( state->eofTarget != 0 ) {
+               long targ = state->eofTarget->alg.stateNum;
+               long action = -1;
+               if ( eofActions != 0 )
+                       action = eofActions->id;
+
+               cgd->setEofTrans( curState, targ, action );
+       }
+}
+
+void BackendGen::makeStateConditions( StateAp *state )
+{
+       if ( state->stateCondList.length() > 0 ) {
+               long length = state->stateCondList.length();
+               cgd->initStateCondList( curState, length );
+               curStateCond = 0;
+
+               for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) {
+                       cgd->addStateCond( curState, scdi->lowKey, scdi->highKey, 
+                                       scdi->condSpace->condSpaceId );
+               }
+       }
+}
+
+void BackendGen::makeTrans( Key lowKey, Key highKey, TransAp *trans )
+{
+       /* First reduce the action. */
+       RedActionTable *actionTable = 0;
+       if ( trans->actionTable.length() > 0 )
+               actionTable = actionTableMap.find( trans->actionTable );
+
+       long targ = -1;
+       if ( trans->toState != 0 )
+               targ = trans->toState->alg.stateNum;
+
+       long action = -1;
+       if ( actionTable != 0 )
+               action = actionTable->id;
+
+       cgd->newTrans( curState, curTrans++, lowKey, highKey, targ, action );
+}
+
+void BackendGen::makeTransList( StateAp *state )
+{
+       TransListVect outList;
+
+       /* If there is only are no ranges the task is simple. */
+       if ( state->outList.length() > 0 ) {
+               /* Loop each source range. */
+               for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
+                       /* Reduce the transition. If it reduced to anything then add it. */
+                       appendTrans( outList, trans->lowKey, trans->highKey, trans );
+               }
+       }
+
+       cgd->initTransList( curState, outList.length() );
+       curTrans = 0;
+
+       for ( TransListVect::Iter tvi = outList; tvi.lte(); tvi++ )
+               makeTrans( tvi->lowKey, tvi->highKey, tvi->value );
+
+       cgd->finishTransList( curState );
+}
+
+
+void BackendGen::makeStateList()
+{
+       /* Write the list of states. */
+       long length = fsm->stateList.length();
+       cgd->initStateList( length );
+       curState = 0;
+       for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) {
+               makeStateActions( st );
+               makeEofTrans( st );
+               makeStateConditions( st );
+               makeTransList( st );
+
+               long id = st->alg.stateNum;
+               cgd->setId( curState, id );
+
+               if ( st->isFinState() )
+                       cgd->setFinal( curState );
+
+               curState += 1;
+       }
+}
+
+
+void BackendGen::makeMachine()
+{
+       cgd->createMachine();
+
+       /* Action tables. */
+       reduceActionTables();
+
+       makeActionList();
+       makeActionTableList();
+       makeConditions();
+
+       /* Start State. */
+       cgd->setStartState( fsm->startState->alg.stateNum );
+
+       /* Error state. */
+       if ( fsm->errState != 0 )
+               cgd->setErrorState( fsm->errState->alg.stateNum );
+
+       makeEntryPoints();
+       makeStateList();
+
+       cgd->closeMachine();
+}
+
+void BackendGen::close_ragel_def()
+{
+       /* Do this before distributing transitions out to singles and defaults
+        * makes life easier. */
+       cgd->redFsm->maxKey = cgd->findMaxKey();
+
+       cgd->redFsm->assignActionLocs();
+
+       /* Find the first final state (The final state with the lowest id). */
+       cgd->redFsm->findFirstFinState();
+
+       /* Call the user's callback. */
+       cgd->finishRagelDef();
+}
+
+
+void BackendGen::makeBackend()
+{
+       /* Alphabet type. */
+       cgd->setAlphType( keyOps->alphType->internalName );
+       
+       /* Getkey expression. */
+       if ( pd->getKeyExpr != 0 ) {
+               cgd->getKeyExpr = new GenInlineList;
+               makeGenInlineList( cgd->getKeyExpr, pd->getKeyExpr );
+       }
+
+       /* Access expression. */
+       if ( pd->accessExpr != 0 ) {
+               cgd->accessExpr = new GenInlineList;
+               makeGenInlineList( cgd->accessExpr, pd->accessExpr );
+       }
+
+       /* PrePush expression. */
+       if ( pd->prePushExpr != 0 ) {
+               cgd->prePushExpr = new GenInlineList;
+               makeGenInlineList( cgd->prePushExpr, pd->prePushExpr );
+       }
+
+       /* PostPop expression. */
+       if ( pd->postPopExpr != 0 ) {
+               cgd->postPopExpr = new GenInlineList;
+               makeGenInlineList( cgd->postPopExpr, pd->postPopExpr );
+       }
+
+       /*
+        * Variable expressions.
+        */
+
+       if ( pd->pExpr != 0 ) {
+               cgd->pExpr = new GenInlineList;
+               makeGenInlineList( cgd->pExpr, pd->pExpr );
+       }
+       
+       if ( pd->peExpr != 0 ) {
+               cgd->peExpr = new GenInlineList;
+               makeGenInlineList( cgd->peExpr, pd->peExpr );
+       }
+
+       if ( pd->eofExpr != 0 ) {
+               cgd->eofExpr = new GenInlineList;
+               makeGenInlineList( cgd->eofExpr, pd->eofExpr );
+       }
+       
+       if ( pd->csExpr != 0 ) {
+               cgd->csExpr = new GenInlineList;
+               makeGenInlineList( cgd->csExpr, pd->csExpr );
+       }
+       
+       if ( pd->topExpr != 0 ) {
+               cgd->topExpr = new GenInlineList;
+               makeGenInlineList( cgd->topExpr, pd->topExpr );
+       }
+       
+       if ( pd->stackExpr != 0 ) {
+               cgd->stackExpr = new GenInlineList;
+               makeGenInlineList( cgd->stackExpr, pd->stackExpr );
+       }
+       
+       if ( pd->actExpr != 0 ) {
+               cgd->actExpr = new GenInlineList;
+               makeGenInlineList( cgd->actExpr, pd->actExpr );
+       }
+       
+       if ( pd->tokstartExpr != 0 ) {
+               cgd->tokstartExpr = new GenInlineList;
+               makeGenInlineList( cgd->tokstartExpr, pd->tokstartExpr );
+       }
+       
+       if ( pd->tokendExpr != 0 ) {
+               cgd->tokendExpr = new GenInlineList;
+               makeGenInlineList( cgd->tokendExpr, pd->tokendExpr );
+       }
+       
+       if ( pd->dataExpr != 0 ) {
+               cgd->dataExpr = new GenInlineList;
+               makeGenInlineList( cgd->dataExpr, pd->dataExpr );
+       }
+       
+       makeExports();
+       makeMachine();
+
+       close_ragel_def();
+}
+
+void InputData::writeLanguage( std::ostream &out )
+{
+       out << " lang=\"";
+       switch ( hostLang->lang ) {
+               case HostLang::C:    out << "C"; break;
+               case HostLang::D:    out << "D"; break;
+               case HostLang::Java: out << "Java"; break;
+               case HostLang::Ruby: out << "Ruby"; break;
+               case HostLang::CSharp: out << "C#"; break;
+       }
+       out << "\"";
+}
+
+void InputData::writeXML( std::ostream &out )
+{
+       out << "<ragel version=\"" VERSION "\" filename=\"" << inputFileName << "\"";
+       writeLanguage( out );
+       out << ">\n";
+
+       for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
+               ParseData *pd = parser->value->pd;
+               if ( pd->instanceList.length() > 0 )
+                       pd->generateXML( *outStream );
+       }
+
+       out << "</ragel>\n";
+}