pelib
2.0.0
|
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 &lInput) 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 &l_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 }