IT++ Logo Newcom Logo

parser.cpp

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

Generated on Fri Jun 8 00:37:33 2007 for IT++ by Doxygen 1.5.2