IT++ Logo Newcom Logo

parser.cpp

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

Generated on Thu Apr 19 14:14:57 2007 for IT++ by Doxygen 1.5.1