// // Created by ivan on 3/5/16. // #include #include #include #include #define BOOST_SPIRIT_USE_PHOENIX_V3 1 using namespace boost::spirit; using namespace boost::spirit::qi; using namespace boost::spirit::qi::labels; namespace gtsam { struct QPSParser::MPSGrammar: grammar> { MPSGrammar(RawQP * rqp) : MPSGrammar::base_type(start), rqp_(rqp) { character = lexeme[char_("a-zA-Z") | char_('_')]; title = lexeme[+character >> *(blank | character | char_('-') | char_('.') | char_("0-9"))]; word = lexeme[(character >> *(char_("0-9") | char_('-') | char_('.') | character))]; name = lexeme[lit("NAME") >> *blank >> title[boost::phoenix::bind(&RawQP::setName, rqp_, qi::_1)] >> +space]; row = lexeme[*blank >> (character >> +blank >> word)[boost::phoenix::bind(&RawQP::addRow, rqp_, qi::_1, qi::_3)] >> *blank]; rhs_single = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_)[boost::phoenix::bind( &RawQP::addRHS, rqp_, qi::_1, qi::_3, qi::_5)] >> *blank]; rhs_double = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_ >> +blank >> word >> +blank >> double_)[boost::phoenix::bind(&RawQP::addRHS, rqp_, qi::_1, qi::_3, qi::_5, qi::_7, qi::_9)] >> *blank]; col_single = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_)[boost::phoenix::bind( &RawQP::addColumn, rqp_, qi::_1, qi::_3, qi::_5)] >> *blank]; col_double = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_ >> +blank >> word >> +blank >> double_)[boost::phoenix::bind(&RawQP::addColumn, rqp_, qi::_1, qi::_3, qi::_5, qi::_7, qi::_9)] >> *blank]; quad_l = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_)[boost::phoenix::bind( &RawQP::addQuadTerm, rqp_, qi::_1, qi::_3, qi::_5)] >> *blank]; bound = lexeme[*blank >> (word >> +blank >> word >> +blank >> word >> +blank >> double_)[boost::phoenix::bind( &RawQP::addBound, rqp_, qi::_1, qi::_5, qi::_7)] >> *blank]; bound_fr = lexeme[*blank >> (word >> +blank >> word >> +blank >> word)[boost::phoenix::bind( &RawQP::addBound, rqp_, qi::_1, qi::_5)] >> *blank]; rows = lexeme[lit("ROWS") >> *blank >> eol >> +(row >> eol)]; rhs = lexeme[lit("RHS") >> *blank >> eol >> +((rhs_double | rhs_single) >> eol)]; cols = lexeme[lit("COLUMNS") >> *blank >> eol >> +((col_double | col_single) >> eol)]; quad = lexeme[lit("QUADOBJ") >> *blank >> eol >> +(quad_l >> eol)]; bounds = lexeme[lit("BOUNDS") >> +space >> +((bound | bound_fr) >> eol)]; ranges = lexeme[lit("RANGES") >> +space]; start = lexeme[name >> rows >> cols >> rhs >> ranges >> bounds >> quad >> lit("ENDATA") >> +space]; } RawQP * rqp_; rule, char()> character; rule, std::vector()> word; rule, std::vector()> title; rule > row; rule > col_single; rule > col_double; rule > rhs_single; rule > rhs_double; rule > ranges; rule > bound; rule > bound_fr; rule > bounds; rule > quad; rule > quad_l; rule > rows; rule > cols; rule > rhs; rule > name; rule > start; }; QP QPSParser::Parse() { RawQP rawData; boost::spirit::basic_istream_iterator begin(stream); boost::spirit::basic_istream_iterator last; if (!parse(begin, last, MPSGrammar(&rawData)) && begin == last) { throw QPSParserException(); } return rawData.makeQP(); } }