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 Sun Dec 9 17:26:17 2007 for IT++ by Doxygen 1.5.4