将规则生产绑定到我的结构成员时出现编译错误
Getting compilation errors while binding a rule production to my struct members
使用 Phoenix 绑定编写 Qi 语法时,我遇到了一个编译错误,例如
boost/spirit/home/support/context.hpp(180):错误 C2338:index_is_out_of_bounds
这里
>> ruleHandId_[phx::bind(&parseContext::handId_, qi::_r1) = qi::_1];
我只是没有太多的凤凰绑定到期,但 perv 绑定在线
ruleStart_ = ruleEncoding_[phx::bind(&parseContext::encoding_, qi::_r1) = qi::_1]
工作正常,没有编译错误
这一切都在VS2013的MSVC下,提升1.56 x86
我在编译错误的代码下做错了什么?
源代码
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <boost/shared_ptr.hpp>
#include <sstream>
namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
struct parseContext {
std::string encoding_;
uint64_t handId_;
};
typedef boost::shared_ptr<parseContext> parseContextShPtr;
template <typename Iterator>
struct parseGrammar : qi::grammar<Iterator, void(parseContext&)> {
parseGrammar() : parseGrammar::base_type(ruleStart_)
{
ruleStart_ = ruleEncoding_[phx::bind(&parseContext::encoding_, qi::_r1) = qi::_1]
>> ruleHandHeader_;
ruleEncoding_ = qi::lit("ABC");
ruleHandHeader_ = qi::lit("DEF") >> qi::space
>> qi::lit("XYZ #")
>> ruleHandId_[phx::bind(&parseContext::handId_, qi::_r1) = qi::_1];
ruleHandId_ = qi::long_long;
}
// Rules
qi::rule<Iterator, void(parseContext&)> ruleStart_;
qi::rule<Iterator, std::string()> ruleEncoding_;
qi::rule<Iterator> ruleHandHeader_;
qi::rule<Iterator, uint64_t> ruleHandId_;
};
void test()
{
std::string s("ABCDEF XYZ #555: PQI #777");
std::stringstream sb;
sb.unsetf(std::ios::skipws);
sb << s;
const parseGrammar<sp::istream_iterator> p;
sp::istream_iterator b(sb);
sp::istream_iterator e;
parseContextShPtr ctx(new parseContext);
bool r = qi::parse(b, e, p(phx::ref(*ctx.get())));
if (r) {
std::cout << "Success" << std::endl;
}
else {
std::cout << "Failure" << std::endl;
}
std::cout << std::string(b, e).substr(0, 32) << std::endl;
}
某些占位符无法绑定。
这可能是因为ruleEncoding_
没有公开属性(对于_1
)(不太可能)或ruleStart_
没有继承的属性(_r1
)。
这就是我现在能告诉你的。
编辑是后者。ruleHandHeader
不声明任何属性,更不用说要绑定到_r1
的继承属性了
更新到评论。
以下是一些建议。与我经常重复的避免语义行为的建议(Boost Spirit:"语义行为是邪恶的"?)非常相似,我会将结构调整为融合序列:
并使用简化得多的语法规则:
ruleStart_ = ruleEncoding_ >> ruleHandHeader_;
ruleEncoding_ = "ABC";
ruleHandId_ = qi::long_long;
ruleHandHeader_ = "DEF XYZ #" >> ruleHandId_;
现在,在规则定义中添加BOOST_SPIRIT_DEBUG
宏并将uint64_t
修复为uint64_t()
:
住在科里鲁
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/shared_ptr.hpp>
#include <sstream>
namespace qi = boost::spirit::qi;
struct parseContext {
std::string encoding_;
uint64_t handId_;
};
BOOST_FUSION_ADAPT_STRUCT(parseContext, (std::string, encoding_)(uint64_t,handId_))
typedef boost::shared_ptr<parseContext> parseContextShPtr;
template <typename Iterator>
struct parseGrammar : qi::grammar<Iterator, parseContext()> {
parseGrammar() : parseGrammar::base_type(ruleStart_)
{
ruleStart_ = ruleEncoding_ >> ruleHandHeader_;
ruleEncoding_ = "ABC";
ruleHandId_ = qi::long_long;
ruleHandHeader_ = "DEF XYZ #" >> ruleHandId_;
BOOST_SPIRIT_DEBUG_NODES((ruleStart_)(ruleEncoding_)(ruleHandId_)(ruleHandHeader_))
}
// Rules
qi::rule<Iterator, parseContext()> ruleStart_;
qi::rule<Iterator, std::string()> ruleEncoding_;
qi::rule<Iterator, uint64_t()> ruleHandId_, ruleHandHeader_;
};
void test()
{
std::stringstream sb("ABCDEF XYZ #555: PQI #777");
sb.unsetf(std::ios::skipws);
typedef boost::spirit::istream_iterator It;
const parseGrammar<It> p;
It b(sb), e;
parseContextShPtr ctx(new parseContext);
bool r = qi::parse(b, e, p, *ctx);
if (r) {
std::cout << "Success: " << ctx->encoding_ << ", " << ctx->handId_ << std::endl;
}
else {
std::cout << "Failure" << std::endl;
}
if (b!=e)
std::cout << "Remaining: '" << std::string(b, e).substr(0, 32) << "'...n";
}
int main()
{
test();
}
指纹
Success: ABC, 555
Remaining: ': PQI #777'...
相关文章:
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 获取 C2039:"交换":不是成员错误,如何解决?
- 在C 中获取Invalig使用非静态数据成员错误
- 非静态数据成员错误的使用无效
- 是非静态数据成员错误的CPPReference定义
- C++ 使用 & 从数组中的对象创建指针成员 [错误]
- C++,类:成员错误的行外声明
- 打印矢量成员.错误
- 可视化解决VS 2003中指向成员错误的c++指针
- 使用 '&' 创建指向成员错误的指针
- 无法访问在类"QReadWriteLock"中声明的私有成员错误 1 错误 C2248:'QReadWriteLock::QReadWriteLock'
- 如何修复MacOSX上全局命名空间中缺少时间相关的无成员错误
- 我的错误,还是英特尔编译器的错误?非静态成员错误的大小
- 链表访问私有成员错误C2248
- 模板友元函数 C++ 中无效使用非静态数据成员错误
- 使用 '&' 创建指向成员错误的指针
- c++友元函数不能访问私有成员;错误2248
- c++中的静态成员错误
- 类模板的静态成员错误
- 修改 int 类型的结构的成员错误:从 'int' 到 'const char*' [-fallowive] 的