| 
									
										
										
										
											2016-06-18 03:24:55 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * 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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  | #define BOOST_SPIRIT_USE_PHOENIX_V3 1
 | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam_unstable/linear/QPSParser.h>
 | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  | #include <gtsam_unstable/linear/QPSParserException.h>
 | 
					
						
							|  |  |  | #include <gtsam_unstable/linear/RawQP.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | #include <boost/spirit/include/qi.hpp>
 | 
					
						
							|  |  |  | #include <boost/lambda/lambda.hpp>
 | 
					
						
							|  |  |  | #include <boost/phoenix/bind.hpp>
 | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  | #include <boost/spirit/include/classic.hpp>
 | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  | namespace bf = boost::fusion; | 
					
						
							|  |  |  | namespace qi = boost::spirit::qi; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | namespace gtsam { | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  | typedef qi::grammar<boost::spirit::basic_istream_iterator<char>> base_grammar; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  | struct QPSParser::MPSGrammar: base_grammar { | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |   typedef std::vector<char> Chars; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   RawQP * rqp_; | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |   boost::function<void(bf::vector<Chars, Chars, Chars> const&)> setName; | 
					
						
							|  |  |  |   boost::function<void(bf::vector<Chars, char, Chars, Chars, Chars> const &)> addRow; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars> const &)> rhsSingle; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							|  |  |  |       void( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |           bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars, Chars, | 
					
						
							|  |  |  |               Chars, double>)> rhsDouble; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars>)> colSingle; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							|  |  |  |       void( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |           bf::vector<Chars, Chars, Chars, Chars, double, Chars, Chars, Chars, | 
					
						
							|  |  |  |               double> const &)> colDouble; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |       void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars> const &)> addQuadTerm; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							|  |  |  |       void( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |           bf::vector<Chars, Chars, Chars, Chars, Chars, Chars, Chars, double> const &)> addBound; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   boost::function< | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |       void(bf::vector<Chars, Chars, Chars, Chars, Chars, Chars, Chars> const &)> addBoundFr; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |   MPSGrammar(RawQP * rqp) : | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |       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]; | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |     rhs_single = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |         >> *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]; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |     col_double = lexeme[*blank | 
					
						
							|  |  |  |         >> (word >> +blank >> word >> +blank >> double_ >> +blank >> word | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |             >> +blank >> double_)[colDouble] >> *blank]; | 
					
						
							|  |  |  |     quad_l = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ | 
					
						
							|  |  |  |         >> *blank][addQuadTerm]; | 
					
						
							| 
									
										
										
										
											2016-08-06 10:34:38 +08:00
										 |  |  |     bound = lexeme[(*blank >> word >> +blank >> word >> +blank >> word >> +blank | 
					
						
							|  |  |  |         >> double_)[addBound] >> *blank]; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |     bound_fr = lexeme[*blank >> word >> +blank >> word >> +blank >> word | 
					
						
							|  |  |  |         >> *blank][addBoundFr]; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |     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]; | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |     end = lexeme[lit("ENDATA") >> *space]; | 
					
						
							|  |  |  |     start = lexeme[name >> rows >> cols >> rhs >> -ranges >> bounds >> quad | 
					
						
							|  |  |  |         >> end]; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 00:24:02 +08:00
										 |  |  |   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; | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QP QPSParser::Parse() { | 
					
						
							|  |  |  |   RawQP rawData; | 
					
						
							| 
									
										
										
										
											2016-04-27 14:04:16 +08:00
										 |  |  |   std::fstream stream(fileName_.c_str()); | 
					
						
							|  |  |  |   stream.unsetf(std::ios::skipws); | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |   boost::spirit::basic_istream_iterator<char> begin(stream); | 
					
						
							|  |  |  |   boost::spirit::basic_istream_iterator<char> last; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 23:34:31 +08:00
										 |  |  |   if (!parse(begin, last, MPSGrammar(&rawData)) || begin != last) { | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  |     throw QPSParserException(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rawData.makeQP(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |