使用 sprit boost 解析器库规则调用函数或仿函数以将值保存在向量 c++ 中
Function or functor calling using sprit boost parser library rule to save values in vector c++
我想解析这一行并将所有十六进制值存储在仿函数中
<005F> <0061> [<00660066> <00660069> <00660066006C>]
txt 文件中的此值和 m 逐行读取此填充
喜欢
005F 0061 00660066 00660069 00660066006C
所有值都应该在向量中,但它不起作用
精神规则是解析这一行是
rule<> blanks = *blank_p;
rule<> parse_int = blanks >> "<" >> int_p [AddEntry] >> ">";
rule<> parse_ints = *parse_int ;
rule<> parse_range = *parse_int >>"[" >> blanks >> *parse_int >> "]";
int status = parse (line.c_str(),
*(
parse_range
)
).full;
我的仿函数是
struct AddEntry
{
vector<int> list;
void operator()( int integer)
{
list.push_back(integer);
}
};
这是使用 Spirit V2 执行此操作的示例
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
typedef std::string::const_iterator It;
std::string const line = "<005F> <0061> [<00660066> <00660069> <00660066006C>]";
It f = line.begin(), l = line.end();
qi::int_parser<uintmax_t, 16> hex_int;
qi::rule<It, uintmax_t()> braced_hex = '<' >> hex_int >> '>';
BOOST_SPIRIT_DEBUG_NODE(braced_hex);
std::vector<uintmax_t> list;
bool result = qi::phrase_parse(f, l, *braced_hex >> '[' >> *braced_hex >> ']', qi::space, list);
if (result) {
std::cout << "Parse success: " << list.size() << "\n";
for (auto& v : list)
std::cout << v << " ";
}
else {
std::cout << "Parse failed\n";
}
if (f!=l) {
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
输出:
Parse success: 5
95 97 6684774 6684777 438093348972
调试输出(如果启用):
<braced_hex>
<try><005F> <0061> [<0066</try>
<success> <0061> [<00660066> </success>
<attributes>[95]</attributes>
</braced_hex>
<braced_hex>
<try><0061> [<00660066> <</try>
<success> [<00660066> <006600</success>
<attributes>[97]</attributes>
</braced_hex>
<braced_hex>
<try>[<00660066> <0066006</try>
<fail/>
</braced_hex>
<braced_hex>
<try><00660066> <00660069</try>
<success> <00660069> <0066006</success>
<attributes>[6684774]</attributes>
</braced_hex>
<braced_hex>
<try><00660069> <00660066</try>
<success> <00660066006C>]</success>
<attributes>[6684777]</attributes>
</braced_hex>
<braced_hex>
<try><00660066006C>]</try>
<success>]</success>
<attributes>[438093348972]</attributes>
</braced_hex>
<braced_hex>
<try>]</try>
<fail/>
</braced_hex>
请注意,在我的系统上 int
不够大,无法容纳这些数字,因此解析会失败。对于最大范围,我使用 intmax_t
但您可以使用其他类型,包括任意精度类型:
- 128 bit string to array using boost::spirit::*
另请注意,我不喜欢使用语义操作,而是使用自动属性传播。这在 Spirit V2 中非常普遍。另见
- Boost Spirit: "Semantic actions are evil"?
我想解析这一行并将所有十六进制值存储在仿函数中 <005F> <0061> [<00660066> <00660069> <00660066006C>] txt 文件中的此值和 m 逐行读取此填充
喜欢 005F 0061 00660066 00660069 00660066006C 所有值都应该在向量中,但它不起作用
精神规则是解析这一行是
rule<> blanks = *blank_p;
rule<> parse_int = blanks >> "<" >> int_p [AddEntry] >> ">";
rule<> parse_ints = *parse_int ;
rule<> parse_range = *parse_int >>"[" >> blanks >> *parse_int >> "]";
int status = parse (line.c_str(),
*(
parse_range
)
).full;
我的仿函数是
struct AddEntry
{
vector<int> list;
void operator()( int integer)
{
list.push_back(integer);
}
};
这是使用 Spirit V2 执行此操作的示例
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
typedef std::string::const_iterator It;
std::string const line = "<005F> <0061> [<00660066> <00660069> <00660066006C>]";
It f = line.begin(), l = line.end();
qi::int_parser<uintmax_t, 16> hex_int;
qi::rule<It, uintmax_t()> braced_hex = '<' >> hex_int >> '>';
BOOST_SPIRIT_DEBUG_NODE(braced_hex);
std::vector<uintmax_t> list;
bool result = qi::phrase_parse(f, l, *braced_hex >> '[' >> *braced_hex >> ']', qi::space, list);
if (result) {
std::cout << "Parse success: " << list.size() << "\n";
for (auto& v : list)
std::cout << v << " ";
}
else {
std::cout << "Parse failed\n";
}
if (f!=l) {
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
输出:
Parse success: 5
95 97 6684774 6684777 438093348972
调试输出(如果启用):
<braced_hex>
<try><005F> <0061> [<0066</try>
<success> <0061> [<00660066> </success>
<attributes>[95]</attributes>
</braced_hex>
<braced_hex>
<try><0061> [<00660066> <</try>
<success> [<00660066> <006600</success>
<attributes>[97]</attributes>
</braced_hex>
<braced_hex>
<try>[<00660066> <0066006</try>
<fail/>
</braced_hex>
<braced_hex>
<try><00660066> <00660069</try>
<success> <00660069> <0066006</success>
<attributes>[6684774]</attributes>
</braced_hex>
<braced_hex>
<try><00660069> <00660066</try>
<success> <00660066006C>]</success>
<attributes>[6684777]</attributes>
</braced_hex>
<braced_hex>
<try><00660066006C>]</try>
<success>]</success>
<attributes>[438093348972]</attributes>
</braced_hex>
<braced_hex>
<try>]</try>
<fail/>
</braced_hex>
请注意,在我的系统上 int
不够大,无法容纳这些数字,因此解析会失败。对于最大范围,我使用 intmax_t
但您可以使用其他类型,包括任意精度类型:
- 128 bit string to array using boost::spirit::*
另请注意,我不喜欢使用语义操作,而是使用自动属性传播。这在 Spirit V2 中非常普遍。另见
- Boost Spirit: "Semantic actions are evil"?