我会简化使用一个适当的规则,这样你就不需要详细说明了
as_string
在解析表达式中。
那里
是
在这种特殊情况下,它的工作方式出现了问题(应该作为bug报告给库维护人员)。但是,我可以通过添加一个
eps
解析器内部
raw
指令:
r %= '<' >> raw[int64_[phx::ref(value) = _1] >> eps] >> '>';
(另请注意,不需要解析括号
char_
).
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iomanip>
using namespace std::string_literals;
int main()
{
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
qi::rule<std::string::const_iterator, std::string()> r;
int64_t value;
{
using namespace qi;
static const int_parser<int64_t> int64_{};
r %= '<' >> raw[int64_[phx::ref(value) = _1] >> eps] >> '>';
}
using Lim = std::numeric_limits<decltype(value)>;
for (std::string const test_str : {
"<+123>"s,
"<0123>"s,
"<0123>"s,
"<123>"s,
"<" + std::to_string(Lim::max()) + ">",
"<" + std::to_string(Lim::min()) + ">",
})
{
std::string value_str;
auto success
= qi::parse(test_str.begin(), test_str.end(), r, value_str);
std::cout << "success: " << std::boolalpha << success << "\n";
std::cout << "value: " << value << "\n";
std::cout << "matched substring: " << std::quoted(value_str) << "\n";
}
}
印刷品
success: true
value: 123
matched substring: "+123"
success: true
value: 123
matched substring: "0123"
success: true
value: 123
matched substring: "0123"
success: true
value: 123
matched substring: "123"
success: true
value: 9223372036854775807
matched substring: "9223372036854775807"
success: true
value: -9223372036854775808
matched substring: "-9223372036854775808"
奖金
也封装“value”参数,这样就不用全局变量了:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iomanip>
using namespace std::string_literals;
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using It = std::string::const_iterator;
using T = std::int64_t;
struct Parser : qi::grammar<It, std::string(T&)> {
Parser() : Parser::base_type(r) {
r %= '<' >> qi::raw[ int64_[qi::_r1 = qi::_1] >> qi::eps ] >> '>';
}
private:
qi::int_parser<T> int64_;
qi::rule<It, std::string(T&)> r;
};
int main()
{
Parser const p;
using Lim = std::numeric_limits<T>;
for (std::string const test_str : {
"<+123>"s,
"<0123>"s,
"<0123>"s,
"<123>"s,
"<" + std::to_string(Lim::max()) + ">",
"<" + std::to_string(Lim::min()) + ">",
})
{
std::string value_str;
int64_t value;
auto success
= qi::parse(test_str.begin(), test_str.end(), p(phx::ref(value)), value_str);
std::cout << "success: " << std::boolalpha << success << "\n";
std::cout << "value: " << value << "\n";
std::cout << "matched substring: " << std::quoted(value_str) << "\n";
}
}
印刷:
成功:真
值:123
匹配的子字符串:“+123”
成功:真
值:123
匹配的子字符串:“0123”
成功:真
值:123
匹配的子字符串:“0123”
成功:真
值:123
匹配的子字符串:“123”
成功:真
价值:9223372036854775807
匹配的子字符串:“9223372036854775807”
成功:真
数值:-922372036854775808
匹配的子字符串:“-922372036854775808”