140 lines
6.0 KiB
C++
140 lines
6.0 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/QPSVisitor.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;
|
|
QPSVisitor * 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> const &)> rangeSingle;
|
|
boost::function<
|
|
void(
|
|
bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars, Chars,
|
|
Chars, double>)> rangeDouble;
|
|
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 &)> addFreeBound;
|
|
MPSGrammar(QPSVisitor * rqp) :
|
|
base_grammar(start), rqp_(rqp), setName(
|
|
boost::bind(&QPSVisitor::setName, rqp, ::_1)), addRow(
|
|
boost::bind(&QPSVisitor::addRow, rqp, ::_1)), rhsSingle(
|
|
boost::bind(&QPSVisitor::addRHS, rqp, ::_1)), rhsDouble(
|
|
boost::bind(&QPSVisitor::addRHSDouble, rqp, ::_1)), rangeSingle(
|
|
boost::bind(&QPSVisitor::addRangeSingle, rqp, ::_1)), rangeDouble(
|
|
boost::bind(&QPSVisitor::addRangeDouble, rqp, ::_1)), colSingle(
|
|
boost::bind(&QPSVisitor::addColumn, rqp, ::_1)), colDouble(
|
|
boost::bind(&QPSVisitor::addColumnDouble, rqp, ::_1)), addQuadTerm(
|
|
boost::bind(&QPSVisitor::addQuadTerm, rqp, ::_1)), addBound(
|
|
boost::bind(&QPSVisitor::addBound, rqp, ::_1)), addFreeBound(
|
|
boost::bind(&QPSVisitor::addFreeBound, 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];
|
|
range_single = lexeme[*blank >> word >> +blank >> word >> +blank >> double_
|
|
>> *blank][rangeSingle];
|
|
range_double = lexeme[(*blank >> word >> +blank >> word >> +blank >> double_
|
|
>> +blank >> word >> +blank >> double_)[rangeDouble] >> *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][addFreeBound];
|
|
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
|
|
>> *((range_double | range_single) >> eol)];
|
|
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, range_single, range_double, ranges,
|
|
bound, bound_fr, bounds, quad, quad_l, rows, cols, rhs, name, start;
|
|
};
|
|
|
|
QP QPSParser::Parse() {
|
|
QPSVisitor 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();
|
|
}
|
|
|
|
}
|