protected:
- friend struct CodeGenData;
-
string FSM_NAME();
string START_STATE_ID();
ostream &ACTIONS_ARRAY();
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@
# 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
+++ /dev/null
-/*
- * 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 );
-}
-
+++ /dev/null
-/*
- * 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 */
/*
- * 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 )
{
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 <<
"\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"
" }\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";
+ }
}
}
}
+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;
+}
+
+
/*
- * 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 );
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 );
+
};
#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;
/*
- * Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
+ * Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
*/
/* This file is part of Ragel.
* 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>
std::ostream &error();
char *fileNameFromStem( char *stemFile, char *suffix );
-#endif /* _RLCODEGEN_H */
+#endif /* _RLGEN_JAVA_H */
+++ /dev/null
-/*
- * 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";
- }
-}
-
+++ /dev/null
-/*
- * 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 */
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;