Boost Spirit X3如何使用u8_to_u32_iterator?
How to use u8_to_u32_iterator in Boost Spirit X3?
我正在使用 Boost Spirit X3 创建编程语言,但是当我尝试支持 Unicode 时,出现错误!
这是该程序的简化版本示例。
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
struct sample : x3::symbols<unsigned> {
sample()
{
add("48", 10);
}
};
int main()
{
const std::string s("");
boost::u8_to_u32_iterator<std::string::const_iterator> first{cbegin(s)},
last{cend(s)};
x3::parse(first, last, sample{});
}
我该怎么办?
如您所见,char_encoding::unicode
在内部采用了 char32_t
。
因此,首先相应地更改 symbols
:
template <typename T>
using symbols = x3::symbols_parser<boost::spirit::char_encoding::unicode, T>;
struct sample : symbols<unsigned> {
sample() { add(U"48", 10); }
};
现在代码无法调用 case_compare
:
/home/sehe/custom/boost_1_78_0/boost/spirit/home/x3/string/detail/tst.hpp|74 col 33| error: no match for call to ‘(boost::spirit::x3::case_compare<boost::spirit::char_encoding::unicode>) (reference, char32_t&)’
如您所见,它需要一个 char32_t
引用,但是 u8_to_u32_iterator
returns unsigned int
s (std::uint32_t
).
仅用于比较/完整性检查:https://godbolt.org/z/1zozxq96W
幸运的是,您可以指示 u8_to_u32_iterator
使用另一个 co-domain 类型:
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
#include <iomanip>
#include <iostream>
namespace x3 = boost::spirit::x3;
template <typename T>
using symbols = x3::symbols_parser<boost::spirit::char_encoding::unicode, T>;
struct sample : symbols<unsigned> {
sample() { add(U"48", 10)(U"", 11); }
};
int main() {
auto test = [](auto const& s) {
boost::u8_to_u32_iterator<decltype(cbegin(s)), char32_t> first{
cbegin(s)},
last{cend(s)};
unsigned parsed_value;
if (x3::parse(first, last, sample{}, parsed_value)) {
std::cout << s << " -> " << parsed_value << "\n";
} else {
std::cout << s << " FAIL\n";
}
};
for (std::string s : {"", "48", ""})
test(s);
}
版画
-> 11
48 -> 10
FAIL
我正在使用 Boost Spirit X3 创建编程语言,但是当我尝试支持 Unicode 时,出现错误!
这是该程序的简化版本示例。
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
struct sample : x3::symbols<unsigned> {
sample()
{
add("48", 10);
}
};
int main()
{
const std::string s("");
boost::u8_to_u32_iterator<std::string::const_iterator> first{cbegin(s)},
last{cend(s)};
x3::parse(first, last, sample{});
}
我该怎么办?
如您所见,char_encoding::unicode
在内部采用了 char32_t
。
因此,首先相应地更改 symbols
:
template <typename T>
using symbols = x3::symbols_parser<boost::spirit::char_encoding::unicode, T>;
struct sample : symbols<unsigned> {
sample() { add(U"48", 10); }
};
现在代码无法调用 case_compare
:
/home/sehe/custom/boost_1_78_0/boost/spirit/home/x3/string/detail/tst.hpp|74 col 33| error: no match for call to ‘(boost::spirit::x3::case_compare<boost::spirit::char_encoding::unicode>) (reference, char32_t&)’
如您所见,它需要一个 char32_t
引用,但是 u8_to_u32_iterator
returns unsigned int
s (std::uint32_t
).
仅用于比较/完整性检查:https://godbolt.org/z/1zozxq96W
幸运的是,您可以指示 u8_to_u32_iterator
使用另一个 co-domain 类型:
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
#include <iomanip>
#include <iostream>
namespace x3 = boost::spirit::x3;
template <typename T>
using symbols = x3::symbols_parser<boost::spirit::char_encoding::unicode, T>;
struct sample : symbols<unsigned> {
sample() { add(U"48", 10)(U"", 11); }
};
int main() {
auto test = [](auto const& s) {
boost::u8_to_u32_iterator<decltype(cbegin(s)), char32_t> first{
cbegin(s)},
last{cend(s)};
unsigned parsed_value;
if (x3::parse(first, last, sample{}, parsed_value)) {
std::cout << s << " -> " << parsed_value << "\n";
} else {
std::cout << s << " FAIL\n";
}
};
for (std::string s : {"", "48", ""})
test(s);
}
版画
-> 11
48 -> 10
FAIL