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 <pelib/AmplInputData.hpp> 00022 #include <pelib/DataParser.hpp> 00023 #include <pelib/Scalar.hpp> 00024 #include <pelib/CastException.hpp> 00025 #include <pelib/ParseException.hpp> 00026 #include <pelib/NoDecimalFloatException.hpp> 00027 #ifndef PELIB_AMPLINPUTSCALAR 00028 #define PELIB_AMPLINPUTSCALAR 00029 00030 #define debug(var) std::cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << std::endl; 00031 00032 namespace pelib 00033 { 00035 template <class Value> 00036 class 00037 AmplInputScalar: public AmplInputData 00038 { 00039 public: 00043 AmplInputScalar(bool strict = true) 00044 { 00045 this->strict = strict; 00046 } 00047 00049 virtual 00050 AmplInputScalar* 00051 clone() const 00052 { 00053 return new AmplInputScalar(); 00054 } 00055 00057 virtual 00058 AlgebraData* 00059 parse(std::istream &in) 00060 { 00061 std::string str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()); 00062 boost::cmatch match; 00063 // TODO: Investigate why regex doesn't return correct string when called in AlgebraDataParser 00064 if(!boost::regex_match(str.c_str(), match, boost::regex(getDetailedPattern()))) 00065 { 00066 throw ParseException(std::string("String \"").append(str).append("\" doesn't match regex \"").append(getDetailedPattern()).append("\". ")); 00067 } 00068 /* 00069 try 00070 { 00071 match = AlgebraDataParser::match(getDetailedPattern(), str); 00072 } catch(NoDecimalFloatException &e) 00073 { 00074 std::ostringstream ss; 00075 ss << e.getValue(); 00076 throw ParseException(std::string("Asked a decimal conversion, but \"").append(ss.str()).append("\" is integer.")); 00077 } 00078 */ 00079 00080 std::string match1 = match[1]; 00081 std::string match2 = match[2]; 00082 Value val = AlgebraDataParser::convert<Value>(match2, strict); 00083 Scalar<Value> *scalar = new Scalar<Value>(match1, val); 00084 return scalar; 00085 } 00086 00091 virtual 00092 void 00093 dump(std::ostream &stream, const AlgebraData *data) const 00094 { 00095 const Scalar<Value> *scalar = dynamic_cast<const Scalar<Value>* >(data); 00096 if(scalar == NULL) throw CastException("parameter \"data\" was not of type \"Scalar<Value>\"."); 00097 00098 Value val = scalar->getValue(); 00099 if(scalar->getPrecision() == AlgebraData::higher) 00100 { 00101 val = AlgebraData::fixPrecision(val, stream.precision()); 00102 } 00103 00104 stream << "param " << scalar->getName() << " := " << val << ";" << std::endl; 00105 } 00106 00108 virtual 00109 std::string 00110 getDetailedPattern() 00111 { 00112 return "param\\s+([^\\s\\n]*)\\s*:=\\s*([^\\s]+)\\s*"; 00113 } 00114 00116 virtual 00117 std::string 00118 getGlobalPattern() 00119 { 00120 return "param\\s+[^\\s\\n]*\\s*:=.+"; 00121 } 00122 00123 protected: 00125 bool strict; 00126 private: 00127 }; 00128 } 00129 00130 #undef debug 00131 #endif