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

Generated on Wed Jul 27 2011 16:27:04 for IT++ by Doxygen 1.7.4