pelib  2.0.0
src/AmplInput.cpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Pelib.
00005 
00006  Pelib is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  Pelib is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with Pelib. If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 #include <iostream>
00022 #include <cstdlib>
00023 #include <fstream>
00024 #include <string>
00025 #include <boost/regex.hpp>
00026 #include <boost/algorithm/string.hpp>
00027 #include <iomanip>
00028 
00029 #include <pelib/AmplInput.hpp>
00030 #include <pelib/AmplInputScalar.hpp>
00031 #include <pelib/AmplInputVector.hpp>
00032 #include <pelib/AmplInputSet.hpp>
00033 #include <pelib/AmplInputMatrix.hpp>
00034 #include <pelib/AmplDataParser.hpp>
00035 
00036 #include <pelib/ParseException.hpp>
00037 #include <pelib/CastException.hpp>
00038 #include <pelib/PelibException.hpp>
00039 
00040 #ifdef debug
00041 #undef debug
00042 #endif
00043 
00044 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl;
00045 
00046 using namespace std;
00047 using namespace boost::algorithm;
00048 
00049 namespace pelib
00050 {
00051         /*
00052         AmplInput::AmplInput()
00053         {
00054                 // Add parsers
00055                 addParsers();
00056                                 
00057                 // Add interpreters
00058                 addOutputs();
00059         }
00060 
00061         AmplInput::AmplInput(std::vector<AmplInputDataParser*> parsers,
00062                         std::vector<AmplInputDataOutput*> outputs)
00063         {
00064                 this->parsers = parsers;
00065                 this->outputs = outputs;
00066         }
00067         */
00068 
00069         AmplInput::AmplInput(std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> > handlers)
00070         {
00071                 this->parsers = handlers.first;
00072                 this->outputs = handlers.second;
00073         }
00074 
00075         AmplInput::~AmplInput()
00076         {
00077                 deleteParsers();
00078                 deleteOutputs();                        
00079         }
00080         
00081         void
00082         AmplInput::deleteParsers()
00083         {
00084                 
00085                 for(std::vector<AmplInputDataParser*>::iterator i = parsers.begin(); i != parsers.end(); i = parsers.erase(i))
00086                 {
00087                         delete *i;
00088                 }
00089         }
00090 
00091         void
00092         AmplInput::deleteOutputs()
00093         {
00094                 for(std::vector<AmplInputDataOutput*>::iterator i = outputs.begin(); i != outputs.end(); i = outputs.erase(i))
00095                 {
00096                         delete *i;
00097                 }
00098         }
00099 
00100         AmplInput&
00101         AmplInput::operator=(const AmplInput &amplInput)
00102         {
00103                 deleteParsers();
00104                 deleteOutputs();
00105 
00106                 for(std::vector<AmplInputDataParser*>::const_iterator i = amplInput.parsers.begin(); i != amplInput.parsers.end(); i++)
00107                 {
00108                         parsers.push_back((*i)->clone());
00109                 }
00110 
00111                 for(std::vector<AmplInputDataOutput*>::const_iterator i = amplInput.outputs.begin(); i != amplInput.outputs.end(); i++)
00112                 {
00113                         outputs.push_back((*i)->clone());
00114                 }
00115 
00116                 return *this;
00117         }
00118 
00119         Algebra
00120         AmplInput::parse(std::istream &ampl_data) const 
00121         {
00122                 Algebra record;
00123                 std::string line;
00124                 std::string first_only = "\\1";
00125                 std::string nothing = "";
00126 
00127                 // Remove all comments from input before starting to parse it
00128                 std::stringstream noComment;
00129                 while(!getline(ampl_data, line).fail())
00130                 {
00131                         boost::regex comment("([^#]*)#[^$]*$");
00132                         line = boost::regex_replace(line, comment, first_only, boost::match_default | boost::format_all);
00133                         boost::regex surrounding_space("^[\\n\\s]*([^\\s\n]*)[\\s\n]*$");
00134                         line = boost::regex_replace(line, surrounding_space, first_only, boost::match_default | boost::format_all);
00135 
00136                         if(line.compare("") != 0)
00137                         {
00138                                 noComment << line << std::endl;
00139                         }
00140                 }
00141 
00142                 // Parse input
00143                 while(!getline(noComment, line, ';').fail())
00144                 {
00145                         trim(line);     
00146                         boost::regex surrounding_space("^[\\n\\s]*([^\\s\\n].*?)[\\s\\n]*$");
00147                         line = boost::regex_replace(line, surrounding_space, first_only, boost::match_default | boost::format_all);
00148 
00149                         if(line.length() == 0)
00150                         {
00151                                 continue;
00152                         }
00153 
00154                         std::vector<AmplInputDataParser*>::const_iterator iter;
00155                         for(iter = parsers.begin(); iter != parsers.end(); iter++)
00156                         {
00157                                 AmplInputDataParser *parser = *iter;
00158                                 try {
00159                                         std::istringstream istr(line);
00160                                         std::istream &str = istr;
00161                                         AlgebraData *data = parser->parse(str);
00162                                         record.insert(data);
00163 
00164                                         // No need to try another parser; proceed with the next token
00165                                         break;
00166                                 } catch (ParseException &e)
00167                                 {
00168                                         //std::cerr << e.what() << "Trying next parser." << std::endl;
00169                                 }
00170                         }
00171 
00172                         if(iter == parsers.end())
00173                         {
00174                                 std::vector<AmplInputDataParser*> parsers = stringParsers();
00175                                 for(iter = parsers.begin(); iter != parsers.end(); iter++)
00176                                 {
00177                                         AmplInputDataParser *parser = *iter;
00178                                         try {
00179                                                 std::istringstream istr(line);
00180                                                 std::istream &str = istr;
00181                                                 AlgebraData *data = parser->parse(str);
00182                                                 record.insert(data);
00183 
00184                                                 // No need to try another parser; proceed with the next token
00185                                                 break;
00186                                         } catch (ParseException &e)
00187                                         {
00188                                                 //std::cerr << e.what() << "Trying next parser." << std::endl;
00189                                         }
00190                                 }
00191 
00192                                 if(iter == parsers.end())
00193                                 {
00194                                         //throw ParseException(std::string("No parser was suitable to the token \"").append(line).append("\"."));
00195                                 }
00196                         }
00197                 }
00198                 
00199                 return record;
00200         }
00201 
00202         void
00203         AmplInput::dump(std::ostream& o, const Algebra &record) const
00204         {
00205                 const std::map<std::string, const AlgebraData * const> records = record.getAllRecords();
00206                 for (std::map<std::string, const AlgebraData * const>::const_iterator rec = records.begin(); rec != records.end(); rec++)
00207                 {
00208                         dump(o, rec->second);
00209                 }
00210         }
00211 
00212         void
00213         AmplInput::dump(std::ostream& o, const AlgebraData *data) const
00214         {
00215                 std::vector<AmplInputDataOutput*>::const_iterator out;
00216                 for (out = outputs.begin(); out != outputs.end(); out++)
00217                 {
00218                         const AmplInputDataOutput *output = *out;
00219                         try
00220                         {
00221                                 output->dump(o, data);
00222                                 break;
00223                         } catch(CastException &e)
00224                         {
00225                                 // No suitable element to output
00226                                 // Couldn't cast the element to record: just let that go and try again with next element
00227                         }
00228                 }
00229 
00230                 if(out == outputs.end())
00231                 {
00232                         vector<AmplInputDataOutput*> string_outputs = stringOutputs();
00233                         for (out = string_outputs.begin(); out != string_outputs.end(); out++)
00234                         {
00235                                 const AmplInputDataOutput *output = *out;
00236                                 try
00237                                 {
00238                                         output->dump(o, data);
00239                                         break;
00240                                 } catch(CastException &e)
00241                                 {
00242                                         // No suitable element to output
00243                                         // Couldn't cast the element to record: just let that go and try again with next element
00244                                 }
00245                         }
00246 
00247                         if(out == string_outputs.end())
00248                         {
00249                                 throw PelibException("Could not find a suitable output format for data record of name \"" + string(data->getName()) + "\".");
00250                         }
00251                 }
00252         }
00253 
00254         void
00255         AmplInput::dump(std::ostream& o, const AlgebraData &data) const
00256         {
00257                 dump(o, &data);
00258         }
00259 
00260         std::vector<AmplInputDataParser*> AmplInput::floatParsers()
00261         {
00262                 std::vector<AmplInputDataParser*> parsers;
00263                 
00264                 parsers.push_back(new AmplInputScalar<float>(false));
00265                 parsers.push_back(new AmplInputVector<int, float>(false));
00266                 parsers.push_back(new AmplInputSet<float>(false));
00267                 parsers.push_back(new AmplInputMatrix<int, int, float>(false));
00268 
00269                 return parsers;
00270         }
00271                 
00272         std::vector<AmplInputDataOutput*> AmplInput::floatOutputs()
00273         {
00274                 std::vector<AmplInputDataOutput*> outputs;
00275 
00276                 outputs.push_back(new AmplInputScalar<float>(false));
00277                 outputs.push_back(new AmplInputVector<int, float>(false));
00278                 outputs.push_back(new AmplInputSet<float>(false));
00279                 outputs.push_back(new AmplInputMatrix<int, int, float>(false));
00280 
00281                 return outputs;
00282         }
00283 
00284         std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> > AmplInput::floatHandlers()
00285         {
00286                 return std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> >(AmplInput::floatParsers(), AmplInput::floatOutputs());
00287         }
00288 
00289         std::vector<AmplInputDataParser*> AmplInput::stringParsers()
00290         {
00291                 std::vector<AmplInputDataParser*> parsers;
00292                 
00293                 parsers.push_back(new AmplInputScalar<string>(false));
00294                 parsers.push_back(new AmplInputVector<int, string>(false));
00295                 parsers.push_back(new AmplInputSet<string>(false));
00296                 parsers.push_back(new AmplInputMatrix<int, int, string>(false));
00297 
00298                 return parsers;
00299         }
00300                 
00301         std::vector<AmplInputDataOutput*> AmplInput::stringOutputs()
00302         {
00303                 std::vector<AmplInputDataOutput*> outputs;
00304 
00305                 outputs.push_back(new AmplInputScalar<string>(false));
00306                 outputs.push_back(new AmplInputVector<int, string>(false));
00307                 outputs.push_back(new AmplInputSet<string>(false));
00308                 outputs.push_back(new AmplInputMatrix<int, int, string>(false));
00309 
00310                 return outputs;
00311         }
00312 
00313         std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> > AmplInput::stringHandlers()
00314         {
00315                 return std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> >(AmplInput::stringParsers(), AmplInput::stringOutputs());
00316         }
00317 
00318         std::vector<AmplInputDataParser*> AmplInput::intFloatParsers()
00319         {
00320                 std::vector<AmplInputDataParser*> parsers;
00321                 parsers.push_back(new AmplInputScalar<int>());
00322                 parsers.push_back(new AmplInputScalar<float>());
00323                 parsers.push_back(new AmplInputVector<int, int>(true));
00324                 parsers.push_back(new AmplInputVector<int, float>(true));
00325                 parsers.push_back(new AmplInputSet<int>(true));
00326                 parsers.push_back(new AmplInputSet<float>(true));
00327                 parsers.push_back(new AmplInputMatrix<int, int, int>(true));
00328                 parsers.push_back(new AmplInputMatrix<int, int, float>(true));
00329 
00330                 return parsers;
00331         }
00332                 
00333         std::vector<AmplInputDataOutput*> AmplInput::intFloatOutputs()
00334         {
00335                 std::vector<AmplInputDataOutput*> outputs;
00336 
00337                 outputs.push_back(new AmplInputScalar<int>());
00338                 outputs.push_back(new AmplInputScalar<float>());
00339                 outputs.push_back(new AmplInputVector<int, int>(true));
00340                 outputs.push_back(new AmplInputVector<int, float>(true));
00341                 outputs.push_back(new AmplInputSet<int>(true));
00342                 outputs.push_back(new AmplInputSet<float>(true));
00343                 outputs.push_back(new AmplInputMatrix<int, int, int>(true));
00344                 outputs.push_back(new AmplInputMatrix<int, int, float>(true));
00345 
00346                 return outputs;
00347         }
00348 
00349         std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> > AmplInput::intFloatHandlers()
00350         {
00351                 return std::pair<std::vector<AmplInputDataParser*>, std::vector<AmplInputDataOutput*> >(AmplInput::intFloatParsers(), AmplInput::intFloatOutputs());
00352         }
00353 
00354         /*
00355         // Protected
00356         void
00357         AmplInput::addParsers()
00358         {       
00359                 parsers.push_back(new AmplInputScalar<int>());
00360                 parsers.push_back(new AmplInputScalar<float>());
00361                 parsers.push_back(new AmplInputVector<int, int>(true));
00362                 parsers.push_back(new AmplInputVector<int, float>(true));
00363                 parsers.push_back(new AmplInputSet<int>(true));
00364                 parsers.push_back(new AmplInputSet<float>(true));
00365                 parsers.push_back(new AmplInputMatrix<int, int, int>(true));
00366                 parsers.push_back(new AmplInputMatrix<int, int, float>(true));
00367         }
00368 
00369         void                    
00370         AmplInput::addOutputs()
00371         {
00372                 outputs.push_back(new AmplInputScalar<int>());
00373                 outputs.push_back(new AmplInputScalar<float>());
00374                 outputs.push_back(new AmplInputVector<int, int>(true));
00375                 outputs.push_back(new AmplInputVector<int, float>(true));
00376                 outputs.push_back(new AmplInputSet<int>(true));
00377                 outputs.push_back(new AmplInputSet<float>(true));
00378                 outputs.push_back(new AmplInputMatrix<int, int, int>(true));
00379                 outputs.push_back(new AmplInputMatrix<int, int, float>(true));
00380         }
00381 */
00382 }