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   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
SourceForge Logo

Generated on Mon Jan 7 22:28:56 2008 for IT++ by Doxygen 1.5.4