gpt4 book ai didi

c++ - Boost spirit编译问题

转载 作者:搜寻专家 更新时间:2023-10-30 23:59:21 26 4
gpt4 key购买 nike

您好,我是 boost spirit 库的新手。你能告诉我为什么下面的代码不能编译吗?

当我将“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

最佳答案

如果您只搜索包含 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 是 skipper 。

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';
}

关于c++ - Boost spirit编译问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16778399/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com