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/AmplOutput.hpp> 00030 #include <pelib/AmplOutputScalar.hpp> 00031 #include <pelib/AmplOutputVector.hpp> 00032 #include <pelib/AmplOutputSet.hpp> 00033 #include <pelib/AmplOutputMatrix.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 AmplOutput::AmplOutput() 00053 { 00054 // Add parsers 00055 addParsers(); 00056 00057 // Add interpreters 00058 addOutputs(); 00059 } 00060 00061 AmplOutput::AmplOutput(std::vector<AmplOutputDataParser*> parsers, 00062 std::vector<AmplOutputDataOutput*> outputs) 00063 { 00064 this->parsers = parsers; 00065 this->outputs = outputs; 00066 } 00067 */ 00068 AmplOutput::AmplOutput(std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> > handlers) 00069 { 00070 this->parsers = handlers.first; 00071 this->outputs = handlers.second; 00072 } 00073 00074 AmplOutput::~AmplOutput() 00075 { 00076 deleteParsers(); 00077 deleteOutputs(); 00078 } 00079 00080 void 00081 AmplOutput::deleteParsers() 00082 { 00083 for(std::vector<AmplOutputDataParser*>::iterator i = parsers.begin(); i != parsers.end(); i = parsers.erase(i)) 00084 { 00085 delete *i; 00086 } 00087 } 00088 00089 void 00090 AmplOutput::deleteOutputs() 00091 { 00092 for(std::vector<AmplOutputDataOutput*>::iterator i = outputs.begin(); i != outputs.end(); i = outputs.erase(i)) 00093 { 00094 delete *i; 00095 } 00096 } 00097 00098 AmplOutput& 00099 AmplOutput::operator=(const AmplOutput &lOutput) 00100 { 00101 deleteParsers(); 00102 deleteOutputs(); 00103 00104 for(std::vector<AmplOutputDataParser*>::const_iterator i = amplOutput.parsers.begin(); i != amplOutput.parsers.end(); i++) 00105 { 00106 parsers.push_back((*i)->clone()); 00107 } 00108 00109 for(std::vector<AmplOutputDataOutput*>::const_iterator i = amplOutput.outputs.begin(); i != amplOutput.outputs.end(); i++) 00110 { 00111 outputs.push_back((*i)->clone()); 00112 } 00113 00114 return *this; 00115 } 00116 00117 Algebra 00118 AmplOutput::parse(std::istream &l_data) const 00119 { 00120 Algebra record; 00121 std::string line; 00122 00123 while(!getline(ampl_data, line, ';').fail()) 00124 { 00125 // Read section into string buffer stream 00126 std::stringstream section; 00127 section << line; 00128 00129 while(!getline(section, line, ';').fail()) 00130 { 00131 std::vector<AmplOutputDataParser*>::const_iterator iter; 00132 for(iter = parsers.begin(); iter != parsers.end(); iter++) 00133 { 00134 AmplOutputDataParser *parser = *iter; 00135 try { 00136 // If any non-blank prefix to be discarded, it must be separated by a new line 00137 std::string regex = std::string("(.*?\\n|)\\s*(") 00138 .append(parser->getGlobalPattern()) 00139 .append(")(?:\\s*)"); 00140 00141 boost::cmatch match; // = AlgebraDataParser::match(regex, line); 00142 if(!boost::regex_match(line.c_str(), match, boost::regex(regex))) 00143 { 00144 throw ParseException(std::string("String \"").append(line).append("\" doesn't match regex \"").append(regex).append("\". ")); 00145 } 00146 00147 std::stringstream token; 00148 token.str(match[2]); 00149 00150 //std::cerr << "Discarded =\"" << match[1] << "\"." << std::endl; 00151 //std::cerr << "Token =\"" << match[2] << "\"." << std::endl; 00152 AlgebraData *data = parser->parse(token); 00153 record.insert(data); 00154 00155 // Keep only the part we have not parsed 00156 line = match[1]; 00157 00158 // Feed the remaining Output line to parsers Output is more useful information are available 00159 section.str(line); 00160 section.seekp(std::ios_base::beg); 00161 section.clear(); 00162 00163 // No need to try another parser; proceed with the next token in section 00164 break; 00165 } catch (ParseException &e) 00166 { 00167 // Try next parser 00168 } 00169 } 00170 00171 // There was no parser for this section; drop it and go to next 00172 if(iter == parsers.end()) 00173 { 00174 std::vector<AmplOutputDataParser*>::const_iterator iter; 00175 std::vector<AmplOutputDataParser*> parsers = stringParsers(); 00176 for(iter = parsers.begin(); iter != parsers.end(); iter++) 00177 { 00178 AmplOutputDataParser *parser = *iter; 00179 try { 00180 // If any non-blank prefix to be discarded, it must be separated by a new line 00181 std::string regex = std::string("(.*?\\n|)\\s*(") 00182 .append(parser->getGlobalPattern()) 00183 .append(")(?:\\s*)"); 00184 00185 boost::cmatch match; // = AlgebraDataParser::match(regex, line); 00186 if(!boost::regex_match(line.c_str(), match, boost::regex(regex))) 00187 { 00188 throw ParseException(std::string("String \"").append(line).append("\" doesn't match regex \"").append(regex).append("\". ")); 00189 } 00190 00191 00192 std::stringstream token; 00193 token.str(match[2]); 00194 00195 //std::cerr << "Discarded =\"" << match[1] << "\"." << std::endl; 00196 //std::cerr << "Token =\"" << match[2] << "\"." << std::endl; 00197 AlgebraData *data = parser->parse(token); 00198 record.insert(data); 00199 00200 // Keep only the part we have not parsed 00201 line = match[1]; 00202 00203 // Feed the remaining Output line to parsers Output is more useful information are available 00204 section.str(line); 00205 section.seekp(std::ios_base::beg); 00206 section.clear(); 00207 00208 // No need to try another parser; proceed with the next token in section 00209 break; 00210 } catch (ParseException &e) 00211 { 00212 // Try next parser 00213 } 00214 } 00215 } 00216 } 00217 } 00218 00219 return record; 00220 } 00221 00222 void 00223 AmplOutput::dump(std::ostream& o, const Algebra &record) const 00224 { 00225 std::map<std::string, const AlgebraData * const> records = record.getAllRecords(); 00226 for (std::map<std::string, const AlgebraData * const>::const_iterator rec = records.begin(); rec != records.end(); rec++) 00227 { 00228 dump(o, rec->second); 00229 } 00230 } 00231 00232 void 00233 AmplOutput::dump(std::ostream& o, const AlgebraData *data) const 00234 { 00235 std::vector<AmplOutputDataOutput*>::const_iterator out; 00236 for (out = outputs.begin(); out != outputs.end(); out++) 00237 { 00238 const AmplOutputDataOutput *output = *out; 00239 try 00240 { 00241 output->dump(o, data); 00242 break; 00243 } catch(CastException &e) 00244 { 00245 // No suitable element to output 00246 // Couldn't cast the element to record: just let that go and try again with next element 00247 } 00248 } 00249 00250 if(out == outputs.end()) 00251 { 00252 vector<AmplOutputDataOutput*> string_outputs = stringOutputs(); 00253 for (out = string_outputs.begin(); out != string_outputs.end(); out++) 00254 { 00255 const AmplOutputDataOutput *output = *out; 00256 try 00257 { 00258 output->dump(o, data); 00259 break; 00260 } catch(CastException &e) 00261 { 00262 // No suitable element to output 00263 // Couldn't cast the element to record: just let that go and try again with next element 00264 } 00265 } 00266 00267 if(out == string_outputs.end()) 00268 { 00269 throw PelibException("Could not find a suitable output format for data record of name \"" + string(data->getName()) + "\"."); 00270 } 00271 } 00272 } 00273 00274 void 00275 AmplOutput::dump(std::ostream& o, const AlgebraData &data) const 00276 { 00277 dump(o, &data); 00278 } 00279 00280 std::vector<AmplOutputDataParser*> AmplOutput::floatParsers() 00281 { 00282 std::vector<AmplOutputDataParser*> parsers; 00283 00284 parsers.push_back(new AmplOutputScalar<float>(false)); 00285 parsers.push_back(new AmplOutputVector<int, float>(false)); 00286 parsers.push_back(new AmplOutputSet<float>(false)); 00287 parsers.push_back(new AmplOutputMatrix<int, int, float>(false)); 00288 00289 return parsers; 00290 } 00291 00292 std::vector<AmplOutputDataOutput*> AmplOutput::floatOutputs() 00293 { 00294 std::vector<AmplOutputDataOutput*> outputs; 00295 00296 outputs.push_back(new AmplOutputScalar<float>(false)); 00297 outputs.push_back(new AmplOutputVector<int, float>(false)); 00298 outputs.push_back(new AmplOutputSet<float>(false)); 00299 outputs.push_back(new AmplOutputMatrix<int, int, float>(false)); 00300 00301 return outputs; 00302 } 00303 00304 std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> > AmplOutput::floatHandlers() 00305 { 00306 return std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> >(AmplOutput::floatParsers(), AmplOutput::floatOutputs()); 00307 } 00308 00309 std::vector<AmplOutputDataParser*> AmplOutput::stringParsers() 00310 { 00311 std::vector<AmplOutputDataParser*> parsers; 00312 00313 parsers.push_back(new AmplOutputScalar<string>(false)); 00314 parsers.push_back(new AmplOutputVector<int, string>(false)); 00315 parsers.push_back(new AmplOutputSet<string>(false)); 00316 parsers.push_back(new AmplOutputMatrix<int, int, string>(false)); 00317 00318 return parsers; 00319 } 00320 00321 std::vector<AmplOutputDataOutput*> AmplOutput::stringOutputs() 00322 { 00323 std::vector<AmplOutputDataOutput*> outputs; 00324 00325 outputs.push_back(new AmplOutputScalar<string>(false)); 00326 outputs.push_back(new AmplOutputVector<int, string>(false)); 00327 outputs.push_back(new AmplOutputSet<string>(false)); 00328 outputs.push_back(new AmplOutputMatrix<int, int, string>(false)); 00329 00330 return outputs; 00331 } 00332 00333 std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> > AmplOutput::stringHandlers() 00334 { 00335 return std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> >(AmplOutput::stringParsers(), AmplOutput::stringOutputs()); 00336 } 00337 00338 std::vector<AmplOutputDataParser*> AmplOutput::intFloatParsers() 00339 { 00340 std::vector<AmplOutputDataParser*> parsers; 00341 parsers.push_back(new AmplOutputScalar<int>()); 00342 parsers.push_back(new AmplOutputScalar<float>()); 00343 parsers.push_back(new AmplOutputVector<int, int>(true)); 00344 parsers.push_back(new AmplOutputVector<int, float>(true)); 00345 parsers.push_back(new AmplOutputSet<int>(true)); 00346 parsers.push_back(new AmplOutputSet<float>(true)); 00347 parsers.push_back(new AmplOutputMatrix<int, int, int>(true)); 00348 parsers.push_back(new AmplOutputMatrix<int, int, float>(true)); 00349 00350 return parsers; 00351 } 00352 00353 std::vector<AmplOutputDataOutput*> AmplOutput::intFloatOutputs() 00354 { 00355 std::vector<AmplOutputDataOutput*> outputs; 00356 00357 outputs.push_back(new AmplOutputScalar<int>()); 00358 outputs.push_back(new AmplOutputScalar<float>()); 00359 outputs.push_back(new AmplOutputVector<int, int>(true)); 00360 outputs.push_back(new AmplOutputVector<int, float>(true)); 00361 outputs.push_back(new AmplOutputSet<int>(true)); 00362 outputs.push_back(new AmplOutputSet<float>(true)); 00363 outputs.push_back(new AmplOutputMatrix<int, int, int>(true)); 00364 outputs.push_back(new AmplOutputMatrix<int, int, float>(true)); 00365 00366 return outputs; 00367 } 00368 00369 std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> > AmplOutput::intFloatHandlers() 00370 { 00371 return std::pair<std::vector<AmplOutputDataParser*>, std::vector<AmplOutputDataOutput*> >(AmplOutput::intFloatParsers(), AmplOutput::intFloatOutputs()); 00372 } 00373 00374 /* 00375 // Protected 00376 void 00377 AmplOutput::addParsers() 00378 { 00379 parsers.push_back(new AmplOutputScalar<int>()); 00380 parsers.push_back(new AmplOutputScalar<float>()); 00381 parsers.push_back(new AmplOutputVector<int, int>()); 00382 parsers.push_back(new AmplOutputVector<int, float>()); 00383 parsers.push_back(new AmplOutputSet<int>()); 00384 parsers.push_back(new AmplOutputSet<float>()); 00385 parsers.push_back(new AmplOutputMatrix<int, int, int>()); 00386 parsers.push_back(new AmplOutputMatrix<int, int, float>()); 00387 } 00388 00389 void 00390 AmplOutput::addOutputs() 00391 { 00392 outputs.push_back(new AmplOutputScalar<int>()); 00393 outputs.push_back(new AmplOutputScalar<float>()); 00394 outputs.push_back(new AmplOutputVector<int, int>()); 00395 outputs.push_back(new AmplOutputVector<int, float>()); 00396 outputs.push_back(new AmplOutputSet<int>()); 00397 outputs.push_back(new AmplOutputSet<float>()); 00398 outputs.push_back(new AmplOutputMatrix<int, int, int>()); 00399 outputs.push_back(new AmplOutputMatrix<int, int, float>()); 00400 } 00401 */ 00402 }