C++ 促进精神编辑问题
嗨,我是精神图书馆的新手。你能告诉我为什么下面的代码不能编译吗 当我将“科学数字”规则添加到语法中时,它不会编译。原因可能是什么? 我添加了“scientificNumber”规则,以便能够解析像“12E10”这样的科学符号。我不知道这样做是否正确C++ 促进精神编辑问题,c++,boost,boost-spirit,C++,Boost,Boost Spirit,嗨,我是精神图书馆的新手。你能告诉我为什么下面的代码不能编译吗 当我将“科学数字”规则添加到语法中时,它不会编译。原因可能是什么? 我添加了“scientificNumber”规则,以便能够解析像“12E10”这样的科学符号。我不知道这样做是否正确 namespace qi = boost::spirit::qi; namespace phx = boost::phoenix; typedef boost::function<double()> V
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);
}
namespace qi=boost::spirit::qi;
名称空间phx=boost::phoenix;
typedef boost::函数值;
#定义二元函数(名称,op)\
结构名\
{ \
名称(值x,值y):x_ux,y_y{}\
双运算符()\
值x_u,y_u\
};
二元函数(加法,+)
二元函数(SUB,-)
二元函数(MUL,*)
二元函数(DIV,/)
结构照明
{
LIT(双x):x_ux{}
双运算符(){return x_;}
双x;
};
结构负
{
NEG(值x):x_ux{}
双运算符()
值x_u;
};
结构SQRT
{
SQRT(值x):x_ux(x){}
双运算符(){return sqrt(x_());}
值x_u;
};
结构科学
{
科学(std::wstring x):x_ux(x){}
双运算符(){return boost::lexical_cast(x_u);}
std::wstring x_2;;
};
//表达式语法定义
模板
结构分析器:boost::spirit::qi::grammar
{
parser():parser::base_类型(表达式)
{
使用名称空间qi;
表情=
术语[_val=_1]
>>*(('+'>>术语[_val=phx::construct(_val,_1)])
|('-'>>术语[_val=phx::construct(_val,_1)])
);
术语=
系数[_val=_1]
>>*(('*'>>因子[_val=phx::construct(_val,_1)])
|('/'>>因子[_val=phx::construct(_val,_1)])
);
因素=
双[u val=phx::construct(_1)]
|科学编号[\u val=phx::构造(\u 1)]
|“('>>表达式[\u val=\u 1]>>”)
|('-'>>因子[_val=phx::construct(_1)])
|('+'>>因子[\u val=\u 1])
|(字符串(“SQRT”)>>”(“>>表达式[_val=phx::construct(_1)]>>”);
scientificNumber=lexeme[+(boost::spirit::qi::digit)>>lit('E')>>lit('-')>>+(boost::spirit::qi::digit)];
BOOST_-SPIRIT_-DEBUG_节点(表达式);
BOOST_-SPIRIT_-DEBUG_节点(术语);
提升精神调试节点(因子);
}
私人:
助推::精神::气::规则科学数字;
qi:规则表达式、术语、因子;
};
int main()
{
std::wstring::const_迭代器beginExpression(testExp.begin());
std::wstring::const_迭代器endExpression(testExp.end());
typedef std::wstring::const_迭代器It;
解析器表达式解析器;
价值逻辑表达;
短语解析(beginExpression、endExpression、expressionParser、boost::spirit::qi::space、logicExpression);
}
你能告诉我什么是boost::spirit::qi::grammar吗编译问题就在这里:
boost::spirit::qi::rule<It, std::wstring , Skipper> scientificNumber;
boost::spirit::qi::规则科学编号;
它不会生成任何属性,因为您不提供构造函数。以下是修复方法:
boost::spirit::qi::rule<It, std::wstring() , Skipper> scientificNumber;
boost::spirit::qi::规则科学编号;
至于boost::spirit::qi::语法,请检查以下内容:
这里有很多例子:如果您只搜索包含
错误的第一行,您将看到以下注释:
// 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?
重要的
然而,使用lexical\u cast
内推精神来。。。解析一个数字(!?!是一种讽刺。您可以对原始的东西进行测试:它也可以与LIT(qi::double)解析器一起工作。
请参阅
同样,请参见此处的文档:
完整代码
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间phx=boost::phoenix;
typedef boost::函数值;
#定义二元函数(名称,op)\
结构名\
{ \
名称(值x,值y):x_ux,y_y{}\
双运算符()\
值x_u,y_u\
};
二元函数(加法,+)
二元函数(SUB,-)
二元函数(MUL,*)
二元函数(DIV,/)
结构照明
{
LIT(双x):x_ux{}
双运算符()
{
返回x;
}
双x;
};
结构负
{
NEG(值x):x_ux{}
双运算符()
{
return-x_u2;();
}
值x_u;
};
结构SQRT
{
SQRT(值x):x_ux(x){}
双运算符()
{
返回sqrt(x_());
}
值x_u;
};
结构科学
{
科学(std::wstring x):x_ux(x){}
双运算符()
{
返回boost::词法转换(x);
}
std::wstring x_2;;
};
//表达式语法定义
模板
结构分析器:qi::grammar
{
parser():parser::base_类型(表达式)
{
使用名称空间qi;
表情=
术语[_val=_1]
>>*(('+'>>术语[_val=phx::construct(_val,_1)])
|('-'>>术语[_val=phx::construct(_val,_1)])
);
术语=
因素
qi::rule<It, std::wstring(), Skipper> scientificNumber;
Success: true Value: 2.7e-09
#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';
}