"eof" is no longer a write command.
[external/ragel.git] / ragel / xmlcodegen.cpp
index dd36167..8cbe738 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.
@@ -175,6 +175,26 @@ void XMLCodeGen::writeTransList( StateAp *state )
        out << "      </trans_list>\n";
 }
 
+void XMLCodeGen::writeEofTrans( StateAp *state )
+{
+       RedActionTable *eofActions = 0;
+       if ( state->eofActionTable.length() > 0 )
+               eofActions = actionTableMap.find( state->eofActionTable );
+       
+       /* 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 << "</eof_t>" << endl;
+       }
+}
+
 void XMLCodeGen::writeText( InlineItem *item )
 {
        if ( item->prev == 0 || item->prev->type != InlineItem::Text )
@@ -291,6 +311,11 @@ 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. */
@@ -301,17 +326,27 @@ void XMLCodeGen::writeLmSwitch( InlineItem *item )
                out << "</sub_action>\n";
        }
        
+       bool needDefault = false;
        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 << "\">";
-                       out << "<exec><get_tokend></get_tokend></exec>";
-                       writeInlineList( lmi->action->inlineList );
-                       out << "</sub_action>\n";
+               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>";
 }
 
@@ -438,8 +473,10 @@ void XMLCodeGen::writeStateActions( StateAp *state )
        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->eofActionTable.length() > 0 )
+       if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 )
                eofActions = actionTableMap.find( state->eofActionTable );
        
        if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) {
@@ -457,7 +494,9 @@ void XMLCodeGen::writeStateActions( StateAp *state )
                if ( eofActions != 0 )
                        out << " " << eofActions->id;
                else
-                       out << " x"; out << "</state_actions>\n";
+                       out << " x";
+
+               out << "</state_actions>\n";
        }
 }
 
@@ -489,6 +528,7 @@ void XMLCodeGen::writeStateList()
                out << ">\n";
 
                writeStateActions( st );
+               writeEofTrans( st );
                writeStateConditions( st );
                writeTransList( st );
 
@@ -620,6 +660,20 @@ void XMLCodeGen::writeXML()
                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.
         */
@@ -635,6 +689,12 @@ void XMLCodeGen::writeXML()
                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>";
@@ -672,6 +732,12 @@ void XMLCodeGen::writeXML()
                out << "</tokend_expr>\n";
        }
        
+       if ( pd->dataExpr != 0 ) {
+               out << "  <data_expr>";
+               writeInlineList( pd->dataExpr );
+               out << "</data_expr>\n";
+       }
+       
        writeExports();
        
        writeMachine();