#include <fstream>
#include "fsm.h"
#include "parser.h"
#include "optimizer.h"
#include "mkdfa.h"
Include dependency graph for main.C:
Go to the source code of this file.
Functions | |
int | main (int argc, char *argv[]) |
Main function for the fsm program. More... |
|
Main function for the fsm program.
Definition at line 95 of file main.C. 00095 { 00096 static const string USAGE("fsm [-o] inputfile outputfile [inputstring trace]"); 00097 00098 try { 00099 // There must be at least two arguments. 00100 00101 if (argc<3) { 00102 cerr << USAGE << endl; 00103 return 1; 00104 } 00105 00106 // Check whether optimization is requested. 00107 00108 bool optimize = ( string(argv[1]) == "-o" ); 00109 00110 // If optimization is requested, at least 3 arguments must be present. 00111 if (optimize && (argc<4)) { 00112 cerr << USAGE << endl; 00113 return 1; 00114 } 00115 00116 int fn_index(1); // index of first argument after optional '-o' 00117 00118 // If optimization is requested, the first filename argumengt is at index 2. 00119 00120 if (optimize) 00121 ++fn_index; 00122 00123 // Is tracing requested? 00124 00125 bool tracing(false); 00126 00127 if (argc > fn_index+2) { // There are arguments beyond input/output automaton. 00128 tracing = true; 00129 if (argc != fn_index + 4) { // need exactly 2 filenames 00130 cerr << USAGE << endl; 00131 return 1; 00132 } 00133 } 00134 00135 // Determine input and output filenames. 00136 00137 const char* input_fnm(argv[fn_index]); 00138 const char* output_fnm(argv[fn_index+1]); 00139 00140 // Try to open the input file. 00141 00142 ifstream ifs(input_fnm); 00143 00144 if (!ifs) { 00145 cerr << "Cannot open \"" << input_fnm << "\" for reading" << endl; 00146 return 2; 00147 } 00148 00149 // Try to open the output file. 00150 00151 ofstream ofs(output_fnm); 00152 if (!ofs) { 00153 cerr << "Cannot open \"" << output_fnm << "\" for writing" << endl; 00154 return 2; 00155 } 00156 00157 00158 // The input automaton is *fsm. 00159 ref<Fsm> fsm = Parser(ifs).parse(); 00160 // The deterministic version of *fsm will be called *dfsm. 00161 ref<Fsm> dfsm; 00162 // The optimized version of *dfsm will be called *ofsm. 00163 ref<Fsm> ofsm; 00164 00165 // Check whether parsing went ok. 00166 00167 if (!fsm) { 00168 cerr << "Syntax error in \"" << input_fnm << "\"" << endl; 00169 return 3; 00170 } 00171 00172 // Generate dfsm out of fsm. 00173 00174 if (fsm->is_deterministic()) // already deterministic. 00175 dfsm = fsm; 00176 else 00177 dfsm = DfaMaker(*fsm).mkdfa(); 00178 00179 // Optimize dfsm, yielding ofsm, if requested. 00180 00181 if (optimize) 00182 ofsm = Optimizer(*dfsm).optimize(); 00183 else 00184 ofsm = dfsm; 00185 00186 ofs << *ofsm; 00187 00188 // Run trace, if needed. 00189 00190 if (tracing) { 00191 const char* trace_in_fn(argv[fn_index+2]); 00192 const char* trace_out_fn(argv[fn_index+3]); 00193 00194 ifstream tifs(trace_in_fn); 00195 00196 if (!tifs) { 00197 cerr << "Cannot open \"" << trace_in_fn << "\" for reading" << endl; 00198 return 2; 00199 } 00200 00201 ofstream tofs(trace_out_fn); 00202 00203 if (!tofs) { 00204 cerr << "Cannot open \"" << trace_out_fn << "\" for writing" << endl; 00205 return 2; 00206 } 00207 00208 try { // There could be an exception, e.g. because of a bad Symbol. 00209 Fsm::State q(ofsm->initial_state()); 00210 Fsm::Symbol a; 00211 00212 while (tifs >> a) { 00213 tofs << q << ": " << a << " => "; 00214 q = ofsm->ddelta(q,a); 00215 tofs << q << "\n"; 00216 } 00217 00218 if (ofsm->is_final(q)) 00219 tofs << "accepted"; 00220 else 00221 tofs << "not accepted"; 00222 tofs << "\n"; 00223 } 00224 catch (exception& e) { 00225 tofs << "error: " << e.what() << "\n"; 00226 cerr << "error: " << e.what() << endl; 00227 return 3; 00228 } 00229 } 00230 00231 return 0; 00232 } 00233 catch (exception& e) { 00234 cerr << "Error: " << e.what() << endl; 00235 return -1; 00236 } 00237 } |