无法在 Spirit:: Qi 中定义规则
我正在尝试将 Unix 文件路径解析为文件夹对(键/值对 - 根据我的应用程序的需要)。问题是我无法正确使用 qi::rule 定义解析器。我收到了一些我无法完全理解的编译器错误(抱歉,如果问题听起来很简单,但我真的陷入困境,无法继续)
下面是程序片段。
更新:我已经按照 Nicol 和 ildjarn 的建议修改了程序,但问题仍然存在。
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
template <typename Iterator>
bool parse_data(Iterator first, Iterator last, std::vector< std::pair<std::string, std::string> >& v)
{
using qi::double_;
using qi::char_;
using qi::phrase_parse;
using qi::_1;
using ascii::space_type;
using phoenix::ref;
using phoenix::push_back;
std::pair<std::string, std::string> p;
qi::rule<Iterator, std::string()> key = '/' >> *char_("a-zA-Z0-9");
qi::rule<Iterator, std::string()> val = '/' >> *char_("a-zA-Z0-9");
qi::rule<Iterator, std::pair<std::string, std::string>()> ppair = key >> val ;
//bool r = phrase_parse(
bool r = parse(
first,
last,
(
+ppair[push_back(ref(v), _1)]
)
);
if (first != last)
return false;
return r;
}
}
int
main()
{
std::string str;
while (getline(std::cin, str))
{
if (str.empty())
break;
std::vector< std::pair<std::string, std::string> > vec_pair;
if(client::parse_data(str.begin(), str.end(), vec_pair))
{
std::cout << std::endl << "Parsing done" << std::endl;
std::cout << "Strings are " ;
std::pair<std::string, std::string> temp;
for(std::vector< std::pair<std::string, std::string> >::iterator i = vec_pair.begin(); i < vec_pair.end(); i++)
{
temp = *i;
std::cout << temp.first <<"|" << temp.second;
}
std::cout << std::endl;
}
else
{
std::cout << "Parsing Failed" << std::endl;
}
}
return 0;
}
错误:
/usr/local/include/boost_1_46_1/boost/spirit/home/qi/detail/assign_to.hpp:109: error: no matching function for call to
‘std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pair(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)’
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:88: note: candidates are:
std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:84: note: std::pair<_T1, _T2>::pair() [with _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:73: note: std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pair(const std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)
你能帮我解决这个问题吗?
谢谢
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了让 Spirit 将数据解析为用户定义的数据结构,您必须提供一个适配器。这是通过 Boost.Fusion 完成的,如 文档中显示。您需要执行此操作:
请注意,此必须定义为全局范围(您必须退出
client
命名空间,定义它,然后重新进入client
命名空间)。但对于这种狭窄的情况,您最好解析为
std::pair
。精神知道如何处理这类事情。另请注意,这是 ildjarn 指出的
parse
与parse_phrase
问题的补充。两者都必须修复。还有一件事。您应该重新定义正在解析的规则。这:
具有
boost.tuple 的原始属性类型; >
。如果你这样做:那么你会得到一个干净的
std::vector
。In order for Spirit to parse data into a user-defined data structure, you must provide an adapter. This is done with Boost.Fusion, as shown in the documentation. You would need to do this:
Note that this must be defined a global scope (you must exit your
client
namespace, define this, then re-enter theclient
namespace).But for this narrow case, you'd be better off parsing into a
std::pair<std::string, std::string>
. Spirit knows how to work with that sort of thing.Also, note that this is in addition to the
parse
vs.parse_phrase
issue that ildjarn pointed out. Both must be fixed.One more thing. You should redefine the rule you are parsing. This:
Has a raw attribute type of
boost.tuple<client::pair, std::vector<client::pair> >
. If you do this:Then you get a clean
std::vector<client::pair>
.添加这些 #include 后,上面的程序对我来说编译得很好(Boost V1.47):
请注意,在此(最新)版本中对 Spirit 进行了相当多的实现更改,这可能解释了为什么它在这里编译,但不适合您(如果您使用的是旧版本)。
After adding these #include's your program above compiles fine for me (Boost V1.47):
Please note that there have been quite some implementation changes to Spirit in this (newest) version, which might explain why it compiles here, but not for you (if you're using an older version).