Merged the FsmCodeGen, TabCodeGen and JavaTabCodeGen classes. Updated the
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Fri, 2 Feb 2007 23:30:45 +0000 (23:30 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Fri, 2 Feb 2007 23:30:45 +0000 (23:30 +0000)
runtests script to use the new filename for the java code generator.

git-svn-id: http://svn.complang.org/ragel/trunk@64 052ea7fc-9027-0410-9066-f65837a77df0

rlcodegen/fsmcodegen.h
rlgen-java/Makefile.in
rlgen-java/fsmcodegen.cpp [deleted file]
rlgen-java/fsmcodegen.h [deleted file]
rlgen-java/javacodegen.cpp
rlgen-java/javacodegen.h
rlgen-java/main.cpp
rlgen-java/rlgen-java.h [moved from rlgen-java/javagen.h with 92% similarity]
rlgen-java/tabcodegen.cpp [deleted file]
rlgen-java/tabcodegen.h [deleted file]
test/runtests

index fec052b..4207a55 100644 (file)
@@ -71,8 +71,6 @@ public:
        
 
 protected:
-       friend struct CodeGenData;
-
        string FSM_NAME();
        string START_STATE_ID();
        ostream &ACTIONS_ARRAY();
index 7ac7fb9..ed2f0e1 100644 (file)
@@ -24,9 +24,9 @@ DEFS +=
 CFLAGS += -g -Wall
 LDFLAGS +=
 
-CC_SRCS = main.cpp fsmcodegen.cpp tabcodegen.cpp javacodegen.cpp
+CC_SRCS = main.cpp javacodegen.cpp
 
-REDFSM = ../redfsm/redfsm.a
+LIBS = ../common/common.a ../redfsm/redfsm.a
 
 LIBS += @LIBS@
 PREFIX += @prefix@
@@ -46,8 +46,8 @@ include ../version.mk
 # Rules.
 all: rlgen-java
 
-rlgen-java: $(REDFSM) $(OBJS)
-       $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(REDFSM) $(LIBS)
+rlgen-java: $(LIBS) $(OBJS)
+       $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
 
 %.o: %.cpp
        @$(CXX) -M $(DEFS) $(INCS) $< > .$*.d
diff --git a/rlgen-java/fsmcodegen.cpp b/rlgen-java/fsmcodegen.cpp
deleted file mode 100644 (file)
index af9c9be..0000000
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
- *            2004 Erich Ocean <eric.ocean@ampede.com>
- *            2005 Alan West <alan@alanz.com>
- */
-
-/*  This file is part of Ragel.
- *
- *  Ragel is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- * 
- *  Ragel is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- * 
- *  You should have received a copy of the GNU General Public License
- *  along with Ragel; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- */
-
-#include "javagen.h"
-#include "redfsm.h"
-#include "gendata.h"
-#include "fsmcodegen.h"
-#include <sstream>
-#include <string>
-#include <assert.h>
-#include <iomanip>
-
-using std::ostream;
-using std::ostringstream;
-using std::string;
-using std::cerr;
-using std::endl;
-
-
-/* Init code gen with in parameters. */
-FsmCodeGen::FsmCodeGen( ostream &out )
-:
-       CodeGenData(out)
-{
-}
-
-unsigned int FsmCodeGen::arrayTypeSize( unsigned long maxVal )
-{
-       long long maxValLL = (long long) maxVal;
-       HostType *arrayType = keyOps->typeSubsumes( maxValLL );
-       assert( arrayType != 0 );
-       return arrayType->size;
-}
-
-string FsmCodeGen::ARRAY_TYPE( unsigned long maxVal )
-{
-       long long maxValLL = (long long) maxVal;
-       HostType *arrayType = keyOps->typeSubsumes( maxValLL );
-       assert( arrayType != 0 );
-
-       string ret = arrayType->data1;
-       if ( arrayType->data2 != 0 ) {
-               ret += " ";
-               ret += arrayType->data2;
-       }
-       return ret;
-}
-
-
-/* Write out the fsm name. */
-string FsmCodeGen::FSM_NAME()
-{
-       return fsmName;
-}
-
-/* Emit the offset of the start state as a decimal integer. */
-string FsmCodeGen::START_STATE_ID()
-{
-       ostringstream ret;
-       ret << redFsm->startState->id;
-       return ret.str();
-};
-
-/* Write out the array of actions. */
-std::ostream &FsmCodeGen::ACTIONS_ARRAY()
-{
-       START_ARRAY_LINE();
-       int totalActions = 0;
-       ARRAY_ITEM( 0, ++totalActions, false );
-       for ( ActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) {
-               /* Write out the length, which will never be the last character. */
-               ARRAY_ITEM( act->key.length(), ++totalActions, false );
-
-               for ( ActionTable::Iter item = act->key; item.lte(); item++ ) {
-                       ARRAY_ITEM( item->value->actionId, ++totalActions, (act.last() && item.last()) );
-               }
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-
-string FsmCodeGen::CS()
-{
-       ostringstream ret;
-       if ( curStateExpr != 0 ) { 
-               /* Emit the user supplied method of retrieving the key. */
-               ret << "(";
-               INLINE_LIST( ret, curStateExpr, 0, false );
-               ret << ")";
-       }
-       else {
-               /* Expression for retrieving the key, use simple dereference. */
-               ret << ACCESS() << "cs";
-       }
-       return ret.str();
-}
-
-string FsmCodeGen::ACCESS()
-{
-       ostringstream ret;
-       if ( accessExpr != 0 )
-               INLINE_LIST( ret, accessExpr, 0, false );
-       return ret.str();
-}
-
-string FsmCodeGen::GET_WIDE_KEY()
-{
-       if ( redFsm->anyConditions() ) 
-               return "_widec";
-       else
-               return GET_KEY();
-}
-
-string FsmCodeGen::GET_WIDE_KEY( RedStateAp *state )
-{
-       if ( state->stateCondList.length() > 0 )
-               return "_widec";
-       else
-               return GET_KEY();
-}
-
-string FsmCodeGen::GET_KEY()
-{
-       ostringstream ret;
-       if ( getKeyExpr != 0 ) { 
-               /* Emit the user supplied method of retrieving the key. */
-               ret << "(";
-               INLINE_LIST( ret, getKeyExpr, 0, false );
-               ret << ")";
-       }
-       else {
-               /* Expression for retrieving the key, use simple dereference. */
-               ret << "(*" << P() << ")";
-       }
-       return ret.str();
-}
-
-/* Write out level number of tabs. Makes the nested binary search nice
- * looking. */
-string FsmCodeGen::TABS( int level )
-{
-       string result;
-       while ( level-- > 0 )
-               result += "\t";
-       return result;
-}
-
-int FsmCodeGen::KEY( Key key )
-{
-       return key.getVal();
-}
-
-void FsmCodeGen::EXEC( ostream &ret, InlineItem *item, int targState, int inFinish )
-{
-       /* The parser gives fexec two children. The double brackets are for D
-        * code. If the inline list is a single word it will get interpreted as a
-        * C-style cast by the D compiler. */
-       ret << "{" << P() << " = ((";
-       INLINE_LIST( ret, item->children, targState, inFinish );
-       ret << "))-1;}";
-}
-
-void FsmCodeGen::EXECTE( ostream &ret, InlineItem *item, int targState, int inFinish )
-{
-       /* Tokend version of exec. */
-
-       /* The parser gives fexec two children. The double brackets are for D
-        * code. If the inline list is a single word it will get interpreted as a
-        * C-style cast by the D compiler. */
-       ret << "{" << TOKEND() << " = ((";
-       INLINE_LIST( ret, item->children, targState, inFinish );
-       ret << "));}";
-}
-
-
-void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, 
-               int targState, int inFinish )
-{
-       ret << 
-               "       switch( act ) {\n";
-
-       /* If the switch handles error then we also forced the error state. It
-        * will exist. */
-       if ( item->handlesError ) {
-               ret << "        case 0: " << TOKEND() << " = " << TOKSTART() << "; ";
-               GOTO( ret, redFsm->errState->id, inFinish );
-               ret << "\n";
-       }
-
-       for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) {
-               /* Write the case label, the action and the case break. */
-               ret << "        case " << lma->lmId << ":\n";
-
-               /* Write the block and close it off. */
-               ret << "        {";
-               INLINE_LIST( ret, lma->children, targState, inFinish );
-               ret << "}\n";
-
-               ret << "        break;\n";
-       }
-       /* Default required for D code. */
-       ret << 
-               "       default: break;\n"
-               "       }\n"
-               "\t";
-}
-
-void FsmCodeGen::SET_ACT( ostream &ret, InlineItem *item )
-{
-       ret << ACT() << " = " << item->lmId << ";";
-}
-
-void FsmCodeGen::SET_TOKEND( ostream &ret, InlineItem *item )
-{
-       /* The tokend action sets tokend. */
-       ret << TOKEND() << " = " << P();
-       if ( item->offset != 0 ) 
-               out << "+" << item->offset;
-       out << ";";
-}
-
-void FsmCodeGen::GET_TOKEND( ostream &ret, InlineItem *item )
-{
-       ret << TOKEND();
-}
-
-void FsmCodeGen::INIT_TOKSTART( ostream &ret, InlineItem *item )
-{
-       ret << TOKSTART() << " = " << NULL_ITEM() << ";";
-}
-
-void FsmCodeGen::INIT_ACT( ostream &ret, InlineItem *item )
-{
-       ret << ACT() << " = 0;";
-}
-
-void FsmCodeGen::SET_TOKSTART( ostream &ret, InlineItem *item )
-{
-       ret << TOKSTART() << " = " << P() << ";";
-}
-
-void FsmCodeGen::SUB_ACTION( ostream &ret, InlineItem *item, 
-               int targState, bool inFinish )
-{
-       if ( item->children->length() > 0 ) {
-               /* Write the block and close it off. */
-               ret << "{";
-               INLINE_LIST( ret, item->children, targState, inFinish );
-               ret << "}";
-       }
-}
-
-
-/* Write out an inline tree structure. Walks the list and possibly calls out
- * to virtual functions than handle language specific items in the tree. */
-void FsmCodeGen::INLINE_LIST( ostream &ret, InlineList *inlineList, 
-               int targState, bool inFinish )
-{
-       for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) {
-               switch ( item->type ) {
-               case InlineItem::Text:
-                       ret << item->data;
-                       break;
-               case InlineItem::Goto:
-                       GOTO( ret, item->targState->id, inFinish );
-                       break;
-               case InlineItem::Call:
-                       CALL( ret, item->targState->id, targState, inFinish );
-                       break;
-               case InlineItem::Next:
-                       NEXT( ret, item->targState->id, inFinish );
-                       break;
-               case InlineItem::Ret:
-                       RET( ret, inFinish );
-                       break;
-               case InlineItem::PChar:
-                       ret << P();
-                       break;
-               case InlineItem::Char:
-                       ret << GET_KEY();
-                       break;
-               case InlineItem::Hold:
-                       ret << P() << "--;";
-                       break;
-               case InlineItem::Exec:
-                       EXEC( ret, item, targState, inFinish );
-                       break;
-               case InlineItem::HoldTE:
-                       ret << TOKEND() << "--;";
-                       break;
-               case InlineItem::ExecTE:
-                       EXECTE( ret, item, targState, inFinish );
-                       break;
-               case InlineItem::Curs:
-                       CURS( ret, inFinish );
-                       break;
-               case InlineItem::Targs:
-                       TARGS( ret, inFinish, targState );
-                       break;
-               case InlineItem::Entry:
-                       ret << item->targState->id;
-                       break;
-               case InlineItem::GotoExpr:
-                       GOTO_EXPR( ret, item, inFinish );
-                       break;
-               case InlineItem::CallExpr:
-                       CALL_EXPR( ret, item, targState, inFinish );
-                       break;
-               case InlineItem::NextExpr:
-                       NEXT_EXPR( ret, item, inFinish );
-                       break;
-               case InlineItem::LmSwitch:
-                       LM_SWITCH( ret, item, targState, inFinish );
-                       break;
-               case InlineItem::LmSetActId:
-                       SET_ACT( ret, item );
-                       break;
-               case InlineItem::LmSetTokEnd:
-                       SET_TOKEND( ret, item );
-                       break;
-               case InlineItem::LmGetTokEnd:
-                       GET_TOKEND( ret, item );
-                       break;
-               case InlineItem::LmInitTokStart:
-                       INIT_TOKSTART( ret, item );
-                       break;
-               case InlineItem::LmInitAct:
-                       INIT_ACT( ret, item );
-                       break;
-               case InlineItem::LmSetTokStart:
-                       SET_TOKSTART( ret, item );
-                       break;
-               case InlineItem::SubAction:
-                       SUB_ACTION( ret, item, targState, inFinish );
-                       break;
-               case InlineItem::Break:
-                       BREAK( ret, targState );
-                       break;
-               }
-       }
-}
-/* Write out paths in line directives. Escapes any special characters. */
-string FsmCodeGen::LDIR_PATH( char *path )
-{
-       ostringstream ret;
-       for ( char *pc = path; *pc != 0; pc++ ) {
-               if ( *pc == '\\' )
-                       ret << "\\\\";
-               else
-                       ret << *pc;
-       }
-       return ret.str();
-}
-
-void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState, bool inFinish )
-{
-       /* Write the preprocessor line info for going into the source file. */
-       lineDirective( ret, sourceFileName, action->loc.line );
-
-       /* Write the block and close it off. */
-       ret << "\t{";
-       INLINE_LIST( ret, action->inlineList, targState, inFinish );
-       ret << "}\n";
-}
-
-void FsmCodeGen::CONDITION( ostream &ret, Action *condition )
-{
-       ret << "\n";
-       lineDirective( ret, sourceFileName, condition->loc.line );
-       INLINE_LIST( ret, condition->inlineList, 0, false );
-}
-
-string FsmCodeGen::ERROR_STATE()
-{
-       ostringstream ret;
-       if ( redFsm->errState != 0 )
-               ret << redFsm->errState->id;
-       else
-               ret << "-1";
-       return ret.str();
-}
-
-string FsmCodeGen::FIRST_FINAL_STATE()
-{
-       ostringstream ret;
-       if ( redFsm->firstFinState != 0 )
-               ret << redFsm->firstFinState->id;
-       else
-               ret << redFsm->nextStateId;
-       return ret.str();
-}
-
-void FsmCodeGen::writeOutInit()
-{
-       out << "        {\n";
-       out << "\t" << CS() << " = " << START() << ";\n";
-       
-       /* If there are any calls, then the stack top needs initialization. */
-       if ( redFsm->anyActionCalls() || redFsm->anyActionRets() )
-               out << "\t" << TOP() << " = 0;\n";
-
-       if ( hasLongestMatch ) {
-               out << 
-                       "       " << TOKSTART() << " = " << NULL_ITEM() << ";\n"
-                       "       " << TOKEND() << " = " << NULL_ITEM() << ";\n"
-                       "       " << ACT() << " = 0;\n";
-       }
-       out << "        }\n";
-}
-
-string FsmCodeGen::DATA_PREFIX()
-{
-       if ( dataPrefix )
-               return FSM_NAME() + "_";
-       return "";
-}
-
-/* Emit the alphabet data type. */
-string FsmCodeGen::ALPH_TYPE()
-{
-       string ret = keyOps->alphType->data1;
-       if ( keyOps->alphType->data2 != 0 ) {
-               ret += " ";
-               ret += + keyOps->alphType->data2;
-       }
-       return ret;
-}
-
-/* Emit the alphabet data type. */
-string FsmCodeGen::WIDE_ALPH_TYPE()
-{
-       string ret;
-       if ( redFsm->maxKey <= keyOps->maxKey )
-               ret = ALPH_TYPE();
-       else {
-               long long maxKeyVal = redFsm->maxKey.getLongLong();
-               HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal );
-               assert( wideType != 0 );
-
-               ret = wideType->data1;
-               if ( wideType->data2 != 0 ) {
-                       ret += " ";
-                       ret += wideType->data2;
-               }
-       }
-       return ret;
-}
-
-/* 
- * Java Specific
- */
-
-string JavaCodeGen::PTR_CONST()
-{
-       /* Not used in Java code. */
-       assert( false );
-       return "final";
-}
-
-std::ostream &JavaCodeGen::OPEN_ARRAY( string type, string name )
-{
-       array_type = type;
-       array_name = name;
-       out << "private static final String packed" << name << " = \n";
-       return out;
-}
-
-std::ostream &JavaCodeGen::START_ARRAY_LINE()
-{
-       out << "\t\"";
-       return out;
-}
-
-std::ostream &JavaCodeGen::ARRAY_ITEM( int item, int count, bool last )
-{
-       // 0 codes in 2 bytes in the Java class file and is common,
-       // so we increment all values by one when packing
-       item++;
-
-       std::ios_base::fmtflags originalFlags=out.flags();
-       if ( item < 0x80 )
-       {
-               out << std::oct << "\\" << item;
-       }
-       else
-       {
-               out << std::hex << "\\u" << std::setfill('0') << std::setw(4) << item;
-       }
-       out.flags(originalFlags);
-       
-       if ( !last )
-       {
-               if ( count % IALL == 0 )
-               {
-                       END_ARRAY_LINE();
-                       START_ARRAY_LINE();
-               }
-       }
-       return out;
-}
-
-std::ostream &JavaCodeGen::END_ARRAY_LINE()
-{
-       out << "\" +\n";
-       return out;
-}
-
-std::ostream &JavaCodeGen::CLOSE_ARRAY()
-{
-       out << "\t\"\";\n";
-       out << "static final " << array_type << "[] " << array_name 
-               << " = unpack_" << array_type << "(packed" << array_name << ");\n";
-       return out;
-}
-
-std::ostream &JavaCodeGen::STATIC_VAR( string type, string name )
-{
-       out << "static final " << type << " " << name;
-       return out;
-}
-
-string JavaCodeGen::UINT( )
-{
-       /* Not used. */
-       assert( false );
-       return "long";
-}
-
-string JavaCodeGen::ARR_OFF( string ptr, string offset )
-{
-       return ptr + " + " + offset;
-}
-
-string JavaCodeGen::CAST( string type )
-{
-       return "(" + type + ")";
-}
-
-string JavaCodeGen::NULL_ITEM()
-{
-       /* In java we use integers instead of pointers. */
-       return "-1";
-}
-
-string JavaCodeGen::POINTER()
-{
-       /* Not used. */
-       assert( false );
-       return " *";
-}
-
-std::ostream &JavaCodeGen::SWITCH_DEFAULT()
-{
-       return out;
-}
-
-string JavaCodeGen::GET_KEY()
-{
-       ostringstream ret;
-       if ( getKeyExpr != 0 ) { 
-               /* Emit the user supplied method of retrieving the key. */
-               ret << "(";
-               INLINE_LIST( ret, getKeyExpr, 0, false );
-               ret << ")";
-       }
-       else {
-               /* Expression for retrieving the key, use simple dereference. */
-               ret << "data[" << P() << "]";
-       }
-       return ret.str();
-}
-
-string JavaCodeGen::CTRL_FLOW()
-{
-       return "if (true) ";
-}
-
-/* Generate the code for an fsm. Assumes parseData is set up properly. Called
- * by parser code. */
-void FsmCodeGen::prepareMachine()
-{
-       if ( hasBeenPrepared )
-               return;
-       hasBeenPrepared = true;
-       
-       /* Do this before distributing transitions out to singles and defaults
-        * makes life easier. */
-       redFsm->maxKey = findMaxKey();
-
-       redFsm->assignActionLocs();
-
-       /* Order the states. */
-       redFsm->depthFirstOrdering();
-
-       if ( codeStyle == GenGoto || codeStyle == GenFGoto || 
-                       codeStyle == GenIpGoto || codeStyle == GenSplit )
-       {
-               /* For goto driven machines we can keep the original depth
-                * first ordering because it's ok if the state ids are not
-                * sequential. Split the the ids by final state status. */
-               redFsm->sortStateIdsByFinal();
-       }
-       else {
-               /* For table driven machines the location of the state is used to
-                * identify it so the states must be sorted by their final ids.
-                * Though having a deterministic ordering is important,
-                * specifically preserving the depth first ordering is not because
-                * states are stored in tables. */
-               redFsm->sortStatesByFinal();
-               redFsm->sequentialStateIds();
-       }
-
-       /* Find the first final state. This is the final state with the lowest
-        * id.  */
-       redFsm->findFirstFinState();
-
-       /* Choose default transitions and the single transition. */
-       redFsm->chooseDefaultSpan();
-               
-       /* Maybe do flat expand, otherwise choose single. */
-       if ( codeStyle == GenFlat || codeStyle == GenFFlat )
-               redFsm->makeFlat();
-       else
-               redFsm->chooseSingle();
-
-       /* If any errors have occured in the input file then don't write anything. */
-       if ( gblErrorCount > 0 )
-               return;
-       
-       if ( codeStyle == GenSplit )
-               redFsm->partitionFsm( numSplitPartitions );
-
-       if ( codeStyle == GenIpGoto || codeStyle == GenSplit )
-               redFsm->setInTrans();
-
-       /* Anlayze Machine will find the final action reference counts, among
-        * other things. We will use these in reporting the usage
-        * of fsm directives in action code. */
-       analyzeMachine();
-
-       /* Determine if we should use indicies. */
-       calcIndexSize();
-}
-
-void FsmCodeGen::finishRagelDef()
-{
-       assert( outputFormat == OutCode );
-       prepareMachine();
-}
-
-void FsmCodeGen::writeStatement( InputLoc &loc, int nargs, char **args )
-{
-       if ( outputFormat == OutCode ) {
-               /* Force a newline. */
-               out << "\n";
-               genLineDirective( out );
-
-               if ( strcmp( args[0], "data" ) == 0 ) {
-                       for ( int i = 1; i < nargs; i++ ) {
-                               if ( strcmp( args[i], "noerror" ) == 0 )
-                                       writeErr = false;
-                               else if ( strcmp( args[i], "noprefix" ) == 0 )
-                                       dataPrefix = false;
-                               else if ( strcmp( args[i], "nofinal" ) == 0 )
-                                       writeFirstFinal = false;
-                               else {
-                                       source_warning(loc) << "unrecognized write option \"" << 
-                                                       args[i] << "\"" << endl;
-                               }
-                       }
-                       writeOutData();
-               }
-               else if ( strcmp( args[0], "init" ) == 0 ) {
-                       for ( int i = 1; i < nargs; i++ ) {
-                               source_warning(loc) << "unrecognized write option \"" << 
-                                               args[i] << "\"" << endl;
-                       }
-                       writeOutInit();
-               }
-               else if ( strcmp( args[0], "exec" ) == 0 ) {
-                       for ( int i = 1; i < nargs; i++ ) {
-                               if ( strcmp( args[i], "noend" ) == 0 )
-                                       hasEnd = false;
-                               else {
-                                       source_warning(loc) << "unrecognized write option \"" << 
-                                                       args[i] << "\"" << endl;
-                               }
-                       }
-
-                       /* Must set labels immediately before writing because we may depend
-                        * on the noend write option. */
-                       setLabelsNeeded();
-                       writeOutExec();
-               }
-               else if ( strcmp( args[0], "eof" ) == 0 ) {
-                       for ( int i = 1; i < nargs; i++ ) {
-                               source_warning(loc) << "unrecognized write option \"" << 
-                                               args[i] << "\"" << endl;
-                       }
-                       writeOutEOF();
-               }
-               else {
-                       /* EMIT An error here. */
-               }
-       }
-}
-
-ostream &FsmCodeGen::source_warning( const InputLoc &loc )
-{
-       cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: ";
-       return cerr;
-}
-
-ostream &FsmCodeGen::source_error( const InputLoc &loc )
-{
-       gblErrorCount += 1;
-       assert( sourceFileName != 0 );
-       cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": ";
-       return cerr;
-}
-
-void genLineDirective( ostream &out )
-{
-       assert( outputFormat == OutCode );
-       std::streambuf *sbuf = out.rdbuf();
-       output_filter *filter = static_cast<output_filter*>(sbuf);
-       lineDirective( out, filter->fileName, filter->line + 1 );
-}
-
diff --git a/rlgen-java/fsmcodegen.h b/rlgen-java/fsmcodegen.h
deleted file mode 100644 (file)
index eb0a4ed..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
- *            2004 Erich Ocean <eric.ocean@ampede.com>
- *            2005 Alan West <alan@alanz.com>
- */
-
-/*  This file is part of Ragel.
- *
- *  Ragel is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- * 
- *  Ragel is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- * 
- *  You should have received a copy of the GNU General Public License
- *  along with Ragel; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- */
-
-#ifndef _FSMCODEGEN_H
-#define _FSMCODEGEN_H
-
-#include <iostream>
-#include <string>
-#include <stdio.h>
-#include "common.h"
-#include "gendata.h"
-
-using std::string;
-using std::ostream;
-
-/* Integer array line length. */
-#define IALL 8
-
-/* Forwards. */
-struct RedFsmAp;
-struct RedStateAp;
-struct CodeGenData;
-struct Action;
-struct NameInst;
-struct InlineItem;
-struct InlineList;
-struct RedAction;
-struct LongestMatch;
-struct LongestMatchPart;
-
-inline string itoa( int i )
-{
-       char buf[16];
-       sprintf( buf, "%i", i );
-       return buf;
-}
-
-/*
- * class FsmCodeGen
- */
-class FsmCodeGen : public CodeGenData
-{
-public:
-       FsmCodeGen( ostream &out );
-       virtual ~FsmCodeGen() {}
-
-       virtual void writeOutData() = 0;
-       virtual void writeOutInit();
-       virtual void writeOutExec() = 0;
-       virtual void writeOutEOF() = 0;
-       
-
-protected:
-       friend struct CodeGenData;
-
-       string FSM_NAME();
-       string START_STATE_ID();
-       ostream &ACTIONS_ARRAY();
-       string GET_WIDE_KEY();
-       string GET_WIDE_KEY( RedStateAp *state );
-       string TABS( int level );
-       int KEY( Key key );
-       string LDIR_PATH( char *path );
-       void ACTION( ostream &ret, Action *action, int targState, bool inFinish );
-       void CONDITION( ostream &ret, Action *condition );
-       string ALPH_TYPE();
-       string WIDE_ALPH_TYPE();
-       string ARRAY_TYPE( unsigned long maxVal );
-
-       virtual string ARR_OFF( string ptr, string offset ) = 0;
-       virtual string CAST( string type ) = 0;
-       virtual string UINT() = 0;
-       virtual string NULL_ITEM() = 0;
-       virtual string POINTER() = 0;
-       virtual string GET_KEY();
-       virtual ostream &SWITCH_DEFAULT() = 0;
-
-       string P() { return "p"; }
-       string PE() { return "pe"; }
-
-       string ACCESS();
-       string CS();
-       string STACK() { return ACCESS() + "stack"; }
-       string TOP() { return ACCESS() + "top"; }
-       string TOKSTART() { return ACCESS() + "tokstart"; }
-       string TOKEND() { return ACCESS() + "tokend"; }
-       string ACT() { return ACCESS() + "act"; }
-
-       string DATA_PREFIX();
-       string PM() { return "_" + DATA_PREFIX() + "partition_map"; }
-       string C() { return "_" + DATA_PREFIX() + "cond_spaces"; }
-       string CK() { return "_" + DATA_PREFIX() + "cond_keys"; }
-       string K() { return "_" + DATA_PREFIX() + "trans_keys"; }
-       string I() { return "_" + DATA_PREFIX() + "indicies"; }
-       string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; }
-       string KO() { return "_" + DATA_PREFIX() + "key_offsets"; }
-       string IO() { return "_" + DATA_PREFIX() + "index_offsets"; }
-       string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; }
-       string SL() { return "_" + DATA_PREFIX() + "single_lengths"; }
-       string RL() { return "_" + DATA_PREFIX() + "range_lengths"; }
-       string A() { return "_" + DATA_PREFIX() + "actions"; }
-       string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; }
-       string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; }
-       string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; }
-       string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; }
-       string EA() { return "_" + DATA_PREFIX() + "eof_actions"; }
-       string SP() { return "_" + DATA_PREFIX() + "key_spans"; }
-       string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; }
-       string START() { return DATA_PREFIX() + "start"; }
-       string ERROR() { return DATA_PREFIX() + "error"; }
-       string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; }
-       string CTXDATA() { return DATA_PREFIX() + "ctxdata"; }
-
-       void INLINE_LIST( ostream &ret, InlineList *inlineList, int targState, bool inFinish );
-       virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ) = 0;
-       virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0;
-       virtual void NEXT( ostream &ret, int nextDest, bool inFinish ) = 0;
-       virtual void GOTO_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish ) = 0;
-       virtual void NEXT_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish ) = 0;
-       virtual void CALL_EXPR( ostream &ret, InlineItem *ilItem, 
-                       int targState, bool inFinish ) = 0;
-       virtual void RET( ostream &ret, bool inFinish ) = 0;
-       virtual void BREAK( ostream &ret, int targState ) = 0;
-       virtual void CURS( ostream &ret, bool inFinish ) = 0;
-       virtual void TARGS( ostream &ret, bool inFinish, int targState ) = 0;
-       void EXEC( ostream &ret, InlineItem *item, int targState, int inFinish );
-       void EXECTE( ostream &ret, InlineItem *item, int targState, int inFinish );
-       void LM_SWITCH( ostream &ret, InlineItem *item, int targState, int inFinish );
-       void SET_ACT( ostream &ret, InlineItem *item );
-       void INIT_TOKSTART( ostream &ret, InlineItem *item );
-       void INIT_ACT( ostream &ret, InlineItem *item );
-       void SET_TOKSTART( ostream &ret, InlineItem *item );
-       void SET_TOKEND( ostream &ret, InlineItem *item );
-       void GET_TOKEND( ostream &ret, InlineItem *item );
-       void SUB_ACTION( ostream &ret, InlineItem *item, 
-                       int targState, bool inFinish );
-
-       string ERROR_STATE();
-       string FIRST_FINAL_STATE();
-
-       virtual string PTR_CONST() = 0;
-       virtual ostream &OPEN_ARRAY( string type, string name ) = 0;
-       virtual ostream &START_ARRAY_LINE() = 0;
-       virtual ostream &ARRAY_ITEM( int item, int count, bool last ) = 0;
-       virtual ostream &END_ARRAY_LINE() = 0;
-       virtual ostream &CLOSE_ARRAY() = 0;
-       virtual ostream &STATIC_VAR( string type, string name ) = 0;
-
-       virtual string CTRL_FLOW() = 0;
-
-       ostream &source_warning(const InputLoc &loc);
-       ostream &source_error(const InputLoc &loc);
-
-       unsigned int arrayTypeSize( unsigned long maxVal );
-
-       /* Set up labelNeeded flag for each state. Differs for each goto style so
-        * is virtual. */
-       virtual void setLabelsNeeded() {}
-
-       bool outLabelUsed;
-       bool againLabelUsed;
-
-       bool useIndicies;
-
-public:
-       void prepareMachine();
-
-       virtual void finishRagelDef();
-       virtual void writeStatement( InputLoc &loc, int nargs, char **args );
-
-       /* Determine if we should use indicies. */
-       virtual void calcIndexSize() {}
-};
-
-class JavaCodeGen : virtual public FsmCodeGen
-{
-private:
-       string array_type;
-       string array_name;
-
-public:
-       JavaCodeGen( ostream &out ) : FsmCodeGen(out) {}
-
-       virtual string NULL_ITEM();
-       virtual string POINTER();
-       virtual ostream &SWITCH_DEFAULT();
-       virtual ostream &OPEN_ARRAY( string type, string name );
-       virtual ostream &START_ARRAY_LINE();
-       virtual ostream &ARRAY_ITEM( int item, int count, bool last );
-       virtual ostream &END_ARRAY_LINE();
-       virtual ostream &CLOSE_ARRAY();
-       virtual ostream &STATIC_VAR( string type, string name );
-       virtual string ARR_OFF( string ptr, string offset );
-       virtual string CAST( string type );
-       virtual string UINT();
-       virtual string PTR_CONST();
-       virtual string GET_KEY();
-       virtual string CTRL_FLOW();
-};
-
-#endif /* _FSMCODEGEN_H */
index 4275743..8929784 100644 (file)
@@ -1,5 +1,6 @@
 /*
- *  Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2006-2007 Adrian Thurston <thurston@cs.queensu.ca>
+ *            2007 Colin Fleming <colin.fleming@caverock.com>
  */
 
 /*  This file is part of Ragel.
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 
+#include "rlgen-java.h"
 #include "javacodegen.h"
-#include "javagen.h"
-#include "tabcodegen.h"
 #include "redfsm.h"
 #include "gendata.h"
+#include <iomanip>
+#include <sstream>
+
+/* Integer array line length. */
+#define IALL 8
+
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::cerr;
+using std::endl;
+
+void genLineDirective( ostream &out )
+{
+       assert( outputFormat == OutCode );
+       std::streambuf *sbuf = out.rdbuf();
+       output_filter *filter = static_cast<output_filter*>(sbuf);
+       lineDirective( out, filter->fileName, filter->line + 1 );
+}
+
 
 void JavaTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish )
 {
@@ -62,6 +82,169 @@ void JavaTabCodeGen::BREAK( ostream &ret, int targState )
        ret << CTRL_FLOW() << "break _resume;";
 }
 
+void JavaTabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish )
+{
+       ret << CS() << " = " << nextDest << ";";
+}
+
+void JavaTabCodeGen::NEXT_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish )
+{
+       ret << CS() << " = (";
+       INLINE_LIST( ret, ilItem->children, 0, inFinish );
+       ret << ");";
+}
+
+void JavaTabCodeGen::EXEC( ostream &ret, InlineItem *item, int targState, int inFinish )
+{
+       /* The parser gives fexec two children. The double brackets are for D
+        * code. If the inline list is a single word it will get interpreted as a
+        * C-style cast by the D compiler. */
+       ret << "{" << P() << " = ((";
+       INLINE_LIST( ret, item->children, targState, inFinish );
+       ret << "))-1;}";
+}
+
+void JavaTabCodeGen::EXECTE( ostream &ret, InlineItem *item, int targState, int inFinish )
+{
+       /* Tokend version of exec. */
+
+       /* The parser gives fexec two children. The double brackets are for D
+        * code. If the inline list is a single word it will get interpreted as a
+        * C-style cast by the D compiler. */
+       ret << "{" << TOKEND() << " = ((";
+       INLINE_LIST( ret, item->children, targState, inFinish );
+       ret << "));}";
+}
+
+/* Write out an inline tree structure. Walks the list and possibly calls out
+ * to virtual functions than handle language specific items in the tree. */
+void JavaTabCodeGen::INLINE_LIST( ostream &ret, InlineList *inlineList, 
+               int targState, bool inFinish )
+{
+       for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) {
+               switch ( item->type ) {
+               case InlineItem::Text:
+                       ret << item->data;
+                       break;
+               case InlineItem::Goto:
+                       GOTO( ret, item->targState->id, inFinish );
+                       break;
+               case InlineItem::Call:
+                       CALL( ret, item->targState->id, targState, inFinish );
+                       break;
+               case InlineItem::Next:
+                       NEXT( ret, item->targState->id, inFinish );
+                       break;
+               case InlineItem::Ret:
+                       RET( ret, inFinish );
+                       break;
+               case InlineItem::PChar:
+                       ret << P();
+                       break;
+               case InlineItem::Char:
+                       ret << GET_KEY();
+                       break;
+               case InlineItem::Hold:
+                       ret << P() << "--;";
+                       break;
+               case InlineItem::Exec:
+                       EXEC( ret, item, targState, inFinish );
+                       break;
+               case InlineItem::HoldTE:
+                       ret << TOKEND() << "--;";
+                       break;
+               case InlineItem::ExecTE:
+                       EXECTE( ret, item, targState, inFinish );
+                       break;
+               case InlineItem::Curs:
+                       ret << "(_ps)";
+                       break;
+               case InlineItem::Targs:
+                       ret << "(" << CS() << ")";
+                       break;
+               case InlineItem::Entry:
+                       ret << item->targState->id;
+                       break;
+               case InlineItem::GotoExpr:
+                       GOTO_EXPR( ret, item, inFinish );
+                       break;
+               case InlineItem::CallExpr:
+                       CALL_EXPR( ret, item, targState, inFinish );
+                       break;
+               case InlineItem::NextExpr:
+                       NEXT_EXPR( ret, item, inFinish );
+                       break;
+               case InlineItem::LmSwitch:
+                       LM_SWITCH( ret, item, targState, inFinish );
+                       break;
+               case InlineItem::LmSetActId:
+                       SET_ACT( ret, item );
+                       break;
+               case InlineItem::LmSetTokEnd:
+                       SET_TOKEND( ret, item );
+                       break;
+               case InlineItem::LmGetTokEnd:
+                       GET_TOKEND( ret, item );
+                       break;
+               case InlineItem::LmInitTokStart:
+                       INIT_TOKSTART( ret, item );
+                       break;
+               case InlineItem::LmInitAct:
+                       INIT_ACT( ret, item );
+                       break;
+               case InlineItem::LmSetTokStart:
+                       SET_TOKSTART( ret, item );
+                       break;
+               case InlineItem::SubAction:
+                       SUB_ACTION( ret, item, targState, inFinish );
+                       break;
+               case InlineItem::Break:
+                       BREAK( ret, targState );
+                       break;
+               }
+       }
+}
+
+string JavaTabCodeGen::DATA_PREFIX()
+{
+       if ( dataPrefix )
+               return FSM_NAME() + "_";
+       return "";
+}
+
+/* Emit the alphabet data type. */
+string JavaTabCodeGen::ALPH_TYPE()
+{
+       string ret = keyOps->alphType->data1;
+       if ( keyOps->alphType->data2 != 0 ) {
+               ret += " ";
+               ret += + keyOps->alphType->data2;
+       }
+       return ret;
+}
+
+/* Emit the alphabet data type. */
+string JavaTabCodeGen::WIDE_ALPH_TYPE()
+{
+       string ret;
+       if ( redFsm->maxKey <= keyOps->maxKey )
+               ret = ALPH_TYPE();
+       else {
+               long long maxKeyVal = redFsm->maxKey.getLongLong();
+               HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal );
+               assert( wideType != 0 );
+
+               ret = wideType->data1;
+               if ( wideType->data2 != 0 ) {
+                       ret += " ";
+                       ret += wideType->data2;
+               }
+       }
+       return ret;
+}
+
+
+
 void JavaTabCodeGen::COND_TRANSLATE()
 {
        out << 
@@ -168,10 +351,459 @@ void JavaTabCodeGen::LOCATE_TRANS()
                "\n";
 }
 
+/* Determine if we should use indicies or not. */
+void JavaTabCodeGen::calcIndexSize()
+{
+       int sizeWithInds = 0, sizeWithoutInds = 0;
+
+       /* Calculate cost of using with indicies. */
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               int totalIndex = st->outSingle.length() + st->outRange.length() + 
+                               (st->defTrans == 0 ? 0 : 1);
+               sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex;
+       }
+       sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length();
+       if ( redFsm->anyActions() )
+               sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length();
+
+       /* Calculate the cost of not using indicies. */
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               int totalIndex = st->outSingle.length() + st->outRange.length() + 
+                               (st->defTrans == 0 ? 0 : 1);
+               sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex;
+               if ( redFsm->anyActions() )
+                       sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex;
+       }
+
+       /* If using indicies reduces the size, use them. */
+       useIndicies = sizeWithInds < sizeWithoutInds;
+}
+
+int JavaTabCodeGen::TO_STATE_ACTION( RedStateAp *state )
+{
+       int act = 0;
+       if ( state->toStateAction != 0 )
+               act = state->toStateAction->location+1;
+       return act;
+}
+
+int JavaTabCodeGen::FROM_STATE_ACTION( RedStateAp *state )
+{
+       int act = 0;
+       if ( state->fromStateAction != 0 )
+               act = state->fromStateAction->location+1;
+       return act;
+}
+
+int JavaTabCodeGen::EOF_ACTION( RedStateAp *state )
+{
+       int act = 0;
+       if ( state->eofAction != 0 )
+               act = state->eofAction->location+1;
+       return act;
+}
+
+
+int JavaTabCodeGen::TRANS_ACTION( RedTransAp *trans )
+{
+       /* If there are actions, emit them. Otherwise emit zero. */
+       int act = 0;
+       if ( trans->action != 0 )
+               act = trans->action->location+1;
+       return act;
+}
+
+std::ostream &JavaTabCodeGen::TO_STATE_ACTION_SWITCH()
+{
+       /* Walk the list of functions, printing the cases. */
+       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
+               /* Write out referenced actions. */
+               if ( act->numToStateRefs > 0 ) {
+                       /* Write the case label, the action and the case break. */
+                       out << "\tcase " << act->actionId << ":\n";
+                       ACTION( out, act, 0, false );
+                       out << "\tbreak;\n";
+               }
+       }
+
+       genLineDirective( out );
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::FROM_STATE_ACTION_SWITCH()
+{
+       /* Walk the list of functions, printing the cases. */
+       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
+               /* Write out referenced actions. */
+               if ( act->numFromStateRefs > 0 ) {
+                       /* Write the case label, the action and the case break. */
+                       out << "\tcase " << act->actionId << ":\n";
+                       ACTION( out, act, 0, false );
+                       out << "\tbreak;\n";
+               }
+       }
+
+       genLineDirective( out );
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::EOF_ACTION_SWITCH()
+{
+       /* Walk the list of functions, printing the cases. */
+       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
+               /* Write out referenced actions. */
+               if ( act->numEofRefs > 0 ) {
+                       /* Write the case label, the action and the case break. */
+                       out << "\tcase " << act->actionId << ":\n";
+                       ACTION( out, act, 0, true );
+                       out << "\tbreak;\n";
+               }
+       }
+
+       genLineDirective( out );
+       return out;
+}
+
+
+std::ostream &JavaTabCodeGen::ACTION_SWITCH()
+{
+       /* Walk the list of functions, printing the cases. */
+       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
+               /* Write out referenced actions. */
+               if ( act->numTransRefs > 0 ) {
+                       /* Write the case label, the action and the case break. */
+                       out << "\tcase " << act->actionId << ":\n";
+                       ACTION( out, act, 0, false );
+                       out << "\tbreak;\n";
+               }
+       }
+
+       genLineDirective( out );
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::COND_OFFSETS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0, curKeyOffset = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write the key offset. */
+               ARRAY_ITEM( curKeyOffset, ++totalStateNum, st.last() );
+
+               /* Move the key offset ahead. */
+               curKeyOffset += st->stateCondList.length();
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::KEY_OFFSETS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0, curKeyOffset = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write the key offset. */
+               ARRAY_ITEM( curKeyOffset, ++totalStateNum, st.last() );
+
+               /* Move the key offset ahead. */
+               curKeyOffset += st->outSingle.length() + st->outRange.length()*2;
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+
+std::ostream &JavaTabCodeGen::INDEX_OFFSETS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0, curIndOffset = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write the index offset. */
+               ARRAY_ITEM( curIndOffset, ++totalStateNum, st.last() );
+
+               /* Move the index offset ahead. */
+               curIndOffset += st->outSingle.length() + st->outRange.length();
+               if ( st->defTrans != 0 )
+                       curIndOffset += 1;
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::COND_LENS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write singles length. */
+               ARRAY_ITEM( st->stateCondList.length(), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+
+std::ostream &JavaTabCodeGen::SINGLE_LENS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write singles length. */
+               ARRAY_ITEM( st->outSingle.length(), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::RANGE_LENS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Emit length of range index. */
+               ARRAY_ITEM( st->outRange.length(), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::TO_STATE_ACTIONS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write any eof action. */
+               ARRAY_ITEM( TO_STATE_ACTION(st), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::FROM_STATE_ACTIONS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write any eof action. */
+               ARRAY_ITEM( FROM_STATE_ACTION(st), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::EOF_ACTIONS()
+{
+       START_ARRAY_LINE();
+       int totalStateNum = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Write any eof action. */
+               ARRAY_ITEM( EOF_ACTION(st), ++totalStateNum, st.last() );
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::COND_KEYS()
+{
+       START_ARRAY_LINE();
+       int totalTrans = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Loop the state's transitions. */
+               for ( StateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
+                       /* Lower key. */
+                       ARRAY_ITEM( KEY( sc->lowKey ), ++totalTrans, false );
+                       ARRAY_ITEM( KEY( sc->highKey ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::COND_SPACES()
+{
+       START_ARRAY_LINE();
+       int totalTrans = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Loop the state's transitions. */
+               for ( StateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
+                       /* Cond Space id. */
+                       ARRAY_ITEM( KEY( sc->condSpace->condSpaceId ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::KEYS()
+{
+       START_ARRAY_LINE();
+       int totalTrans = 0;
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Loop the singles. */
+               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
+                       ARRAY_ITEM( KEY( stel->lowKey ), ++totalTrans, false );
+               }
+
+               /* Loop the state's transitions. */
+               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
+                       /* Lower key. */
+                       ARRAY_ITEM( KEY( rtel->lowKey ), ++totalTrans, false );
+
+                       /* Upper key. */
+                       ARRAY_ITEM( KEY( rtel->highKey ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::INDICIES()
+{
+       int totalTrans = 0;
+       START_ARRAY_LINE();
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Walk the singles. */
+               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
+                       ARRAY_ITEM( KEY( stel->value->id ), ++totalTrans, false );
+               }
+
+               /* Walk the ranges. */
+               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
+                       ARRAY_ITEM( KEY( rtel->value->id ), ++totalTrans, false );
+               }
+
+               /* The state's default index goes next. */
+               if ( st->defTrans != 0 ) {
+                       ARRAY_ITEM( KEY( st->defTrans->id ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::TRANS_TARGS()
+{
+       int totalTrans = 0;
+       START_ARRAY_LINE();
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Walk the singles. */
+               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
+                       RedTransAp *trans = stel->value;
+                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
+               }
+
+               /* Walk the ranges. */
+               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
+                       RedTransAp *trans = rtel->value;
+                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
+               }
+
+               /* The state's default target state. */
+               if ( st->defTrans != 0 ) {
+                       RedTransAp *trans = st->defTrans;
+                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+
+std::ostream &JavaTabCodeGen::TRANS_ACTIONS()
+{
+       int totalTrans = 0;
+       START_ARRAY_LINE();
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               /* Walk the singles. */
+               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
+                       RedTransAp *trans = stel->value;
+                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
+               }
+
+               /* Walk the ranges. */
+               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
+                       RedTransAp *trans = rtel->value;
+                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
+               }
+
+               /* The state's default index goes next. */
+               if ( st->defTrans != 0 ) {
+                       RedTransAp *trans = st->defTrans;
+                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
+               }
+       }
+
+       /* Output one last number so we don't have to figure out when the last
+        * entry is and avoid writing a comma. */
+       ARRAY_ITEM( 0, ++totalTrans, true );
+       END_ARRAY_LINE();
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::TRANS_TARGS_WI()
+{
+       /* Transitions must be written ordered by their id. */
+       RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
+       for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
+               transPtrs[trans->id] = trans;
+
+       /* Keep a count of the num of items in the array written. */
+       START_ARRAY_LINE();
+       int totalStates = 0;
+       for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
+               /* Write out the target state. */
+               RedTransAp *trans = transPtrs[t];
+               ARRAY_ITEM( trans->targ->id, ++totalStates, ( t >= redFsm->transSet.length()-1 ) );
+       }
+       END_ARRAY_LINE();
+       delete[] transPtrs;
+       return out;
+}
+
+
+std::ostream &JavaTabCodeGen::TRANS_ACTIONS_WI()
+{
+       /* Transitions must be written ordered by their id. */
+       RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
+       for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
+               transPtrs[trans->id] = trans;
+
+       /* Keep a count of the num of items in the array written. */
+       START_ARRAY_LINE();
+       int totalAct = 0;
+       for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
+               /* Write the function for the transition. */
+               RedTransAp *trans = transPtrs[t];
+               ARRAY_ITEM( TRANS_ACTION( trans ), ++totalAct, ( t >= redFsm->transSet.length()-1 ) );
+       }
+       END_ARRAY_LINE();
+       delete[] transPtrs;
+       return out;
+}
+
+
 void JavaTabCodeGen::writeOutData()
 {
-       TabCodeGen::writeOutData();
-       
        out <<
                "       private static byte[] unpack_byte(String packed)\n"
                "       {\n"
@@ -195,7 +827,128 @@ void JavaTabCodeGen::writeOutData()
                "               }\n"
                "               return ret;\n"
                "       }\n";
+       
+       /* If there are any transtion functions then output the array. If there
+        * are none, don't bother emitting an empty array that won't be used. */
+       if ( redFsm->anyActions() ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
+               ACTIONS_ARRAY();
+               CLOSE_ARRAY() <<
+               "\n";
+       }
+
+       if ( redFsm->anyConditions() ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() );
+               COND_OFFSETS();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() );
+               COND_LENS();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
+               COND_KEYS();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() );
+               COND_SPACES();
+               CLOSE_ARRAY() <<
+               "\n";
+       }
+
+       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() );
+       KEY_OFFSETS();
+       CLOSE_ARRAY() <<
+       "\n";
+
+       OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
+       KEYS();
+       CLOSE_ARRAY() <<
+       "\n";
+
+       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() );
+       SINGLE_LENS();
+       CLOSE_ARRAY() <<
+       "\n";
+
+       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() );
+       RANGE_LENS();
+       CLOSE_ARRAY() <<
+       "\n";
+
+       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() );
+       INDEX_OFFSETS();
+       CLOSE_ARRAY() <<
+       "\n";
+
+       if ( useIndicies ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
+               INDICIES();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
+               TRANS_TARGS_WI();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               if ( redFsm->anyActions() ) {
+                       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
+                       TRANS_ACTIONS_WI();
+                       CLOSE_ARRAY() <<
+                       "\n";
+               }
+       }
+       else {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
+               TRANS_TARGS();
+               CLOSE_ARRAY() <<
+               "\n";
+
+               if ( redFsm->anyActions() ) {
+                       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
+                       TRANS_ACTIONS();
+                       CLOSE_ARRAY() <<
+                       "\n";
+               }
+       }
+
+       if ( redFsm->anyToStateActions() ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
+               TO_STATE_ACTIONS();
+               CLOSE_ARRAY() <<
+               "\n";
+       }
+
+       if ( redFsm->anyFromStateActions() ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
+               FROM_STATE_ACTIONS();
+               CLOSE_ARRAY() <<
+               "\n";
+       }
+
+       if ( redFsm->anyEofActions() ) {
+               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
+               EOF_ACTIONS();
+               CLOSE_ARRAY() <<
+               "\n";
+       }
+
+       STATIC_VAR( "int", START() ) << " = " << START_STATE_ID() << ";\n"
+       "\n";
+
+       if ( writeFirstFinal ) {
+               STATIC_VAR( "int" , FIRST_FINAL() ) << " = " << FIRST_FINAL_STATE() << ";\n"
+               "\n";
+       }
 
+       if ( writeErr ) {
+               STATIC_VAR( "int", ERROR() ) << " = " << ERROR_STATE() << ";\n"
+               "\n";
+       }
        
 }
 
@@ -338,3 +1091,518 @@ void JavaTabCodeGen::writeOutEOF()
        }
 }
 
+string JavaTabCodeGen::PTR_CONST()
+{
+       /* Not used in Java code. */
+       assert( false );
+       return "final";
+}
+
+std::ostream &JavaTabCodeGen::OPEN_ARRAY( string type, string name )
+{
+       array_type = type;
+       array_name = name;
+       out << "private static final String packed" << name << " = \n";
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::START_ARRAY_LINE()
+{
+       out << "\t\"";
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::ARRAY_ITEM( int item, int count, bool last )
+{
+       // 0 codes in 2 bytes in the Java class file and is common,
+       // so we increment all values by one when packing
+       item++;
+
+       std::ios_base::fmtflags originalFlags=out.flags();
+       if ( item < 0x80 )
+       {
+               out << std::oct << "\\" << item;
+       }
+       else
+       {
+               out << std::hex << "\\u" << std::setfill('0') << std::setw(4) << item;
+       }
+       out.flags(originalFlags);
+       
+       if ( !last )
+       {
+               if ( count % IALL == 0 )
+               {
+                       END_ARRAY_LINE();
+                       START_ARRAY_LINE();
+               }
+       }
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::END_ARRAY_LINE()
+{
+       out << "\" +\n";
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::CLOSE_ARRAY()
+{
+       out << "\t\"\";\n";
+       out << "static final " << array_type << "[] " << array_name 
+               << " = unpack_" << array_type << "(packed" << array_name << ");\n";
+       return out;
+}
+
+std::ostream &JavaTabCodeGen::STATIC_VAR( string type, string name )
+{
+       out << "static final " << type << " " << name;
+       return out;
+}
+
+string JavaTabCodeGen::UINT( )
+{
+       /* Not used. */
+       assert( false );
+       return "long";
+}
+
+string JavaTabCodeGen::ARR_OFF( string ptr, string offset )
+{
+       return ptr + " + " + offset;
+}
+
+string JavaTabCodeGen::CAST( string type )
+{
+       return "(" + type + ")";
+}
+
+string JavaTabCodeGen::NULL_ITEM()
+{
+       /* In java we use integers instead of pointers. */
+       return "-1";
+}
+
+string JavaTabCodeGen::POINTER()
+{
+       /* Not used. */
+       assert( false );
+       return " *";
+}
+
+std::ostream &JavaTabCodeGen::SWITCH_DEFAULT()
+{
+       return out;
+}
+
+string JavaTabCodeGen::GET_KEY()
+{
+       ostringstream ret;
+       if ( getKeyExpr != 0 ) { 
+               /* Emit the user supplied method of retrieving the key. */
+               ret << "(";
+               INLINE_LIST( ret, getKeyExpr, 0, false );
+               ret << ")";
+       }
+       else {
+               /* Expression for retrieving the key, use simple dereference. */
+               ret << "data[" << P() << "]";
+       }
+       return ret.str();
+}
+
+string JavaTabCodeGen::CTRL_FLOW()
+{
+       return "if (true) ";
+}
+
+unsigned int JavaTabCodeGen::arrayTypeSize( unsigned long maxVal )
+{
+       long long maxValLL = (long long) maxVal;
+       HostType *arrayType = keyOps->typeSubsumes( maxValLL );
+       assert( arrayType != 0 );
+       return arrayType->size;
+}
+
+string JavaTabCodeGen::ARRAY_TYPE( unsigned long maxVal )
+{
+       long long maxValLL = (long long) maxVal;
+       HostType *arrayType = keyOps->typeSubsumes( maxValLL );
+       assert( arrayType != 0 );
+
+       string ret = arrayType->data1;
+       if ( arrayType->data2 != 0 ) {
+               ret += " ";
+               ret += arrayType->data2;
+       }
+       return ret;
+}
+
+
+/* Write out the fsm name. */
+string JavaTabCodeGen::FSM_NAME()
+{
+       return fsmName;
+}
+
+/* Emit the offset of the start state as a decimal integer. */
+string JavaTabCodeGen::START_STATE_ID()
+{
+       ostringstream ret;
+       ret << redFsm->startState->id;
+       return ret.str();
+};
+
+/* Write out the array of actions. */
+std::ostream &JavaTabCodeGen::ACTIONS_ARRAY()
+{
+       START_ARRAY_LINE();
+       int totalActions = 0;
+       ARRAY_ITEM( 0, ++totalActions, false );
+       for ( ActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) {
+               /* Write out the length, which will never be the last character. */
+               ARRAY_ITEM( act->key.length(), ++totalActions, false );
+
+               for ( ActionTable::Iter item = act->key; item.lte(); item++ ) {
+                       ARRAY_ITEM( item->value->actionId, ++totalActions, (act.last() && item.last()) );
+               }
+       }
+       END_ARRAY_LINE();
+       return out;
+}
+
+
+string JavaTabCodeGen::CS()
+{
+       ostringstream ret;
+       if ( curStateExpr != 0 ) { 
+               /* Emit the user supplied method of retrieving the key. */
+               ret << "(";
+               INLINE_LIST( ret, curStateExpr, 0, false );
+               ret << ")";
+       }
+       else {
+               /* Expression for retrieving the key, use simple dereference. */
+               ret << ACCESS() << "cs";
+       }
+       return ret.str();
+}
+
+string JavaTabCodeGen::ACCESS()
+{
+       ostringstream ret;
+       if ( accessExpr != 0 )
+               INLINE_LIST( ret, accessExpr, 0, false );
+       return ret.str();
+}
+
+string JavaTabCodeGen::GET_WIDE_KEY()
+{
+       if ( redFsm->anyConditions() ) 
+               return "_widec";
+       else
+               return GET_KEY();
+}
+
+string JavaTabCodeGen::GET_WIDE_KEY( RedStateAp *state )
+{
+       if ( state->stateCondList.length() > 0 )
+               return "_widec";
+       else
+               return GET_KEY();
+}
+
+/* Write out level number of tabs. Makes the nested binary search nice
+ * looking. */
+string JavaTabCodeGen::TABS( int level )
+{
+       string result;
+       while ( level-- > 0 )
+               result += "\t";
+       return result;
+}
+
+int JavaTabCodeGen::KEY( Key key )
+{
+       return key.getVal();
+}
+
+
+void JavaTabCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, 
+               int targState, int inFinish )
+{
+       ret << 
+               "       switch( act ) {\n";
+
+       /* If the switch handles error then we also forced the error state. It
+        * will exist. */
+       if ( item->handlesError ) {
+               ret << "        case 0: " << TOKEND() << " = " << TOKSTART() << "; ";
+               GOTO( ret, redFsm->errState->id, inFinish );
+               ret << "\n";
+       }
+
+       for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) {
+               /* Write the case label, the action and the case break. */
+               ret << "        case " << lma->lmId << ":\n";
+
+               /* Write the block and close it off. */
+               ret << "        {";
+               INLINE_LIST( ret, lma->children, targState, inFinish );
+               ret << "}\n";
+
+               ret << "        break;\n";
+       }
+       /* Default required for D code. */
+       ret << 
+               "       default: break;\n"
+               "       }\n"
+               "\t";
+}
+
+void JavaTabCodeGen::SET_ACT( ostream &ret, InlineItem *item )
+{
+       ret << ACT() << " = " << item->lmId << ";";
+}
+
+void JavaTabCodeGen::SET_TOKEND( ostream &ret, InlineItem *item )
+{
+       /* The tokend action sets tokend. */
+       ret << TOKEND() << " = " << P();
+       if ( item->offset != 0 ) 
+               out << "+" << item->offset;
+       out << ";";
+}
+
+void JavaTabCodeGen::GET_TOKEND( ostream &ret, InlineItem *item )
+{
+       ret << TOKEND();
+}
+
+void JavaTabCodeGen::INIT_TOKSTART( ostream &ret, InlineItem *item )
+{
+       ret << TOKSTART() << " = " << NULL_ITEM() << ";";
+}
+
+void JavaTabCodeGen::INIT_ACT( ostream &ret, InlineItem *item )
+{
+       ret << ACT() << " = 0;";
+}
+
+void JavaTabCodeGen::SET_TOKSTART( ostream &ret, InlineItem *item )
+{
+       ret << TOKSTART() << " = " << P() << ";";
+}
+
+void JavaTabCodeGen::SUB_ACTION( ostream &ret, InlineItem *item, 
+               int targState, bool inFinish )
+{
+       if ( item->children->length() > 0 ) {
+               /* Write the block and close it off. */
+               ret << "{";
+               INLINE_LIST( ret, item->children, targState, inFinish );
+               ret << "}";
+       }
+}
+
+void JavaTabCodeGen::ACTION( ostream &ret, Action *action, int targState, bool inFinish )
+{
+       /* Write the preprocessor line info for going into the source file. */
+       lineDirective( ret, sourceFileName, action->loc.line );
+
+       /* Write the block and close it off. */
+       ret << "\t{";
+       INLINE_LIST( ret, action->inlineList, targState, inFinish );
+       ret << "}\n";
+}
+
+void JavaTabCodeGen::CONDITION( ostream &ret, Action *condition )
+{
+       ret << "\n";
+       lineDirective( ret, sourceFileName, condition->loc.line );
+       INLINE_LIST( ret, condition->inlineList, 0, false );
+}
+
+string JavaTabCodeGen::ERROR_STATE()
+{
+       ostringstream ret;
+       if ( redFsm->errState != 0 )
+               ret << redFsm->errState->id;
+       else
+               ret << "-1";
+       return ret.str();
+}
+
+string JavaTabCodeGen::FIRST_FINAL_STATE()
+{
+       ostringstream ret;
+       if ( redFsm->firstFinState != 0 )
+               ret << redFsm->firstFinState->id;
+       else
+               ret << redFsm->nextStateId;
+       return ret.str();
+}
+
+void JavaTabCodeGen::writeOutInit()
+{
+       out << "        {\n";
+       out << "\t" << CS() << " = " << START() << ";\n";
+       
+       /* If there are any calls, then the stack top needs initialization. */
+       if ( redFsm->anyActionCalls() || redFsm->anyActionRets() )
+               out << "\t" << TOP() << " = 0;\n";
+
+       if ( hasLongestMatch ) {
+               out << 
+                       "       " << TOKSTART() << " = " << NULL_ITEM() << ";\n"
+                       "       " << TOKEND() << " = " << NULL_ITEM() << ";\n"
+                       "       " << ACT() << " = 0;\n";
+       }
+       out << "        }\n";
+}
+
+/* Generate the code for an fsm. Assumes parseData is set up properly. Called
+ * by parser code. */
+void JavaTabCodeGen::prepareMachine()
+{
+       if ( hasBeenPrepared )
+               return;
+       hasBeenPrepared = true;
+       
+       /* Do this before distributing transitions out to singles and defaults
+        * makes life easier. */
+       redFsm->maxKey = findMaxKey();
+
+       redFsm->assignActionLocs();
+
+       /* Order the states. */
+       redFsm->depthFirstOrdering();
+
+       if ( codeStyle == GenGoto || codeStyle == GenFGoto || 
+                       codeStyle == GenIpGoto || codeStyle == GenSplit )
+       {
+               /* For goto driven machines we can keep the original depth
+                * first ordering because it's ok if the state ids are not
+                * sequential. Split the the ids by final state status. */
+               redFsm->sortStateIdsByFinal();
+       }
+       else {
+               /* For table driven machines the location of the state is used to
+                * identify it so the states must be sorted by their final ids.
+                * Though having a deterministic ordering is important,
+                * specifically preserving the depth first ordering is not because
+                * states are stored in tables. */
+               redFsm->sortStatesByFinal();
+               redFsm->sequentialStateIds();
+       }
+
+       /* Find the first final state. This is the final state with the lowest
+        * id.  */
+       redFsm->findFirstFinState();
+
+       /* Choose default transitions and the single transition. */
+       redFsm->chooseDefaultSpan();
+               
+       /* Maybe do flat expand, otherwise choose single. */
+       if ( codeStyle == GenFlat || codeStyle == GenFFlat )
+               redFsm->makeFlat();
+       else
+               redFsm->chooseSingle();
+
+       /* If any errors have occured in the input file then don't write anything. */
+       if ( gblErrorCount > 0 )
+               return;
+       
+       if ( codeStyle == GenSplit )
+               redFsm->partitionFsm( numSplitPartitions );
+
+       if ( codeStyle == GenIpGoto || codeStyle == GenSplit )
+               redFsm->setInTrans();
+
+       /* Anlayze Machine will find the final action reference counts, among
+        * other things. We will use these in reporting the usage
+        * of fsm directives in action code. */
+       analyzeMachine();
+
+       /* Determine if we should use indicies. */
+       calcIndexSize();
+}
+
+void JavaTabCodeGen::finishRagelDef()
+{
+       assert( outputFormat == OutCode );
+       prepareMachine();
+}
+
+void JavaTabCodeGen::writeStatement( InputLoc &loc, int nargs, char **args )
+{
+       if ( outputFormat == OutCode ) {
+               /* Force a newline. */
+               out << "\n";
+               genLineDirective( out );
+
+               if ( strcmp( args[0], "data" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               if ( strcmp( args[i], "noerror" ) == 0 )
+                                       writeErr = false;
+                               else if ( strcmp( args[i], "noprefix" ) == 0 )
+                                       dataPrefix = false;
+                               else if ( strcmp( args[i], "nofinal" ) == 0 )
+                                       writeFirstFinal = false;
+                               else {
+                                       source_warning(loc) << "unrecognized write option \"" << 
+                                                       args[i] << "\"" << endl;
+                               }
+                       }
+                       writeOutData();
+               }
+               else if ( strcmp( args[0], "init" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               source_warning(loc) << "unrecognized write option \"" << 
+                                               args[i] << "\"" << endl;
+                       }
+                       writeOutInit();
+               }
+               else if ( strcmp( args[0], "exec" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               if ( strcmp( args[i], "noend" ) == 0 )
+                                       hasEnd = false;
+                               else {
+                                       source_warning(loc) << "unrecognized write option \"" << 
+                                                       args[i] << "\"" << endl;
+                               }
+                       }
+
+                       /* Must set labels immediately before writing because we may depend
+                        * on the noend write option. */
+                       setLabelsNeeded();
+                       writeOutExec();
+               }
+               else if ( strcmp( args[0], "eof" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               source_warning(loc) << "unrecognized write option \"" << 
+                                               args[i] << "\"" << endl;
+                       }
+                       writeOutEOF();
+               }
+               else {
+                       /* EMIT An error here. */
+               }
+       }
+}
+
+ostream &JavaTabCodeGen::source_warning( const InputLoc &loc )
+{
+       cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: ";
+       return cerr;
+}
+
+ostream &JavaTabCodeGen::source_error( const InputLoc &loc )
+{
+       gblErrorCount += 1;
+       assert( sourceFileName != 0 );
+       cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": ";
+       return cerr;
+}
+
+
index 58ec9e0..3efa83e 100644 (file)
@@ -1,5 +1,6 @@
 /*
- *  Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2006-2007 Adrian Thurston <thurston@cs.queensu.ca>
+ *            2007 Colin Fleming <colin.fleming@caverock.com>
  */
 
 /*  This file is part of Ragel.
 #ifndef _JAVACODEGEN_H
 #define _JAVACODEGEN_H
 
-#include "tabcodegen.h"
+#include <iostream>
+#include <string>
+#include <stdio.h>
+#include "common.h"
+#include "gendata.h"
+
+using std::string;
+using std::ostream;
 
 /*
  * JavaTabCodeGen
  */
-struct JavaTabCodeGen
-       : public TabCodeGen, public JavaCodeGen
+struct JavaTabCodeGen : public CodeGenData
 {
        JavaTabCodeGen( ostream &out ) : 
-               FsmCodeGen(out), TabCodeGen(out), JavaCodeGen(out) {}
+               CodeGenData(out) {}
+
+       std::ostream &TO_STATE_ACTION_SWITCH();
+       std::ostream &FROM_STATE_ACTION_SWITCH();
+       std::ostream &EOF_ACTION_SWITCH();
+       std::ostream &ACTION_SWITCH();
+
+       std::ostream &COND_KEYS();
+       std::ostream &COND_SPACES();
+       std::ostream &KEYS();
+       std::ostream &INDICIES();
+       std::ostream &COND_OFFSETS();
+       std::ostream &KEY_OFFSETS();
+       std::ostream &INDEX_OFFSETS();
+       std::ostream &COND_LENS();
+       std::ostream &SINGLE_LENS();
+       std::ostream &RANGE_LENS();
+       std::ostream &TO_STATE_ACTIONS();
+       std::ostream &FROM_STATE_ACTIONS();
+       std::ostream &EOF_ACTIONS();
+       std::ostream &TRANS_TARGS();
+       std::ostream &TRANS_ACTIONS();
+       std::ostream &TRANS_TARGS_WI();
+       std::ostream &TRANS_ACTIONS_WI();
 
        void BREAK( ostream &ret, int targState );
        void GOTO( ostream &ret, int gotoDest, bool inFinish );
@@ -42,9 +72,130 @@ struct JavaTabCodeGen
 
        void COND_TRANSLATE();
        void LOCATE_TRANS();
+
        virtual void writeOutExec();
        virtual void writeOutEOF();
        virtual void writeOutData();
+       virtual void writeOutInit();
+
+       void NEXT( ostream &ret, int nextDest, bool inFinish );
+       void NEXT_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish );
+
+       int TO_STATE_ACTION( RedStateAp *state );
+       int FROM_STATE_ACTION( RedStateAp *state );
+       int EOF_ACTION( RedStateAp *state );
+       int TRANS_ACTION( RedTransAp *trans );
+
+       /* Determine if we should use indicies. */
+       void calcIndexSize();
+
+private:
+       string array_type;
+       string array_name;
+
+public:
+
+       virtual string NULL_ITEM();
+       virtual string POINTER();
+       virtual ostream &SWITCH_DEFAULT();
+       virtual ostream &OPEN_ARRAY( string type, string name );
+       virtual ostream &START_ARRAY_LINE();
+       virtual ostream &ARRAY_ITEM( int item, int count, bool last );
+       virtual ostream &END_ARRAY_LINE();
+       virtual ostream &CLOSE_ARRAY();
+       virtual ostream &STATIC_VAR( string type, string name );
+       virtual string ARR_OFF( string ptr, string offset );
+       virtual string CAST( string type );
+       virtual string UINT();
+       virtual string PTR_CONST();
+       virtual string GET_KEY();
+       virtual string CTRL_FLOW();
+
+       string FSM_NAME();
+       string START_STATE_ID();
+       ostream &ACTIONS_ARRAY();
+       string GET_WIDE_KEY();
+       string GET_WIDE_KEY( RedStateAp *state );
+       string TABS( int level );
+       int KEY( Key key );
+       void ACTION( ostream &ret, Action *action, int targState, bool inFinish );
+       void CONDITION( ostream &ret, Action *condition );
+       string ALPH_TYPE();
+       string WIDE_ALPH_TYPE();
+       string ARRAY_TYPE( unsigned long maxVal );
+
+       string P() { return "p"; }
+       string PE() { return "pe"; }
+
+       string ACCESS();
+       string CS();
+       string STACK() { return ACCESS() + "stack"; }
+       string TOP() { return ACCESS() + "top"; }
+       string TOKSTART() { return ACCESS() + "tokstart"; }
+       string TOKEND() { return ACCESS() + "tokend"; }
+       string ACT() { return ACCESS() + "act"; }
+
+       string DATA_PREFIX();
+       string PM() { return "_" + DATA_PREFIX() + "partition_map"; }
+       string C() { return "_" + DATA_PREFIX() + "cond_spaces"; }
+       string CK() { return "_" + DATA_PREFIX() + "cond_keys"; }
+       string K() { return "_" + DATA_PREFIX() + "trans_keys"; }
+       string I() { return "_" + DATA_PREFIX() + "indicies"; }
+       string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; }
+       string KO() { return "_" + DATA_PREFIX() + "key_offsets"; }
+       string IO() { return "_" + DATA_PREFIX() + "index_offsets"; }
+       string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; }
+       string SL() { return "_" + DATA_PREFIX() + "single_lengths"; }
+       string RL() { return "_" + DATA_PREFIX() + "range_lengths"; }
+       string A() { return "_" + DATA_PREFIX() + "actions"; }
+       string TA() { return "_" + DATA_PREFIX() + "trans_actions_wi"; }
+       string TT() { return "_" + DATA_PREFIX() + "trans_targs_wi"; }
+       string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; }
+       string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; }
+       string EA() { return "_" + DATA_PREFIX() + "eof_actions"; }
+       string SP() { return "_" + DATA_PREFIX() + "key_spans"; }
+       string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; }
+       string START() { return DATA_PREFIX() + "start"; }
+       string ERROR() { return DATA_PREFIX() + "error"; }
+       string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; }
+       string CTXDATA() { return DATA_PREFIX() + "ctxdata"; }
+
+       void INLINE_LIST( ostream &ret, InlineList *inlineList, int targState, bool inFinish );
+       void EXEC( ostream &ret, InlineItem *item, int targState, int inFinish );
+       void EXECTE( ostream &ret, InlineItem *item, int targState, int inFinish );
+       void LM_SWITCH( ostream &ret, InlineItem *item, int targState, int inFinish );
+       void SET_ACT( ostream &ret, InlineItem *item );
+       void INIT_TOKSTART( ostream &ret, InlineItem *item );
+       void INIT_ACT( ostream &ret, InlineItem *item );
+       void SET_TOKSTART( ostream &ret, InlineItem *item );
+       void SET_TOKEND( ostream &ret, InlineItem *item );
+       void GET_TOKEND( ostream &ret, InlineItem *item );
+       void SUB_ACTION( ostream &ret, InlineItem *item, 
+                       int targState, bool inFinish );
+
+       string ERROR_STATE();
+       string FIRST_FINAL_STATE();
+
+       ostream &source_warning(const InputLoc &loc);
+       ostream &source_error(const InputLoc &loc);
+
+       unsigned int arrayTypeSize( unsigned long maxVal );
+
+       /* Set up labelNeeded flag for each state. Differs for each goto style so
+        * is virtual. */
+       virtual void setLabelsNeeded() {}
+
+       bool outLabelUsed;
+       bool againLabelUsed;
+
+       bool useIndicies;
+
+public:
+       void prepareMachine();
+
+       virtual void finishRagelDef();
+       virtual void writeStatement( InputLoc &loc, int nargs, char **args );
+
 };
 
 
index f23acbf..8cfcf33 100644 (file)
 #include <fstream>
 #include <unistd.h>
 
-#include "javagen.h"
+#include "rlgen-java.h"
 #include "xmlparse.h"
 #include "pcheck.h"
 #include "vector.h"
 #include "version.h"
-
-/* Code generators. */
-#include "javacodegen.h"
-
 #include "common.h"
-#include "common.cpp"
+#include "javacodegen.h"
 
 using std::istream;
 using std::ifstream;
similarity index 92%
rename from rlgen-java/javagen.h
rename to rlgen-java/rlgen-java.h
index b787291..ed52e22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
  */
 
 /*  This file is part of Ragel.
@@ -19,8 +19,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
 
-#ifndef _RLCODEGEN_H
-#define _RLCODEGEN_H
+#ifndef _RLGEN_JAVA_H
+#define _RLGEN_JAVA_H
 
 #include <stdio.h>
 #include <iostream>
@@ -80,4 +80,4 @@ extern int numSplitPartitions;
 std::ostream &error();
 char *fileNameFromStem( char *stemFile, char *suffix );
 
-#endif /* _RLCODEGEN_H */
+#endif /* _RLGEN_JAVA_H */
diff --git a/rlgen-java/tabcodegen.cpp b/rlgen-java/tabcodegen.cpp
deleted file mode 100644 (file)
index 42b1ae8..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
- *            2004 Erich Ocean <eric.ocean@ampede.com>
- *            2005 Alan West <alan@alanz.com>
- */
-
-/*  This file is part of Ragel.
- *
- *  Ragel is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- * 
- *  Ragel is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- * 
- *  You should have received a copy of the GNU General Public License
- *  along with Ragel; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- */
-
-#include "javagen.h"
-#include "tabcodegen.h"
-#include "redfsm.h"
-#include "gendata.h"
-
-/* Determine if we should use indicies or not. */
-void TabCodeGen::calcIndexSize()
-{
-       int sizeWithInds = 0, sizeWithoutInds = 0;
-
-       /* Calculate cost of using with indicies. */
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               int totalIndex = st->outSingle.length() + st->outRange.length() + 
-                               (st->defTrans == 0 ? 0 : 1);
-               sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex;
-       }
-       sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length();
-       if ( redFsm->anyActions() )
-               sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length();
-
-       /* Calculate the cost of not using indicies. */
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               int totalIndex = st->outSingle.length() + st->outRange.length() + 
-                               (st->defTrans == 0 ? 0 : 1);
-               sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex;
-               if ( redFsm->anyActions() )
-                       sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex;
-       }
-
-       /* If using indicies reduces the size, use them. */
-       useIndicies = sizeWithInds < sizeWithoutInds;
-}
-
-int TabCodeGen::TO_STATE_ACTION( RedStateAp *state )
-{
-       int act = 0;
-       if ( state->toStateAction != 0 )
-               act = state->toStateAction->location+1;
-       return act;
-}
-
-int TabCodeGen::FROM_STATE_ACTION( RedStateAp *state )
-{
-       int act = 0;
-       if ( state->fromStateAction != 0 )
-               act = state->fromStateAction->location+1;
-       return act;
-}
-
-int TabCodeGen::EOF_ACTION( RedStateAp *state )
-{
-       int act = 0;
-       if ( state->eofAction != 0 )
-               act = state->eofAction->location+1;
-       return act;
-}
-
-
-int TabCodeGen::TRANS_ACTION( RedTransAp *trans )
-{
-       /* If there are actions, emit them. Otherwise emit zero. */
-       int act = 0;
-       if ( trans->action != 0 )
-               act = trans->action->location+1;
-       return act;
-}
-
-std::ostream &TabCodeGen::TO_STATE_ACTION_SWITCH()
-{
-       /* Walk the list of functions, printing the cases. */
-       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
-               /* Write out referenced actions. */
-               if ( act->numToStateRefs > 0 ) {
-                       /* Write the case label, the action and the case break. */
-                       out << "\tcase " << act->actionId << ":\n";
-                       ACTION( out, act, 0, false );
-                       out << "\tbreak;\n";
-               }
-       }
-
-       genLineDirective( out );
-       return out;
-}
-
-std::ostream &TabCodeGen::FROM_STATE_ACTION_SWITCH()
-{
-       /* Walk the list of functions, printing the cases. */
-       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
-               /* Write out referenced actions. */
-               if ( act->numFromStateRefs > 0 ) {
-                       /* Write the case label, the action and the case break. */
-                       out << "\tcase " << act->actionId << ":\n";
-                       ACTION( out, act, 0, false );
-                       out << "\tbreak;\n";
-               }
-       }
-
-       genLineDirective( out );
-       return out;
-}
-
-std::ostream &TabCodeGen::EOF_ACTION_SWITCH()
-{
-       /* Walk the list of functions, printing the cases. */
-       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
-               /* Write out referenced actions. */
-               if ( act->numEofRefs > 0 ) {
-                       /* Write the case label, the action and the case break. */
-                       out << "\tcase " << act->actionId << ":\n";
-                       ACTION( out, act, 0, true );
-                       out << "\tbreak;\n";
-               }
-       }
-
-       genLineDirective( out );
-       return out;
-}
-
-
-std::ostream &TabCodeGen::ACTION_SWITCH()
-{
-       /* Walk the list of functions, printing the cases. */
-       for ( ActionList::Iter act = actionList; act.lte(); act++ ) {
-               /* Write out referenced actions. */
-               if ( act->numTransRefs > 0 ) {
-                       /* Write the case label, the action and the case break. */
-                       out << "\tcase " << act->actionId << ":\n";
-                       ACTION( out, act, 0, false );
-                       out << "\tbreak;\n";
-               }
-       }
-
-       genLineDirective( out );
-       return out;
-}
-
-std::ostream &TabCodeGen::COND_OFFSETS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0, curKeyOffset = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write the key offset. */
-               ARRAY_ITEM( curKeyOffset, ++totalStateNum, st.last() );
-
-               /* Move the key offset ahead. */
-               curKeyOffset += st->stateCondList.length();
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::KEY_OFFSETS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0, curKeyOffset = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write the key offset. */
-               ARRAY_ITEM( curKeyOffset, ++totalStateNum, st.last() );
-
-               /* Move the key offset ahead. */
-               curKeyOffset += st->outSingle.length() + st->outRange.length()*2;
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-
-std::ostream &TabCodeGen::INDEX_OFFSETS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0, curIndOffset = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write the index offset. */
-               ARRAY_ITEM( curIndOffset, ++totalStateNum, st.last() );
-
-               /* Move the index offset ahead. */
-               curIndOffset += st->outSingle.length() + st->outRange.length();
-               if ( st->defTrans != 0 )
-                       curIndOffset += 1;
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::COND_LENS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write singles length. */
-               ARRAY_ITEM( st->stateCondList.length(), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-
-std::ostream &TabCodeGen::SINGLE_LENS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write singles length. */
-               ARRAY_ITEM( st->outSingle.length(), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::RANGE_LENS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Emit length of range index. */
-               ARRAY_ITEM( st->outRange.length(), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::TO_STATE_ACTIONS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write any eof action. */
-               ARRAY_ITEM( TO_STATE_ACTION(st), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::FROM_STATE_ACTIONS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write any eof action. */
-               ARRAY_ITEM( FROM_STATE_ACTION(st), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::EOF_ACTIONS()
-{
-       START_ARRAY_LINE();
-       int totalStateNum = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Write any eof action. */
-               ARRAY_ITEM( EOF_ACTION(st), ++totalStateNum, st.last() );
-       }
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::COND_KEYS()
-{
-       START_ARRAY_LINE();
-       int totalTrans = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Loop the state's transitions. */
-               for ( StateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
-                       /* Lower key. */
-                       ARRAY_ITEM( KEY( sc->lowKey ), ++totalTrans, false );
-                       ARRAY_ITEM( KEY( sc->highKey ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::COND_SPACES()
-{
-       START_ARRAY_LINE();
-       int totalTrans = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Loop the state's transitions. */
-               for ( StateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) {
-                       /* Cond Space id. */
-                       ARRAY_ITEM( KEY( sc->condSpace->condSpaceId ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::KEYS()
-{
-       START_ARRAY_LINE();
-       int totalTrans = 0;
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Loop the singles. */
-               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
-                       ARRAY_ITEM( KEY( stel->lowKey ), ++totalTrans, false );
-               }
-
-               /* Loop the state's transitions. */
-               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
-                       /* Lower key. */
-                       ARRAY_ITEM( KEY( rtel->lowKey ), ++totalTrans, false );
-
-                       /* Upper key. */
-                       ARRAY_ITEM( KEY( rtel->highKey ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::INDICIES()
-{
-       int totalTrans = 0;
-       START_ARRAY_LINE();
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Walk the singles. */
-               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
-                       ARRAY_ITEM( KEY( stel->value->id ), ++totalTrans, false );
-               }
-
-               /* Walk the ranges. */
-               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
-                       ARRAY_ITEM( KEY( rtel->value->id ), ++totalTrans, false );
-               }
-
-               /* The state's default index goes next. */
-               if ( st->defTrans != 0 ) {
-                       ARRAY_ITEM( KEY( st->defTrans->id ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::TRANS_TARGS()
-{
-       int totalTrans = 0;
-       START_ARRAY_LINE();
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Walk the singles. */
-               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
-                       RedTransAp *trans = stel->value;
-                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
-               }
-
-               /* Walk the ranges. */
-               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
-                       RedTransAp *trans = rtel->value;
-                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
-               }
-
-               /* The state's default target state. */
-               if ( st->defTrans != 0 ) {
-                       RedTransAp *trans = st->defTrans;
-                       ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-
-std::ostream &TabCodeGen::TRANS_ACTIONS()
-{
-       int totalTrans = 0;
-       START_ARRAY_LINE();
-       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-               /* Walk the singles. */
-               for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) {
-                       RedTransAp *trans = stel->value;
-                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
-               }
-
-               /* Walk the ranges. */
-               for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) {
-                       RedTransAp *trans = rtel->value;
-                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
-               }
-
-               /* The state's default index goes next. */
-               if ( st->defTrans != 0 ) {
-                       RedTransAp *trans = st->defTrans;
-                       ARRAY_ITEM( TRANS_ACTION( trans ), ++totalTrans, false );
-               }
-       }
-
-       /* Output one last number so we don't have to figure out when the last
-        * entry is and avoid writing a comma. */
-       ARRAY_ITEM( 0, ++totalTrans, true );
-       END_ARRAY_LINE();
-       return out;
-}
-
-std::ostream &TabCodeGen::TRANS_TARGS_WI()
-{
-       /* Transitions must be written ordered by their id. */
-       RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
-       for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
-               transPtrs[trans->id] = trans;
-
-       /* Keep a count of the num of items in the array written. */
-       START_ARRAY_LINE();
-       int totalStates = 0;
-       for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
-               /* Write out the target state. */
-               RedTransAp *trans = transPtrs[t];
-               ARRAY_ITEM( trans->targ->id, ++totalStates, ( t >= redFsm->transSet.length()-1 ) );
-       }
-       END_ARRAY_LINE();
-       delete[] transPtrs;
-       return out;
-}
-
-
-std::ostream &TabCodeGen::TRANS_ACTIONS_WI()
-{
-       /* Transitions must be written ordered by their id. */
-       RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
-       for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
-               transPtrs[trans->id] = trans;
-
-       /* Keep a count of the num of items in the array written. */
-       START_ARRAY_LINE();
-       int totalAct = 0;
-       for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
-               /* Write the function for the transition. */
-               RedTransAp *trans = transPtrs[t];
-               ARRAY_ITEM( TRANS_ACTION( trans ), ++totalAct, ( t >= redFsm->transSet.length()-1 ) );
-       }
-       END_ARRAY_LINE();
-       delete[] transPtrs;
-       return out;
-}
-
-
-void TabCodeGen::CURS( ostream &ret, bool inFinish )
-{
-       ret << "(_ps)";
-}
-
-void TabCodeGen::TARGS( ostream &ret, bool inFinish, int targState )
-{
-       ret << "(" << CS() << ")";
-}
-
-void TabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish )
-{
-       ret << CS() << " = " << nextDest << ";";
-}
-
-void TabCodeGen::NEXT_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish )
-{
-       ret << CS() << " = (";
-       INLINE_LIST( ret, ilItem->children, 0, inFinish );
-       ret << ");";
-}
-
-void TabCodeGen::writeOutData()
-{
-       /* If there are any transtion functions then output the array. If there
-        * are none, don't bother emitting an empty array that won't be used. */
-       if ( redFsm->anyActions() ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
-               ACTIONS_ARRAY();
-               CLOSE_ARRAY() <<
-               "\n";
-       }
-
-       if ( redFsm->anyConditions() ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() );
-               COND_OFFSETS();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() );
-               COND_LENS();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
-               COND_KEYS();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() );
-               COND_SPACES();
-               CLOSE_ARRAY() <<
-               "\n";
-       }
-
-       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() );
-       KEY_OFFSETS();
-       CLOSE_ARRAY() <<
-       "\n";
-
-       OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
-       KEYS();
-       CLOSE_ARRAY() <<
-       "\n";
-
-       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() );
-       SINGLE_LENS();
-       CLOSE_ARRAY() <<
-       "\n";
-
-       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() );
-       RANGE_LENS();
-       CLOSE_ARRAY() <<
-       "\n";
-
-       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() );
-       INDEX_OFFSETS();
-       CLOSE_ARRAY() <<
-       "\n";
-
-       if ( useIndicies ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
-               INDICIES();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
-               TRANS_TARGS_WI();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               if ( redFsm->anyActions() ) {
-                       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
-                       TRANS_ACTIONS_WI();
-                       CLOSE_ARRAY() <<
-                       "\n";
-               }
-       }
-       else {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
-               TRANS_TARGS();
-               CLOSE_ARRAY() <<
-               "\n";
-
-               if ( redFsm->anyActions() ) {
-                       OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
-                       TRANS_ACTIONS();
-                       CLOSE_ARRAY() <<
-                       "\n";
-               }
-       }
-
-       if ( redFsm->anyToStateActions() ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
-               TO_STATE_ACTIONS();
-               CLOSE_ARRAY() <<
-               "\n";
-       }
-
-       if ( redFsm->anyFromStateActions() ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
-               FROM_STATE_ACTIONS();
-               CLOSE_ARRAY() <<
-               "\n";
-       }
-
-       if ( redFsm->anyEofActions() ) {
-               OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
-               EOF_ACTIONS();
-               CLOSE_ARRAY() <<
-               "\n";
-       }
-
-       STATIC_VAR( "int", START() ) << " = " << START_STATE_ID() << ";\n"
-       "\n";
-
-       if ( writeFirstFinal ) {
-               STATIC_VAR( "int" , FIRST_FINAL() ) << " = " << FIRST_FINAL_STATE() << ";\n"
-               "\n";
-       }
-
-       if ( writeErr ) {
-               STATIC_VAR( "int", ERROR() ) << " = " << ERROR_STATE() << ";\n"
-               "\n";
-       }
-}
-
diff --git a/rlgen-java/tabcodegen.h b/rlgen-java/tabcodegen.h
deleted file mode 100644 (file)
index c9343e3..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
- *            2004 Erich Ocean <eric.ocean@ampede.com>
- *            2005 Alan West <alan@alanz.com>
- */
-
-/*  This file is part of Ragel.
- *
- *  Ragel is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- * 
- *  Ragel is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- * 
- *  You should have received a copy of the GNU General Public License
- *  along with Ragel; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- */
-
-#ifndef _TABCODEGEN_H
-#define _TABCODEGEN_H
-
-#include <iostream>
-#include "fsmcodegen.h"
-
-/* Forwards. */
-struct CodeGenData;
-struct NameInst;
-struct RedTransAp;
-struct RedStateAp;
-
-/*
- * TabCodeGen
- */
-class TabCodeGen : virtual public FsmCodeGen
-{
-public:
-       TabCodeGen( ostream &out ) : FsmCodeGen(out) {}
-       virtual ~TabCodeGen() { }
-       virtual void writeOutData();
-
-protected:
-       std::ostream &TO_STATE_ACTION_SWITCH();
-       std::ostream &FROM_STATE_ACTION_SWITCH();
-       std::ostream &EOF_ACTION_SWITCH();
-       std::ostream &ACTION_SWITCH();
-
-       std::ostream &COND_KEYS();
-       std::ostream &COND_SPACES();
-       std::ostream &KEYS();
-       std::ostream &INDICIES();
-       std::ostream &COND_OFFSETS();
-       std::ostream &KEY_OFFSETS();
-       std::ostream &INDEX_OFFSETS();
-       std::ostream &COND_LENS();
-       std::ostream &SINGLE_LENS();
-       std::ostream &RANGE_LENS();
-       std::ostream &TO_STATE_ACTIONS();
-       std::ostream &FROM_STATE_ACTIONS();
-       std::ostream &EOF_ACTIONS();
-       std::ostream &TRANS_TARGS();
-       std::ostream &TRANS_ACTIONS();
-       std::ostream &TRANS_TARGS_WI();
-       std::ostream &TRANS_ACTIONS_WI();
-
-       void NEXT( ostream &ret, int nextDest, bool inFinish );
-       void NEXT_EXPR( ostream &ret, InlineItem *ilItem, bool inFinish );
-       void CURS( ostream &ret, bool inFinish );
-       void TARGS( ostream &ret, bool inFinish, int targState );
-
-       virtual int TO_STATE_ACTION( RedStateAp *state );
-       virtual int FROM_STATE_ACTION( RedStateAp *state );
-       virtual int EOF_ACTION( RedStateAp *state );
-       virtual int TRANS_ACTION( RedTransAp *trans );
-       virtual void calcIndexSize();
-};
-
-
-#endif /* _TABCODEGEN_H */
index 50722bd..2b0daf0 100755 (executable)
@@ -125,7 +125,7 @@ for test_case; do
                        cflags="-Wall -O3 -fno-strict-aliasing -lobjc"
                ;;
                java)
-                       codegen=../javagen/rlcodegen-java;
+                       codegen=../rlgen-java/rlgen-java;
                        code_suffix=java;
                        compiler=$java_compiler
                        lang_opt=-J;