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