" Keywords
" FIXME: Enable the range keyword post 5.17.
" syntax keyword rlKeywords machine action context include range contained
-syntax keyword rlKeywords machine action context include export entry contained
+syntax keyword rlKeywords machine action context include export contained
syntax keyword rlExprKeywords when err lerr eof from to contained
" Case Labels
if ( name->numUses == name->numRefs ) {
assert( graph->entryPoints.find( name->id ) != 0 );
graph->unsetEntry( name->id );
+ assert( graph->entryPoints.find( name->id ) == 0 );
}
}
}
nameIndex = new NameInst*[nextNameId];
memset( nameIndex, 0, sizeof(NameInst*)*nextNameId );
fillNameIndex( rootName );
+ fillNameIndex( exportsRootName );
}
cerr << " ";
cerr << (nameInst->name != 0 ? nameInst->name : "<ANON>") <<
" id: " << nameInst->id <<
- " refs: " << nameInst->numRefs << endl;
+ " refs: " << nameInst->numRefs <<
+ " uses: " << nameInst->numUses << endl;
for ( NameVect::Iter name = nameInst->childVect; name.lte(); name++ )
printNameInst( *name, level+1 );
}
* is okay since generating part of the graph is usually only done when
* inspecting the compiled machine. */
+ /* Same story for extern entry point references. */
+
/* Flag this case so that the XML code generator is aware that we haven't
* looked up name references in actions. It can then avoid segfaulting. */
generatingSectionSubset = true;
/* Resolve action code name references. */
resolveActionNameRefs();
+ /* Force name references to the top level instantiations. */
+ for ( NameVect::Iter inst = rootName->childVect; inst.lte(); inst++ )
+ (*inst)->numRefs += 1;
+
FsmAp *mainGraph = 0;
FsmAp **graphs = new FsmAp*[instanceList.length()];
int numOthers = 0;
mainGraph = makeInstance( glel );
}
else {
- /* Check to see if the instance is ever referenced. */
- NameInst *nameInst = nextNameScope();
- if ( nameInst->anyRefsRec() )
- graphs[numOthers++] = makeInstance( glel );
- else {
- /* Need to walk over the name tree item. */
- NameFrame nameFrame = enterNameScope( true, 1 );
- popNameScope( nameFrame );
- }
+ /* Instantiate and store in others array. */
+ graphs[numOthers++] = makeInstance( glel );
}
}
struct VarDef
{
VarDef( char *name, JoinOrLm *joinOrLm )
- : name(name), joinOrLm(joinOrLm) { }
+ : name(name), joinOrLm(joinOrLm), isExport(false) { }
/* Parse tree traversal. */
FsmAp *walk( ParseData *pd );
char *name;
JoinOrLm *joinOrLm;
-
bool isExport;
- bool isEntry;
};
# Keywords.
token KW_Action, KW_AlphType, KW_Range, KW_GetKey, KW_Include, KW_Write,
KW_Machine, KW_When, KW_Eof, KW_Err, KW_Lerr, KW_To, KW_From,
- KW_Export, KW_Entry;
+ KW_Export;
# Specials in code blocks.
token KW_Break, KW_Exec, KW_Hold, KW_PChar, KW_Char, KW_Goto, KW_Call,
{
pd = new ParseData( fileName, sectionName, sectionLoc );
exportContext.append( false );
- entryContext.append( false );
}
int token( InputLoc &loc, int tokId, char *tokstart, int toklen );
NameRefList nameRefList;
Vector<bool> exportContext;
- Vector<bool> entryContext;
};
%% write token_defs;
statement: access_spec commit;
statement: variable_spec commit;
statement: export_block commit;
-statement: entry_block commit;
export_open: KW_Export
final {
exportContext.remove( exportContext.length()-1 );
};
-nonterm opt_entry
-{
- bool isSet;
-};
-
-entry_open: KW_Entry
- final {
- entryContext.append( true );
- };
-
-opt_entry: entry_open final { $$->isSet = true; };
-opt_entry: final { $$->isSet = false; };
-
-entry_block: entry_open '{' statement_list '}'
- final {
- entryContext.remove( entryContext.length()-1 );
- };
-
assignment:
- opt_export opt_entry machine_name '=' join ';' final {
+ opt_export machine_name '=' join ';' final {
/* Main machine must be an instance. */
bool isInstance = false;
- if ( strcmp($3->token.data, machineMain) == 0 ) {
- warning($3->token.loc) <<
+ if ( strcmp($2->token.data, machineMain) == 0 ) {
+ warning($2->token.loc) <<
"main machine will be implicitly instantiated" << endl;
isInstance = true;
}
/* Generic creation of machine for instantiation and assignment. */
- JoinOrLm *joinOrLm = new JoinOrLm( $5->join );
- tryMachineDef( $3->token.loc, $3->token.data, joinOrLm, isInstance );
+ JoinOrLm *joinOrLm = new JoinOrLm( $4->join );
+ tryMachineDef( $2->token.loc, $2->token.data, joinOrLm, isInstance );
if ( $1->isSet )
exportContext.remove( exportContext.length()-1 );
- if ( $2->isSet )
- entryContext.remove( entryContext.length()-1 );
};
instantiation:
- opt_export opt_entry machine_name TK_ColonEquals join_or_lm ';' final {
+ opt_export machine_name TK_ColonEquals join_or_lm ';' final {
/* Generic creation of machine for instantiation and assignment. */
- tryMachineDef( $3->token.loc, $3->token.data, $5->joinOrLm, true );
+ tryMachineDef( $2->token.loc, $2->token.data, $4->joinOrLm, true );
if ( $1->isSet )
exportContext.remove( exportContext.length()-1 );
- if ( $2->isSet )
- entryContext.remove( entryContext.length()-1 );
};
type token_type
newEl->isInstance = isInstance;
newEl->loc = loc;
newEl->value->isExport = exportContext[exportContext.length()-1];
- newEl->value->isEntry = entryContext[entryContext.length()-1];
/* It it is an instance, put on the instance list. */
if ( isInstance )
'to' => { token( KW_To ); };
'from' => { token( KW_From ); };
'export' => { token( KW_Export ); };
- 'entry' => { token( KW_Entry ); };
# Identifiers.
ident => { token( TK_Word, tokstart, tokend ); } ;
if ( !st.last() )
out << "\n";
-
}
out << " </state_list>\n";
}
+bool XMLCodeGen::writeNameInst( NameInst *nameInst )
+{
+ bool written = false;
+ if ( nameInst->parent != 0 )
+ written = writeNameInst( nameInst->parent );
+
+ if ( nameInst->name != 0 ) {
+ if ( written )
+ out << '_';
+ out << nameInst->name;
+ written = true;
+ }
+
+ return written;
+}
+
void XMLCodeGen::writeEntryPoints()
{
/* List of entry points other than start state. */
/* Get the name instantiation from nameIndex. */
NameInst *nameInst = pd->nameIndex[en->key];
StateAp *state = en->value;
- out << " <entry name=\"" << nameInst->name << "\">" <<
- state->alg.stateNum << "</entry>\n";
+ out << " <entry name=\"";
+ writeNameInst( nameInst );
+ out << "\">" << state->alg.stateNum << "</entry>\n";
}
out << " </entry_points>\n";
}
void writeLmOnLagBehind( InlineItem *item );
void writeExports();
+ bool writeNameInst( NameInst *nameInst );
void writeEntryPoints();
void writeGetKeyExpr();
void writeAccessExpr();
return ret;
}
+void FsmCodeGen::ENTRY_POINTS()
+{
+ for ( EntryNameVect::Iter en = entryPointNames; en.lte(); en++ ) {
+ STATIC_VAR( "int", DATA_PREFIX() + "en_" + *en ) <<
+ " = " << entryPointIds[en.pos()] << ";\n";
+ }
+ out << "\n";
+}
+
void FsmCodeGen::writeExports()
{
if ( exportList.length() > 0 ) {
void GET_TOKEND( ostream &ret, InlineItem *item );
void SUB_ACTION( ostream &ret, InlineItem *item,
int targState, bool inFinish );
+ void ENTRY_POINTS();
string ERROR_STATE();
string FIRST_FINAL_STATE();
STATIC_VAR( "int", ERROR() ) << " = " << ERROR_STATE() << ";\n"
"\n";
}
+
+ ENTRY_POINTS();
}
void TabCodeGen::COND_TRANSLATE()
}
-void JavaTabCodeGen::writeOutData()
+void JavaTabCodeGen::writeData()
{
/* 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. */
}
-void JavaTabCodeGen::writeOutExec()
+void JavaTabCodeGen::writeExec()
{
out <<
" {\n"
out << " }\n";
}
-void JavaTabCodeGen::writeOutEOF()
+void JavaTabCodeGen::writeEOF()
{
if ( redFsm->anyEofActions() ) {
out <<
return ret.str();
}
-void JavaTabCodeGen::writeOutInit()
+void JavaTabCodeGen::writeInit()
{
out << " {\n";
out << "\t" << CS() << " = " << START() << ";\n";
void COND_TRANSLATE();
void LOCATE_TRANS();
- virtual void writeOutExec();
- virtual void writeOutEOF();
- virtual void writeOutData();
- virtual void writeOutInit();
+ virtual void writeExec();
+ virtual void writeEOF();
+ virtual void writeData();
+ virtual void writeInit();
virtual void finishRagelDef();
void NEXT( ostream &ret, int nextDest, bool inFinish );
<< INDENT_D() << "end # cc _match" ;
}
-void RubyCodeGen::writeOutExec()
+void RubyCodeGen::writeExec()
{
out << INDENT_U() << "callcc do |_out|"
<< INDENT_S() << "_klen, _trans, _keys";
out << INDENT_D() << "end # cc _out" ;
}
-void RubyCodeGen::writeOutEOF()
+void RubyCodeGen::writeEOF()
{
if ( redFsm->anyEofActions() ) {
out << INDENT_S() << "_acts = " << EA() << "[" << CS() << "]"
}
-void RubyCodeGen::writeOutInit()
+void RubyCodeGen::writeInit()
{
out << INDENT_U() << "begin"
<< INDENT_S() << CS() << " = " << START();
}
-void RubyCodeGen::writeOutData()
+void RubyCodeGen::writeData()
{
/* 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. */
void COND_TRANSLATE();
void LOCATE_TRANS();
- virtual void writeOutExec();
- virtual void writeOutEOF();
- virtual void writeOutInit();
- virtual void writeOutData();
+ virtual void writeExec();
+ virtual void writeEOF();
+ virtual void writeInit();
+ virtual void writeData();
virtual void finishRagelDef();
protected: