127 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
| /* ----------------------------------------------------------------------------
 | |
| 
 | |
|  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
 | |
|  * Atlanta, Georgia 30332-0415
 | |
|  * All Rights Reserved
 | |
|  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
 | |
| 
 | |
|  * See LICENSE for the license information
 | |
| 
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * @file     QPParser.cpp
 | |
|  * @author   Ivan Dario Jimenez
 | |
|  * @date     3/5/16
 | |
|  */
 | |
| 
 | |
| #define BOOST_SPIRIT_USE_PHOENIX_V3 1
 | |
| 
 | |
| #include <gtsam_unstable/linear/QPSParser.h>
 | |
| #include <gtsam_unstable/linear/QPSParserException.h>
 | |
| #include <gtsam_unstable/linear/RawQP.h>
 | |
| 
 | |
| #include <boost/spirit/include/qi.hpp>
 | |
| #include <boost/lambda/lambda.hpp>
 | |
| #include <boost/phoenix/bind.hpp>
 | |
| #include <boost/spirit/include/classic.hpp>
 | |
| 
 | |
| namespace bf = boost::fusion;
 | |
| namespace qi = boost::spirit::qi;
 | |
| 
 | |
| namespace gtsam {
 | |
| typedef qi::grammar<boost::spirit::basic_istream_iterator<char>> base_grammar;
 | |
| 
 | |
| struct QPSParser::MPSGrammar: base_grammar {
 | |
|   typedef std::vector<char> Chars;
 | |
|   RawQP * rqp_;
 | |
|   boost::function<void(bf::vector<Chars, Chars, Chars> const&)> setName;
 | |
|   boost::function<void(bf::vector<Chars, char, Chars, Chars, Chars> const &)> addRow;
 | |
|   boost::function<
 | |
|       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars> const &)> rhsSingle;
 | |
|   boost::function<
 | |
|       void(
 | |
|           bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars, Chars,
 | |
|               Chars, double>)> rhsDouble;
 | |
|   boost::function<
 | |
|       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars>)> colSingle;
 | |
|   boost::function<
 | |
|       void(
 | |
|           bf::vector<Chars, Chars, Chars, Chars, double, Chars, Chars, Chars,
 | |
|               double> const &)> colDouble;
 | |
|   boost::function<
 | |
|       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars> const &)> addQuadTerm;
 | |
|   boost::function<
 | |
|       void(
 | |
|           bf::vector<Chars, Chars, Chars, Chars, Chars, Chars, Chars, double> const &)> addBound;
 | |
|   boost::function<
 | |
|       void(bf::vector<Chars, Chars, Chars, Chars, Chars, Chars, Chars> 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_)[addBound] >> *blank];
 | |
|     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];
 | |
|   }
 | |
| 
 | |
|   qi::rule<boost::spirit::basic_istream_iterator<char>, char()> character;
 | |
|   qi::rule<boost::spirit::basic_istream_iterator<char>, Chars()> word, title;
 | |
|   qi::rule<boost::spirit::basic_istream_iterator<char> > row, end, col_single,
 | |
|       col_double, rhs_single, rhs_double, ranges, bound, bound_fr, bounds, quad,
 | |
|       quad_l, rows, cols, rhs, name, start;
 | |
| };
 | |
| 
 | |
| QP QPSParser::Parse() {
 | |
|   RawQP rawData;
 | |
|   std::fstream stream(fileName_.c_str());
 | |
|   stream.unsetf(std::ios::skipws);
 | |
|   boost::spirit::basic_istream_iterator<char> begin(stream);
 | |
|   boost::spirit::basic_istream_iterator<char> last;
 | |
| 
 | |
|   if (!parse(begin, last, MPSGrammar(&rawData)) || begin != last) {
 | |
|     throw QPSParserException();
 | |
|   }
 | |
| 
 | |
|   return rawData.makeQP();
 | |
| }
 | |
| 
 | |
| }
 |