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