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