00001 00035 #include <itpp/base/parser.h> 00036 #include <fstream> 00037 00038 00039 using std::cout; 00040 using std::endl; 00041 00042 namespace itpp { 00043 00044 Parser::Parser() 00045 { 00046 VERBOSE=true; 00047 } 00048 00049 Parser::Parser(const std::string &filename) 00050 { 00051 VERBOSE=true; 00052 init(filename); 00053 } 00054 00055 Parser::Parser(int argc, char *argv[]) 00056 { 00057 VERBOSE=true; 00058 init(argc,argv); 00059 } 00060 00061 Parser::Parser(const std::string &filename, int argc, char *argv[]) 00062 { 00063 VERBOSE=true; 00064 init(filename, argc, argv); 00065 } 00066 00067 Parser::Parser(const Array<std::string> &setup) 00068 { 00069 VERBOSE=true; 00070 init(setup); 00071 } 00072 00073 void Parser::pre_parsing(void) 00074 { 00075 int i, j, n, k; 00076 int count = 0; 00077 int size = SetupStrings.size(); 00078 bool cont_line; 00079 std::string Line, NewLine; 00080 Array<std::string> TempSetupStrings; 00081 00082 // Remove lines starting with '%' or have zero length: 00083 for (i=0; i<size; i++) { 00084 Line = SetupStrings(i); 00085 if ((Line[0]!='%') && (Line.length() != 0)) { 00086 SetupStrings(count) = Line; 00087 count++; 00088 } 00089 } 00090 SetupStrings.set_size(count,true); 00091 size = SetupStrings.size(); 00092 00093 //Check for '...' continuation as in Matlab: 00094 count = 0; 00095 NewLine = ""; 00096 for (i=0; i<SetupStrings.size(); i++) { 00097 Line = SetupStrings(i); 00098 n = Line.size(); 00099 cont_line = false; 00100 for (k=0; k<(n-2); k++) { 00101 if ((Line[k]=='.') && (Line[k+1]=='.') && (Line[k+2]=='.')) { 00102 cont_line = true; break; 00103 } 00104 } 00105 if (cont_line) { 00106 for (j=0; j<k; j++) { NewLine += Line[j]; } 00107 } else { 00108 NewLine += Line; 00109 SetupStrings(count) = NewLine; 00110 count++; 00111 NewLine = ""; 00112 } 00113 } 00114 SetupStrings.set_size(count,true); 00115 00116 //Strip unneccesary blanks, tabs, and newlines: 00117 size = SetupStrings.size(); 00118 for (i=0; i<size; i++) { 00119 NewLine = ""; 00120 Line = SetupStrings(i); 00121 n = Line.length(); 00122 j = 0; //counter in Line 00123 while (j<n) { 00124 switch (Line[j]) { 00125 case '\n': 00126 //Remove newlines 00127 j++; 00128 break; 00129 case ' ': 00130 //Remove blanks 00131 j++; 00132 break; 00133 case '\t': 00134 //Remove tabs 00135 j++; 00136 break; 00137 case '[': 00138 //Don't remove blanks between '[' and ']' 00139 while ( (Line[j] != ']') && ( j < n ) ) { NewLine += Line[j]; j++; } 00140 if (j<n) { NewLine += Line[j]; j++; } 00141 break; 00142 case '{': 00143 //Don't remove blanks between '{' and '}' 00144 while ( (Line[j] != '}') && ( j < n ) ) { NewLine += Line[j]; j++; } 00145 if (j<n) { NewLine += Line[j]; j++; } 00146 break; 00147 case '"': 00148 //Don't remove blanks between '"' and '"' 00149 NewLine += Line[j]; j++; //Read in the first '"' 00150 while ( (Line[j] != '"') && ( j < n ) ) { NewLine += Line[j]; j++; } 00151 NewLine += Line[j]; j++; 00152 break; 00153 case '\'': 00154 //Don't remove blanks between '\'' and '\'' 00155 NewLine += Line[j]; j++; //Read in the first '\'' 00156 while ( (Line[j] != '\'') && ( j < n ) ) { NewLine += Line[j]; j++; } 00157 NewLine += Line[j]; j++; 00158 break; 00159 case '%': 00160 //Remove trailing comments 00161 j = n; 00162 break; 00163 default: 00164 //Keep the current character: 00165 NewLine += Line[j]; j++; 00166 break; 00167 } 00168 } 00169 SetupStrings(i) = NewLine; 00170 } 00171 00172 // Split lines with several expressions (i.e. a=3;b=[1 2 3],c="Hello World") on the same line 00173 // (separated by comma or semicolon) 00174 TempSetupStrings.set_size(size,false); 00175 count = 0; //Counter in TempSetupStrings 00176 for (i=0; i<size; i++) { 00177 00178 NewLine = ""; 00179 Line = SetupStrings(i); 00180 n = Line.length(); 00181 j = 0; 00182 00183 while (j<n) { 00184 00185 switch (Line[j]) { 00186 00187 case '[': 00188 //A vector or a matrix 00189 while ( (Line[j] != ']') && ( j < n ) ) { NewLine += Line[j]; j++; } 00190 if (Line[j]==']') { NewLine += Line[j]; j++; } 00191 if (j==n) { 00192 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00193 TempSetupStrings(count) = NewLine; NewLine = ""; count++; 00194 } 00195 break; 00196 00197 case '"': 00198 //A string 00199 NewLine += Line[j]; j++; //Read in the first '"' 00200 while ( (Line[j] != '"') && ( j < n ) ) { NewLine += Line[j]; j++; } 00201 if (Line[j]=='"') { NewLine += Line[j]; j++; } 00202 if (j==n) { 00203 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00204 TempSetupStrings(count) = NewLine; NewLine = ""; count++; 00205 } 00206 break; 00207 00208 00209 case '\'': 00210 //A string 00211 NewLine += Line[j]; j++; //Read in the first '\'' 00212 while ( (Line[j] != '\'') && ( j < n ) ) { NewLine += Line[j]; j++; } 00213 if (Line[j]=='\'') { NewLine += Line[j]; j++; } 00214 if (j==n) { 00215 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00216 TempSetupStrings(count) = NewLine; NewLine = ""; count++; 00217 } 00218 break; 00219 00220 case ',': 00221 //Expression ends here 00222 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00223 TempSetupStrings(count) = NewLine; 00224 NewLine = ""; count++; j++; 00225 break; 00226 00227 case ';': 00228 //Expression ends here 00229 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00230 TempSetupStrings(count) = NewLine + ';'; 00231 NewLine = ""; count++; j++; 00232 break; 00233 00234 default: 00235 //Copy the current character: 00236 NewLine += Line[j]; 00237 j++; 00238 if (j==n) { 00239 if (count>=TempSetupStrings.size()) { TempSetupStrings.set_size(2*count,true); } 00240 TempSetupStrings(count) = NewLine; NewLine = ""; count++; 00241 } 00242 break; 00243 00244 } 00245 00246 } 00247 00248 } 00249 TempSetupStrings.set_size(count,true); 00250 SetupStrings = TempSetupStrings; 00251 } 00252 00253 void Parser::init(const std::string &filename) 00254 { 00255 std::string Line; 00256 SetupStrings.set_size(0,false); 00257 std::ifstream SetupFile(filename.c_str()); 00258 it_assert(SetupFile.is_open(), 00259 "Parser::init(): Could not open `" + filename + "' file"); 00260 00261 while (getline(SetupFile,Line,'\n')) { 00262 SetupStrings.set_size( SetupStrings.size() + 1, true ); 00263 SetupStrings( SetupStrings.size() - 1 ) = Line; 00264 } 00265 00266 SetupFile.close(); 00267 pre_parsing(); 00268 } 00269 00270 void Parser::init(int argc, char *argv[]) 00271 { 00272 SetupStrings.set_size(argc); 00273 int i; 00274 00275 for (i=0; i<argc; i++) { 00276 SetupStrings(i) = argv[i]; 00277 } 00278 pre_parsing(); 00279 } 00280 00281 void Parser::init(const std::string &filename, int argc, char *argv[]) 00282 { 00283 std::string Line; 00284 int i; 00285 std::ifstream SetupFile(filename.c_str()); 00286 it_assert(SetupFile.is_open(), 00287 "Parser::init(): Could not open `" + filename + "' file"); 00288 00289 //Read the command line parameters: 00290 SetupStrings.set_size(argc); 00291 for (i=0; i<argc; i++) { 00292 SetupStrings(i) = argv[i]; 00293 } 00294 00295 //Read the file parameters: 00296 while (getline(SetupFile,Line,'\n')) { 00297 SetupStrings.set_size( SetupStrings.size() + 1, true ); 00298 SetupStrings( SetupStrings.size() - 1 ) = Line; 00299 } 00300 00301 SetupFile.close(); 00302 pre_parsing(); 00303 } 00304 00305 void Parser::init(const Array<std::string> &setup) 00306 { 00307 SetupStrings = setup; 00308 pre_parsing(); 00309 } 00310 00311 void Parser::set_silentmode(bool v) 00312 { 00313 VERBOSE=!v; 00314 } 00315 00316 bool Parser::exist(const std::string &name) 00317 { 00318 bool error_flag, print_flag; 00319 std::string temp = findname( name, error_flag, print_flag ); 00320 if (error_flag) { 00321 return false; 00322 } else { 00323 return true; 00324 } 00325 } 00326 00327 template<> 00328 bool Parser::get(std::string &var, const std::string &name, int num) 00329 { 00330 bool error_flag, print_flag; 00331 std::string str = findname(name, error_flag, print_flag, num); 00332 if (error_flag) { 00333 if (VERBOSE) { 00334 cout << name << " = '" << var << "';" << endl; 00335 } 00336 } else { 00337 var = str; 00338 if (print_flag) { 00339 cout << name << " = '" << var << "'" << endl; 00340 } else if (VERBOSE) { 00341 cout << name << " = '" << var << "';" << endl; 00342 } 00343 } 00344 return !error_flag; 00345 } 00346 00347 bool Parser::get_bool(const std::string &name, int num) 00348 { 00349 bool out; 00350 bool error_flag, print_flag; 00351 out = atof(findname(name,error_flag,print_flag,num).c_str())==1; 00352 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00353 if (print_flag) { cout << "Parsing bool : " << name << " = " << out << endl; } 00354 return out; 00355 } 00356 00357 int Parser::get_int(const std::string &name, int num) 00358 { 00359 int out; 00360 bool error_flag, print_flag; 00361 out = int(atof(findname(name,error_flag,print_flag,num).c_str())); 00362 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00363 if (print_flag) { cout << "Parsing int : " << name << " = " << out << endl; } 00364 return out; 00365 } 00366 00367 double Parser::get_double(const std::string &name, int num) 00368 { 00369 double out; 00370 bool error_flag, print_flag; 00371 out = atof(findname(name,error_flag,print_flag,num).c_str()); 00372 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00373 if (print_flag) { cout << "Parsing double: " << name << " = " << out << endl; } 00374 return out; 00375 } 00376 00377 std::string Parser::get_string(const std::string &name, int num) 00378 { 00379 std::string out; 00380 bool error_flag, print_flag; 00381 out = findname(name,error_flag,print_flag,num); 00382 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00383 if (print_flag) { cout << "Parsing string: " << name << " = " << out << endl; } 00384 return out; 00385 } 00386 00387 vec Parser::get_vec(const std::string &name, int num) 00388 { 00389 vec out; 00390 bool error_flag, print_flag; 00391 out = vec(findname(name,error_flag,print_flag,num)); 00392 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00393 if (print_flag) { cout << "Parsing vec : " << name << " = " << out << endl; } 00394 return out; 00395 } 00396 00397 ivec Parser::get_ivec(const std::string &name, int num) 00398 { 00399 ivec out; 00400 bool error_flag, print_flag; 00401 out = ivec(findname(name,error_flag,print_flag,num)); 00402 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00403 if (print_flag) { cout << "Parsing ivec : " << name << " = " << out << endl; } 00404 return out; 00405 } 00406 00407 svec Parser::get_svec(const std::string &name, int num) 00408 { 00409 svec out; 00410 bool error_flag, print_flag; 00411 out = svec(findname(name,error_flag,print_flag,num)); 00412 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00413 if (print_flag) { cout << "Parsing svec : " << name << " = " << out << endl; } 00414 return out; 00415 } 00416 00417 bvec Parser::get_bvec(const std::string &name, int num) 00418 { 00419 bvec out; 00420 bool error_flag, print_flag; 00421 out = bvec(findname(name,error_flag,print_flag,num)); 00422 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00423 if (print_flag) { cout << "Parsing bvec : " << name << " = " << out << endl; } 00424 return out; 00425 } 00426 00427 mat Parser::get_mat(const std::string &name, int num) 00428 { 00429 mat out; 00430 bool error_flag, print_flag; 00431 out = mat(findname(name,error_flag,print_flag,num)); 00432 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00433 if (print_flag) { cout << "Parsing mat : " << name << " = " << out << endl; } 00434 return out; 00435 } 00436 00437 imat Parser::get_imat(const std::string &name, int num) 00438 { 00439 imat out; 00440 bool error_flag, print_flag; 00441 out = imat(findname(name,error_flag,print_flag,num)); 00442 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00443 if (print_flag) { cout << "Parsing imat : " << name << " = " << out << endl; } 00444 return out; 00445 } 00446 00447 smat Parser::get_smat(const std::string &name, int num) 00448 { 00449 smat out; 00450 bool error_flag, print_flag; 00451 out = smat(findname(name,error_flag,print_flag,num)); 00452 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00453 if (print_flag) { cout << "Parsing smat : " << name << " = " << out << endl; } 00454 return out; 00455 } 00456 00457 bmat Parser::get_bmat(const std::string &name, int num) 00458 { 00459 bmat out; 00460 bool error_flag, print_flag; 00461 out = bmat(findname(name,error_flag,print_flag,num)); 00462 if (error_flag) { it_error("Parser: Can not find variable: " + name); } 00463 if (print_flag) { cout << "Parsing bmat : " << name << " = " << out << endl; } 00464 return out; 00465 } 00466 00467 std::string Parser::findname(const std::string &name, bool &error_flag, bool &print_flag, int num, bool keep_brackets) 00468 { 00469 std::string Name, Out, Line, Temp; 00470 int n, j=0, i=0, index=-1; 00471 bool found = false, vec_mat = false; 00472 00473 error_flag = false; 00474 print_flag = false; 00475 if (num<0) { num=0; } 00476 Name = ""; 00477 00478 // Go through all words in input string to find a match 00479 while (i < SetupStrings.size()) { 00480 Line = SetupStrings(i); i++; 00481 00482 // Find equal sign "=", and take the left part to be the Name 00483 if (Line.find_first_of("=") != std::string::npos) { 00484 Name = Line.substr(0, Line.find_first_of("=")); 00485 } else { 00486 Name = ""; 00487 } 00488 00489 if (Name==name) { 00490 if (found) { 00491 //cout << "Parser Warning: Duplicate Entry of variable " << name << endl; 00492 } else { 00493 found = true; 00494 index = i-1; 00495 } 00496 } 00497 } 00498 00499 // if we have a match 00500 if ( (found) && (index+num <= SetupStrings.size()) ) { 00501 Line = SetupStrings(index+num); 00502 if (num != 0) { 00503 Temp = Line; 00504 } else { 00505 Temp = Line.substr(Line.find_first_of("=")+1); 00506 } 00507 } else { 00508 error_flag = true; 00509 return ""; 00510 } 00511 00512 //Remove [, ],",' and ending ;. Set the print_flag: 00513 n = Temp.size(); 00514 Out = ""; 00515 for (i=0; i<n; i++) { 00516 switch (Temp[i]) { 00517 case '[': 00518 vec_mat = true; 00519 if (keep_brackets) { Out += Temp[i]; } 00520 if (i==(n-1)) { print_flag = true; } 00521 break; 00522 case ']': 00523 if (keep_brackets) { Out += Temp[i]; } 00524 if (i==(n-1)) { print_flag = true; } 00525 break; 00526 case '"': 00527 if (i==(n-1)) { print_flag = true; } 00528 break; 00529 case '\'': 00530 if (i==(n-1)) { print_flag = true; } 00531 break; 00532 case ';': 00533 if (i==(n-1)) { print_flag = false; } else { Out += Temp[i]; } 00534 break; 00535 default: 00536 Out += Temp[i]; 00537 if (i==(n-1)) { print_flag = true; } 00538 break; 00539 } 00540 } 00541 00542 //Final parsing of vectors and matrices: 00543 if (vec_mat) { 00544 00545 Temp = Out; 00546 Out = ""; 00547 n = Temp.size(); 00548 j = 0; 00549 00550 while ((Temp[j] == ' ') || (Temp[j] == '\t') || (Temp[j] == '\n')) { j++; } //Remove spaces/tabs/newline in beginning 00551 while ((Temp[n-1] == ' ') || (Temp[n-1] == '\t') || (Temp[n-1] == '\n')) { n--; } //Remove spaces/tabs/newline at the end 00552 00553 while (j<n) { 00554 00555 //Read in data element: 00556 while ((Temp[j]!=' ')&&(Temp[j]!='\t')&&(Temp[j]!='\n')&&(Temp[j]!=',')&&(Temp[j]!=';')&&(j<n)) { 00557 Out += Temp[j]; j++; 00558 } 00559 00560 //Read separator: 00561 if (j<(n-1)) { 00562 //Remove spaces before separator 00563 while (((Temp[j]==' ')||(Temp[j]=='\t')||(Temp[j]=='\n'))&&(j<n)) { j++; } 00564 //Insert Separator: 00565 if (j<n) { 00566 if (Temp[j]==';') { Out += ';'; j++; } 00567 else if (Temp[j]==',') { Out += Temp[j]; j++; } 00568 else if (Temp[j]=='+') { Out += ','; Out += Temp[j]; j++; } 00569 else if (Temp[j]=='-') { Out += ','; Out += Temp[j]; j++; } 00570 else { Out += ','; } 00571 } 00572 //Remove spaces after separator: 00573 while (((Temp[j]==' ')||(Temp[j]=='\t')||(Temp[j]=='\n'))&&(j<n)) { j++; } 00574 } 00575 00576 } 00577 00578 } 00579 if (!VERBOSE) print_flag=false; 00580 return Out; 00581 } 00582 00583 } // namespace itpp
Generated on Thu Apr 19 14:14:57 2007 for IT++ by Doxygen 1.5.1