// // Created by ivan on 3/5/16. // #define BOOST_SPIRIT_USE_PHOENIX_V3 1 #include #include #include #include #include namespace gtsam { typedef boost::spirit::qi::grammar> base_grammar; struct QPSParser::MPSGrammar: base_grammar { RawQP * rqp_; boost::function< void( boost::fusion::vector, std::vector, std::vector> const&)> setName; boost::function< void( boost::fusion::vector, char, std::vector, std::vector, std::vector> const &)> addRow; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, double, std::vector > const &)> rhsSingle; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, double, std::vector, std::vector, std::vector, double>)> rhsDouble; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, double, std::vector>)> colSingle; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, double, std::vector, std::vector, std::vector, double> const &)> colDouble; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, double, std::vector> const &)> addQuadTerm; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector, double> const &)> addBound; boost::function< void( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, std::vector, std::vector> const &)> addBoundFr; MPSGrammar(RawQP * rqp) : base_grammar(start), rqp_(rqp), setName( boost::bind(&RawQP::setName, rqp, ::_1)), addRow( boost::bind(&RawQP::addRow, rqp, ::_1)), rhsSingle( boost::bind(&RawQP::addRHS, rqp, ::_1)), rhsDouble( boost::bind(&RawQP::addRHSDouble, rqp, ::_1)), colSingle( boost::bind(&RawQP::addColumn, rqp, ::_1)), colDouble( boost::bind(&RawQP::addColumnDouble, rqp, ::_1)), addQuadTerm( boost::bind(&RawQP::addQuadTerm, rqp, ::_1)), addBound( boost::bind(&RawQP::addBound, rqp, ::_1)), addBoundFr( boost::bind(&RawQP::addBoundFr, rqp, ::_1)) { using namespace boost::spirit; using namespace boost::spirit::qi; character = lexeme[alnum | '_' | '-' | '.']; title = lexeme[character >> *(blank | character)]; word = lexeme[+character]; name = lexeme[lit("NAME") >> *blank >> title >> +space][setName]; row = lexeme[*blank >> character >> +blank >> word >> *blank][addRow]; rhs_single = lexeme[*blank >> word >> +blank >> word >> +blank>> double_ >> *blank][rhsSingle]; rhs_double = lexeme[(*blank >> word >> +blank >> word >> +blank >> double_ >> +blank >> word >> +blank >> double_)[rhsDouble] >> *blank]; col_single = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ >> *blank][colSingle]; col_double = lexeme[*blank >> (word >> +blank >> word >> +blank >> double_ >> +blank >> word >> +blank >> double_)[colDouble] >> *blank]; quad_l = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ >> *blank][addQuadTerm]; bound = lexeme[*blank >> word >> +blank >> word >> +blank >> word >> +blank >> double_ >> *blank][addBound]; bound_fr = lexeme[*blank >> word >> +blank >> word >> +blank >> word >> *blank][addBoundFr]; 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]; end = lexeme[lit("ENDATA") >> *space]; start = lexeme[name >> rows >> cols >> rhs >> -ranges >> bounds >> quad >> end]; } boost::spirit::qi::rule, char()> character; boost::spirit::qi::rule, std::vector()> word; boost::spirit::qi::rule, std::vector()> title; boost::spirit::qi::rule > row; boost::spirit::qi::rule > end; boost::spirit::qi::rule > col_single; boost::spirit::qi::rule > col_double; boost::spirit::qi::rule > rhs_single; boost::spirit::qi::rule > rhs_double; boost::spirit::qi::rule > ranges; boost::spirit::qi::rule > bound; boost::spirit::qi::rule > bound_fr; boost::spirit::qi::rule > bounds; boost::spirit::qi::rule > quad; boost::spirit::qi::rule > quad_l; boost::spirit::qi::rule > rows; boost::spirit::qi::rule > cols; boost::spirit::qi::rule > rhs; boost::spirit::qi::rule > name; boost::spirit::qi::rule > start; }; QP QPSParser::Parse() { RawQP rawData; std::fstream stream(fileName_.c_str()); stream.unsetf(std::ios::skipws); boost::spirit::basic_istream_iterator begin(stream); boost::spirit::basic_istream_iterator last; if (!parse(begin, last, MPSGrammar(&rawData)) || begin != last) { throw QPSParserException(); } else { std::cout << "Parse Successful." << std::endl; } return rawData.makeQP(); } }