Boost Spirit编译问题
Posted
技术标签:
【中文标题】Boost Spirit编译问题【英文标题】:Boost spirit compile issue 【发布时间】:2013-05-27 18:05:33 【问题描述】:嗨,我是提升精神库的新手。你能告诉我为什么下面的代码不能编译吗?
当我在我的语法中添加“scientificNumber”规则时,它不会编译。可能是什么原因? 我添加了“scientificNumber”规则,以便解析像“12E10”这样的科学记数法。我不知道这是否是正确的方法。
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef boost::function<double()> Value;
#define BINARY_FUNCTOR(name, op) \
struct name \
\
name(Value x, Value y): x_(x), y_(y) \
double operator()() return x_() op y_(); \
Value x_, y_; \
;
BINARY_FUNCTOR(ADD, +)
BINARY_FUNCTOR(SUB, -)
BINARY_FUNCTOR(MUL, *)
BINARY_FUNCTOR(DIV, /)
struct LIT
LIT(double x): x_(x)
double operator()() return x_;
double x_;
;
struct NEG
NEG(Value x): x_(x)
double operator()() return -x_();
Value x_;
;
struct SQRT
SQRT(Value x): x_(x)
double operator()() return sqrt(x_());
Value x_;
;
struct SCIENTIFIC
SCIENTIFIC(std::wstring x): x_(x)
double operator()() return boost::lexical_cast<double>(x_);
std::wstring x_;
;
// expression grammar definition
template <typename It, typename Skipper=boost::spirit::qi::space_type>
struct parser : boost::spirit::qi::grammar<It, Value(), Skipper>
parser() : parser::base_type(expression)
using namespace qi;
expression =
term [_val = _1]
>> *( ('+' >> term [_val = phx::construct<ADD>(_val, _1)])
| ('-' >> term [_val = phx::construct<SUB>(_val, _1)])
);
term =
factor [_val = _1]
>> *( ('*' >> factor [_val = phx::construct<MUL>(_val, _1)])
| ('/' >> factor [_val = phx::construct<DIV>(_val, _1)])
);
factor =
double_ [_val = phx::construct<LIT>(_1)]
| scientificNumber [_val = phx::construct<SCIENTIFIC>(_1)]
| '(' >> expression [_val = _1] >> ')'
| ('-' >> factor [_val = phx::construct<NEG>(_1)])
| ('+' >> factor [_val = _1])
| (string("SQRT") >> '(' >> expression [_val = phx::construct<SQRT>(_1)] >> ')');
scientificNumber = lexeme[+(boost::spirit::qi::digit) >> lit('E') >> lit('-') >> +(boost::spirit::qi::digit)];
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
private:
boost::spirit::qi::rule<It, std::wstring , Skipper> scientificNumber;
qi::rule<It, Value(), Skipper> expression, term, factor;
;
int main()
std::wstring::const_iterator beginExpression(testExp.begin());
std::wstring::const_iterator endExpression(testExp.end());
typedef std::wstring::const_iterator It;
parser<It , boost::spirit::qi::space_type> expressionParser;
Value logicExpression;
phrase_parse(beginExpression,endExpression,expressionParser,boost::spirit::qi::space,logicExpression);
你能告诉我什么是 boost::spirit::qi::grammar
【问题讨论】:
一般来说,了解编译器输出对于查找错误很有帮助。所以也许你想告诉我们,编译器在抱怨什么(以及在哪里)? 因为它是一个模板错误,它太长而且实际上我不知道我应该在这里粘贴哪个部分。这就是为什么我没有把它放在这里。我认为我在定义 scienceNumber 规则并将其与语法结合时遇到了问题 您能否添加缺少的包含文件和“testExp”声明/定义,使其尽可能完整? 引人注目的是,这与这里的解析器基本相同:http://***.com/questions/15486531/boostspiritqi-defining-a-calculator-for-nullaries/15488691#15488691 【参考方案1】:如果您只搜索包含 error
的第一行,您将看到以下注释:
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
这是宾果游戏:它准确地告诉你哪里出了问题。它认为std::wstring
是船长。
qi::rule<It, std::wstring, Skipper> scientificNumber; // huh?
根据文档,您需要将属性类型拼写为函数签名的返回类型:
qi::rule<It, std::wstring(), Skipper> scientificNumber;
现在,它编译并运行,见下文,打印输出:
Success: true Value: 2.7e-09
重要
但是,使用lexical_cast
inside Boost Spirit 来...解析一个数字(!?!)是一种讽刺。您可以测试原始的东西:它也可以与 LIT (qi::double_
) 解析器一起工作。请参阅 http://ideone.com/mI1ESI
再次,请参阅此处的文档:link
完整代码
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/lexical_cast.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef boost::function<double()> Value;
#define BINARY_FUNCTOR(name, op) \
struct name \
\
name(Value x, Value y): x_(x), y_(y) \
double operator()() return x_() op y_(); \
Value x_, y_; \
;
BINARY_FUNCTOR(ADD, +)
BINARY_FUNCTOR(SUB, -)
BINARY_FUNCTOR(MUL, *)
BINARY_FUNCTOR(DIV, /)
struct LIT
LIT(double x): x_(x)
double operator()()
return x_;
double x_;
;
struct NEG
NEG(Value x): x_(x)
double operator()()
return -x_();
Value x_;
;
struct SQRT
SQRT(Value x): x_(x)
double operator()()
return sqrt(x_());
Value x_;
;
struct SCIENTIFIC
SCIENTIFIC(std::wstring x): x_(x)
double operator()()
return boost::lexical_cast<double>(x_);
std::wstring x_;
;
// expression grammar definition
template <typename It, typename Skipper=qi::space_type>
struct parser : qi::grammar<It, Value(), Skipper>
parser() : parser::base_type(expression)
using namespace qi;
expression =
term [_val = _1]
>> *(('+' >> term [_val = phx::construct<ADD>(_val, _1)])
| ('-' >> term [_val = phx::construct<SUB>(_val, _1)])
);
term =
factor [_val = _1]
>> *(('*' >> factor [_val = phx::construct<MUL>(_val, _1)])
| ('/' >> factor [_val = phx::construct<DIV>(_val, _1)])
);
factor =
double_ [_val = phx::construct<LIT>(_1)]
| scientificNumber [_val = phx::construct<SCIENTIFIC>(_1)]
| '(' >> expression [_val = _1] >> ')'
| ('-' >> factor [_val = phx::construct<NEG>(_1)])
| ('+' >> factor [_val = _1])
| (string("SQRT") >> '(' >> expression [_val = phx::construct<SQRT>(_1)] >> ')');
scientificNumber = lexeme[+(qi::digit) >> lit('E') >> lit('-') >> +(qi::digit)];
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
private:
qi::rule<It, std::wstring(), Skipper> scientificNumber;
qi::rule<It, Value(), Skipper> expression, term, factor;
;
int main()
const std::wstring testExp = L"3E-10*(12-3)";
typedef std::wstring::const_iterator It;
It f(testExp.begin()), e(testExp.end());
parser<It, qi::space_type> expressionParser;
Value logicExpression;
bool ok = phrase_parse(f,e,expressionParser,qi::space,logicExpression);
std::cout << "Success: " << std::boolalpha << ok << "\tValue: " << logicExpression() << '\n';
【讨论】:
【参考方案2】:编译问题就在这里:
boost::spirit::qi::rule<It, std::wstring , Skipper> scientificNumber;
它不会产生任何属性,因为您不提供构造函数。这是修复:
boost::spirit::qi::rule<It, std::wstring() , Skipper> scientificNumber;
关于 boost::spirit::qi::grammar ,请查看:http://www.boost.org/doc/libs/1_53_0/libs/spirit/classic/doc/grammar.html
这里有很多例子:https://***.com/questions/tagged/boost-spirit
【讨论】:
以上是关于Boost Spirit编译问题的主要内容,如果未能解决你的问题,请参考以下文章
Boost Spirit v2 gcc 编译错误,使用 msvc 未显示
ceph 源码安装 configure: error: "Can't find boost spirit headers"