我正试着写一本书
boost::uuids::uuid
boost::spirit::qi
为了更好地与其他人一起使用它
qi
解析器和有一个很好的统一解析器api。
我的第一个想法是写一个习惯
qi::grammar
用哪一个
boost::conversion::try_lexical_convert<boost::uuids::uuid &, const std::string &>
但是,这会有将begin迭代器正确设置为consumed位置的问题,因为
将不仅匹配16个字符长的输入,而且还匹配带大括号或不带破折号的输入。
我的第二种方法是使用
boost::spirit::qi::rule
boost::spirit::qi::grammar::base_type
如果你愿意的话),但是我得到了编译错误,可能来自
BOOST_FUSION_ADAPT_STRUCT
表达方式:
#include <iostream>
#include <string>
#include <cstdint>
#include <boost/uuid/uuid.hpp>
#include <boost/spirit/include/qi.hpp>
BOOST_FUSION_ADAPT_STRUCT(
boost::uuids::uuid,
(uint8_t, data[0])
(uint8_t, data[1])
(uint8_t, data[2])
(uint8_t, data[3])
(uint8_t, data[4])
(uint8_t, data[5])
(uint8_t, data[6])
(uint8_t, data[7])
(uint8_t, data[8])
(uint8_t, data[9])
(uint8_t, data[10])
(uint8_t, data[11])
(uint8_t, data[12])
(uint8_t, data[13])
(uint8_t, data[14])
(uint8_t, data[15])
)
template<typename Iterator>
boost::spirit::qi::rule<Iterator, boost::uuids::uuid>
uuid_internal_{
boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
//time-low
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
//time-mid
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
//time-high-and-version
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>() //clock-seq-and-reserved
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>() //clock-seq-low
>> -boost::spirit::qi::lit("-")
//node
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
};
template<typename Iterator>
struct uuid_
: ::boost::spirit::qi::grammar<Iterator, boost::uuids::uuid()>{
uuid_() : uuid_::base_type(start) {
start %= (boost::spirit::qi::lit("{") >> uuid_internal_ >> boost::spirit::qi::lit("}")) |
uuid_internal_ ;
}
boost::spirit::qi::rule<Iterator, boost::uuids::uuid()> start;
boost::spirit::qi::rule<Iterator, boost::uuids::uuid()>
uuid_internal_{
boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
//time-low
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
//time-mid
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
//time-high-and-version
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> -boost::spirit::qi::lit("-")
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>() //clock-seq-and-reserved
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>() //clock-seq-low
>> -boost::spirit::qi::lit("-")
//node
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
>> boost::spirit::qi::uint_parser<uint8_t, 16, 1, 1>()
};
};
int main() {
std::string input;
std::cin >> input;
uuid_<std::string::const_iterator> uuid_{};
boost::uuids::uuid uuid{};
auto begin = input.begin(), end = input.end();
const bool success = boost::spirit::qi::parse(begin, end, uuid_, uuid);
if (!success || begin != end)
throw std::runtime_error("Parsing failed");
return 0;
}
/opt/local/include/boost/spirit/home/support/container.hpp:292:15:错误:boost::uuids::uuid中没有名为“insert”的成员
c、 插入(c.end(),val);
似乎是由生成的
boost::spirit::qi::detail::pass_through_container
然而,我的方法
BOOST_FUSION_ADAPT_ADT
结合
*(obj.begin()+n)
也因多个错误而失败。