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