/*
- * Copyright 2001-2007 Adrian Thurston <thurston@cs.queensu.ca>
+ * Copyright 2001-2007 Adrian Thurston <thurston@complang.org>
*/
/* This file is part of Ragel.
#include "version.h"
#include "common.h"
#include "xmlparse.h"
+#include "inputdata.h"
using std::istream;
using std::ostream;
" -x Run the frontend only: emit XML intermediate format\n"
" -V Generate a dot file for Graphviz\n"
" -p Display printable characters on labels\n"
-" -S <spec> FSM specification to output (for rlgen-dot)\n"
-" -M <machine> Machine definition/instantiation to output (for rlgen-dot)\n"
+" -S <spec> FSM specification to output (for graphviz output)\n"
+" -M <machine> Machine definition/instantiation to output (for graphviz output)\n"
"host language:\n"
" -C The host language is C, C++, Obj-C or Obj-C++ (default)\n"
" -D The host language is D\n"
void version()
{
cout << "Ragel State Machine Compiler version " VERSION << " " PUBDATE << endl <<
- "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
+ "Copyright (c) 2001-2008 by Adrian Thurston" << endl;
exit(0);
}
}
}
-int frontend( const char *inputFileName, const char *intermed )
+void process( const char *inputFileName )
{
+ bool wantComplete = true;
+ bool outputActive = true;
+
/* Open the input file for reading. */
assert( inputFileName != 0 );
ifstream *inFile = new ifstream( inputFileName );
- istream *inStream = inFile;
if ( ! inFile->is_open() )
error() << "could not open " << inputFileName << " for reading" << endp;
/* Used for just a few things. */
std::ostringstream hostData;
- if ( machineSpec == 0 && machineName == 0 )
- hostData << "<host line=\"1\" col=\"1\">";
+ /* Make the first input item. */
+ InputItem *firstInputItem = new InputItem;
+ firstInputItem->type = InputItem::HostData;
+ firstInputItem->loc.line = 1;
+ firstInputItem->loc.col = 1;
+ inputItems.append( firstInputItem );
- Scanner scanner( inputFileName, *inStream, hostData, 0, 0, 0, false );
+ Scanner scanner( inputFileName, *inFile, 0, 0, 0, false );
scanner.do_scan();
/* Finished, final check for errors.. */
if ( gblErrorCount > 0 )
- return 1;
+ exit(1);
/* Now send EOF to all parsers. */
terminateAllParsers();
/* Finished, final check for errors.. */
if ( gblErrorCount > 0 )
- return 1;
+ exit(1);
+
+ /* Bail on above error. */
+ if ( gblErrorCount > 0 )
+ exit(1);
+
+ /* Locate the backend program */
+ if ( generateDot ) {
+ wantComplete = false;
+ outputActive = false;
+ }
- if ( machineSpec == 0 && machineName == 0 )
- hostData << "</host>\n";
+ InputData inputData( inputFileName, outputActive, wantComplete );
+
+ /* Compiles machines. */
+ inputData.prepareMachineGen();
if ( gblErrorCount > 0 )
- return 1;
-
- ostream *outputFile = new ofstream( intermed );
+ exit(1);
+
+ inputData.openOutput();
+
+ /* Generates the reduced machine, which we use to write output. */
+ inputData.generateReduced();
- /* Write the machines, then the surrounding code. */
- writeMachines( *outputFile, hostData.str(), inputFileName );
+ if ( gblErrorCount > 0 )
+ exit(1);
+
+ inputData.openOutput2();
+ inputData.writeOutput();
+
+ /* Close the input and the intermediate file. */
+ delete inFile;
+
+ /* Bail on above error. */
+ if ( gblErrorCount > 0 )
+ exit(1);
- /* Close the intermediate file. */
- delete outputFile;
+ /* If writing to a file, delete the ostream, causing it to flush.
+ * Standard out is flushed automatically. */
+ if ( outputFileName != 0 ) {
+ delete outStream;
+ delete outFilter;
+ }
- return gblErrorCount > 0;
+ /* Finished, final check for errors.. */
+ if ( gblErrorCount > 0 ) {
+ /* If we opened an output file, remove it. */
+ if ( outputFileName != 0 )
+ unlink( outputFileName );
+ exit(1);
+ }
}
char *makeIntermedTemplate( const char *baseFileName )
}
-void cleanExit( const char *intermed, int status )
-{
- unlink( intermed );
- exit( status );
-}
-
-void backend( const char *intermed )
-{
- const char *xmlInputFileName = intermed;
-
- bool wantComplete = true;
- bool outputActive = true;
-
- /* Open the input file for reading. */
- ifstream *inFile = new ifstream( xmlInputFileName );
- inStream = inFile;
- if ( ! inFile->is_open() )
- error() << "could not open " << xmlInputFileName << " for reading" << endl;
-
- /* Bail on above error. */
- if ( gblErrorCount > 0 )
- exit(1);
-
- /* Locate the backend program */
- if ( generateDot ) {
- wantComplete = false;
- outputActive = false;
- }
-
- xml_parse( *inStream, xmlInputFileName, outputActive, wantComplete );
-
- /* If writing to a file, delete the ostream, causing it to flush.
- * Standard out is flushed automatically. */
- if ( outputFileName != 0 ) {
- delete outStream;
- delete outFilter;
- }
-
- /* Finished, final check for errors.. */
- if ( gblErrorCount > 0 ) {
- /* If we opened an output file, remove it. */
- if ( outputFileName != 0 )
- unlink( outputFileName );
- exit(1);
- }
-}
/* Main, process args and call yyparse to start scanning input. */
int main( int argc, const char **argv )
{
const char *inputFileName = 0;
processArgs( argc, argv, inputFileName );
+
/* If -M or -S are given and we're not generating a dot file then invoke
* the frontend. These options are not useful with code generators. */
"\" is the same as the input file" << endp;
}
- const char *intermed = openIntermed( inputFileName, outputFileName );
- frontend( inputFileName, intermed );
- backend( intermed );
+ process( inputFileName );
/* Clean up the intermediate. */
- cleanExit( intermed, 0 );
+ exit( 0 );
return 0;
}