gpt4 book ai didi

c++ - 如何使用存储在 boost spirit 闭包中的变量作为 boost spirit 循环解析器的输入?

转载 作者:太空狗 更新时间:2023-10-29 21:30:58 34 4
gpt4 key购买 nike

我想使用解析后的值作为循环解析器的输入。

语法定义了一个 header ,它指定了以下字符串的(可变)大小。例如,假设以下字符串是某个解析器的输入。

12\r\nTest Payload

解析器应提取 12,将其转换为 unsigned int,然后读取十二个字符。我可以定义可编译的 boost spirit 语法,但 boost spirit 代码中的断言在运行时失败。

#include <iostream>
#include <boost/spirit.hpp>

using namespace boost::spirit;

struct my_closure : public closure<my_closure, std::size_t> {
member1 size;
};

struct my_grammar : public grammar<my_grammar> {
template <typename ScannerT>
struct definition {
typedef rule<ScannerT> rule_type;
typedef rule<ScannerT, my_closure::context_t> closure_rule_type;

closure_rule_type header;
rule_type payload;
rule_type top;

definition(const my_grammar &self)
{
using namespace phoenix;
header = uint_p[header.size = arg1];
payload = repeat_p(header.size())[anychar_p][assign_a(self.result)];
top = header >> str_p("\r\n") >> payload;
}

const rule_type &start() const { return top; }
};

my_grammar(std::string &p_) : result(p_) {}
std::string &result;
};

int
main(int argc, char **argv)
{
const std::string content = "12\r\nTest Payload";
std::string payload;
my_grammar g(payload);
if (!parse(content.begin(), content.end(), g).full) {
std::cerr << "there was a parsing error!\n";
return -1;
}
std::cout << "Payload: " << payload << std::endl;
return 0;
}

是否可以告诉 spirit 应该延迟计算闭包变量?这种行为是否得到 boost spirit 的支持?

最佳答案

使用 Spirit 2 中可用的新 qi 解析器,这要容易得多。以下代码片段提供了一个大部分有效的完整示例。最终结果中插入了意外字符。

#include <iostream>
#include <string>

#include <boost/version.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_repeat.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

using boost::spirit::qi::repeat;
using boost::spirit::qi::uint_;
using boost::spirit::ascii::char_;
using boost::spirit::ascii::alpha;
using boost::spirit::qi::_1;
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;

template <typename P, typename T>
void test_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::parse;

char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}

static void
straight_forward()
{
std::string str;
int n;
test_parser_attr("12\r\nTest Payload",
uint_[phx::ref(n) = _1] >> "\r\n" >> repeat(phx::ref(n))[char_],
str);
std::cout << "str.length() == " << str.length() << std::endl;
std::cout << n << "," << str << std::endl; // will print "12,Test Payload"
}

template <typename P, typename T>
void
test_phrase_parser(char const* input, P const& p,
T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;

char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}

template <typename Iterator>
struct test_grammar
: qi::grammar<Iterator, std::string(), qi::locals<unsigned> > {

test_grammar()
: test_grammar::base_type(my_rule)
{
using boost::spirit::qi::_a;
my_rule %= uint_[_a = _1] >> "\r\n" >> repeat(_a)[char_];
}

qi::rule<Iterator, std::string(), qi::locals<unsigned> > my_rule;
};

static void
with_grammar_local_variable()
{
std::string str;
test_phrase_parser("12\r\nTest Payload", test_grammar<const char*>(), str);
std::cout << str << std::endl; // will print "Test Payload"
}

int
main(int argc, char **argv)
{
std::cout << "boost version: " << BOOST_LIB_VERSION << std::endl;

straight_forward();
with_grammar_local_variable();

return 0;
}

关于c++ - 如何使用存储在 boost spirit 闭包中的变量作为 boost spirit 循环解析器的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1474990/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com