boost qi::grammar 不使用 spirit/phoenix 更新值类型
boost qi::grammar not updating valuetype using spirit/phoenix
我有以下问题:
在使用 qi::grammar 解析文本时,结构语法不返回已解析对象的值。
语法
template<typename Iterator>
struct PositionalDegreeImpl_grammer : qi::grammar<Iterator,PositionalDegreeImpl>
{
struct Type_ : qi::symbols<char,horus::parsergenerator::nmea::CardinalDirection::Direction>
{
Type_()
{
this->add("E", horus::parsergenerator::nmea::CardinalDirection::Direction::EAST)
("N", horus::parsergenerator::nmea::CardinalDirection::Direction::NORTH)
("W", horus::parsergenerator::nmea::CardinalDirection::Direction::WEST)
("S", horus::parsergenerator::nmea::CardinalDirection::Direction::SOUTH);
}
} type_;
qi::rule<Iterator,PositionalDegreeImpl> r;
PositionalDegreeImpl_grammer() : PositionalDegreeImpl_grammer::base_type(r)
{
r = (double_ >> ',' >> type_)
[
qi::_val = boost::phoenix::construct<PositionalDegreeImpl>(qi::_2,qi::_1)
];
}
};
在调试会话期间可以看到使用正确的值调用了正确的构造函数。
std::string str = "123.2,W";
PositionalDegreeImpl val(horus::parsergenerator::nmea::CardinalDirection::Direction::EAST,1.0);
PositionalDegreeImpl_grammer<std::string::iterator> pos_deg_parser;
bool r = qi::parse(str.begin(), str.end(), pos_deg_parser, &val);
if (!r || val.degrees() != 123.2)
{
std::cout<< "Err" <<std::endl;
}
val 包含解析后的初始值。我有一种感觉,我正在看东西。
纯虚拟基地
class PositionalDegree
{
public:
/*! number of degrees of the position */
virtual double degrees() const = 0;
/*! the direction {N,S,E,W} of the position */
virtual const CardinalDirection& direction() const = 0;
/*! Provide the assignment operator */
virtual PositionalDegree& operator=(const PositionalDegree&) = 0;
};
实施
class PositionalDegreeImpl : public PositionalDegree
{
private:
double _degrees;
CardinalDirectionImpl _direction;
public:
PositionalDegreeImpl();
explicit PositionalDegreeImpl(PositionalDegree const &other);
PositionalDegreeImpl(PositionalDegreeImpl const &other);
PositionalDegreeImpl(CardinalDirectionImpl const & cardinal, double degrees);
virtual ~PositionalDegreeImpl();
virtual double degrees() const;
virtual const CardinalDirection& direction() const;
virtual PositionalDegree& operator=(const PositionalDegree& other);
PositionalDegreeImpl& operator=(const PositionalDegreeImpl& other);
};
如有任何想法和提示,我们将不胜感激。
问候奥克
看来您缺少括号:
qi::rule<Iterator,PositionalDegreeImpl()> r;
如果我没记错的话,包含括号的绝对要求将在即将发布的版本中取消(可能已经存在 1_57_0
这是一个独立的例子
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace horus { namespace parsergenerator { namespace nmea {
struct CardinalDirection {
enum class Direction { EAST, NORTH, WEST, SOUTH };
};
struct PositionalDegreeImpl {
PositionalDegreeImpl(CardinalDirection::Direction direction, double d)
: _dir(direction), _degrees(d)
{
}
double degrees() const { return _degrees; }
private:
CardinalDirection::Direction _dir;
double _degrees;
};
template<typename Iterator, typename T = PositionalDegreeImpl>
struct PositionalDegreeGrammar : qi::grammar<Iterator,T()>
{
PositionalDegreeGrammar() : PositionalDegreeGrammar::base_type(r)
{
r = (qi::double_ >> ',' >> type_)
[
qi::_val = boost::phoenix::construct<T>(qi::_2,qi::_1)
];
}
private:
struct Type_ : qi::symbols<char, CardinalDirection::Direction> {
Type_() {
this->add
("E", CardinalDirection::Direction::EAST)
("N", CardinalDirection::Direction::NORTH)
("W", CardinalDirection::Direction::WEST)
("S", CardinalDirection::Direction::SOUTH);
}
} type_;
qi::rule<Iterator,T()> r;
};
} } }
int main()
{
using namespace horus::parsergenerator::nmea;
typedef std::string::const_iterator It;
PositionalDegreeImpl val(CardinalDirection::Direction::EAST, 1.0);
PositionalDegreeGrammar<It> pos_deg_parser;
std::string const str = "123.2,W";
It f = str.begin(), l = str.end();
bool r = qi::parse(f, l, pos_deg_parser, val);
if (r)
std::cout << val.degrees() << ": " << std::boolalpha << (123.2==val.degrees()) << "\n";
else
std::cout << "parsing failed\n";
}
打印:
123.2: true
我有以下问题:
在使用 qi::grammar 解析文本时,结构语法不返回已解析对象的值。
语法
template<typename Iterator>
struct PositionalDegreeImpl_grammer : qi::grammar<Iterator,PositionalDegreeImpl>
{
struct Type_ : qi::symbols<char,horus::parsergenerator::nmea::CardinalDirection::Direction>
{
Type_()
{
this->add("E", horus::parsergenerator::nmea::CardinalDirection::Direction::EAST)
("N", horus::parsergenerator::nmea::CardinalDirection::Direction::NORTH)
("W", horus::parsergenerator::nmea::CardinalDirection::Direction::WEST)
("S", horus::parsergenerator::nmea::CardinalDirection::Direction::SOUTH);
}
} type_;
qi::rule<Iterator,PositionalDegreeImpl> r;
PositionalDegreeImpl_grammer() : PositionalDegreeImpl_grammer::base_type(r)
{
r = (double_ >> ',' >> type_)
[
qi::_val = boost::phoenix::construct<PositionalDegreeImpl>(qi::_2,qi::_1)
];
}
};
在调试会话期间可以看到使用正确的值调用了正确的构造函数。
std::string str = "123.2,W";
PositionalDegreeImpl val(horus::parsergenerator::nmea::CardinalDirection::Direction::EAST,1.0);
PositionalDegreeImpl_grammer<std::string::iterator> pos_deg_parser;
bool r = qi::parse(str.begin(), str.end(), pos_deg_parser, &val);
if (!r || val.degrees() != 123.2)
{
std::cout<< "Err" <<std::endl;
}
val 包含解析后的初始值。我有一种感觉,我正在看东西。
纯虚拟基地
class PositionalDegree
{
public:
/*! number of degrees of the position */
virtual double degrees() const = 0;
/*! the direction {N,S,E,W} of the position */
virtual const CardinalDirection& direction() const = 0;
/*! Provide the assignment operator */
virtual PositionalDegree& operator=(const PositionalDegree&) = 0;
};
实施
class PositionalDegreeImpl : public PositionalDegree
{
private:
double _degrees;
CardinalDirectionImpl _direction;
public:
PositionalDegreeImpl();
explicit PositionalDegreeImpl(PositionalDegree const &other);
PositionalDegreeImpl(PositionalDegreeImpl const &other);
PositionalDegreeImpl(CardinalDirectionImpl const & cardinal, double degrees);
virtual ~PositionalDegreeImpl();
virtual double degrees() const;
virtual const CardinalDirection& direction() const;
virtual PositionalDegree& operator=(const PositionalDegree& other);
PositionalDegreeImpl& operator=(const PositionalDegreeImpl& other);
};
如有任何想法和提示,我们将不胜感激。
问候奥克
看来您缺少括号:
qi::rule<Iterator,PositionalDegreeImpl()> r;
如果我没记错的话,包含括号的绝对要求将在即将发布的版本中取消(可能已经存在 1_57_0
这是一个独立的例子
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace horus { namespace parsergenerator { namespace nmea {
struct CardinalDirection {
enum class Direction { EAST, NORTH, WEST, SOUTH };
};
struct PositionalDegreeImpl {
PositionalDegreeImpl(CardinalDirection::Direction direction, double d)
: _dir(direction), _degrees(d)
{
}
double degrees() const { return _degrees; }
private:
CardinalDirection::Direction _dir;
double _degrees;
};
template<typename Iterator, typename T = PositionalDegreeImpl>
struct PositionalDegreeGrammar : qi::grammar<Iterator,T()>
{
PositionalDegreeGrammar() : PositionalDegreeGrammar::base_type(r)
{
r = (qi::double_ >> ',' >> type_)
[
qi::_val = boost::phoenix::construct<T>(qi::_2,qi::_1)
];
}
private:
struct Type_ : qi::symbols<char, CardinalDirection::Direction> {
Type_() {
this->add
("E", CardinalDirection::Direction::EAST)
("N", CardinalDirection::Direction::NORTH)
("W", CardinalDirection::Direction::WEST)
("S", CardinalDirection::Direction::SOUTH);
}
} type_;
qi::rule<Iterator,T()> r;
};
} } }
int main()
{
using namespace horus::parsergenerator::nmea;
typedef std::string::const_iterator It;
PositionalDegreeImpl val(CardinalDirection::Direction::EAST, 1.0);
PositionalDegreeGrammar<It> pos_deg_parser;
std::string const str = "123.2,W";
It f = str.begin(), l = str.end();
bool r = qi::parse(f, l, pos_deg_parser, val);
if (r)
std::cout << val.degrees() << ": " << std::boolalpha << (123.2==val.degrees()) << "\n";
else
std::cout << "parsing failed\n";
}
打印:
123.2: true