IT++ Logo

parser.cpp

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Tue Nov 23 08:47:56 2010 for IT++ by Doxygen 1.6.1