gpt4 book ai didi

c++ - boost::spirit::qi 文法使用不同迭代器类型的文法

转载 作者:行者123 更新时间:2023-11-30 03:28:55 25 4
gpt4 key购买 nike

我遇到了 boost::spirit::qi 的问题。我定义了以下两个解析器:

struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))

struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))

struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};

struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};

现在,我想用前面的语法写第三个语法,如下:

typedef boost::variant<attr_1, attr_2> attr_comp;

struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};

由于 grammar_1grammar_2 具有不同的迭代器类型,我应该将哪种类型放在新语法的定义中?

这是一个(非编译)简化示例:

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <sstream>

struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))

struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))

struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};

struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};

typedef boost::variant<attr_1, attr_2> attr_comp;

struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};

int main() {
std::string s;
std::istringstream iss("3\n13.2\nCIAO\nFOOFOOfoo\n");
grammar_comp gg_;
attr_comp aa_;
while (std::getline(iss, s)){
auto it = s.begin();
if (boost::spirit::qi::parse(it, s.end(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
return 0;
}

最佳答案

您不能使用不同迭代器类型的子语法。出于显而易见的原因,您不会神奇地解析不同的输入集。

单个输入意味着单个输入迭代器范围。

只需将关于迭代器类型的决定推迟到顶层实例化器:

Live On Coliru

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <sstream>
#include <string>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

struct attr_1 {
std::string a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))

struct attr_2 {
double a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))

template <typename It = const char *> struct grammar_1 : qi::grammar<It, attr_1()> {
grammar_1() : grammar_1::base_type{ rule_ } { rule_ = qi::eps >> +ascii::upper; }

private:
qi::rule<It, attr_1()> rule_;
};

template <typename It = std::string::const_iterator> struct grammar_2 : qi::grammar<It, attr_2()> {
grammar_2() : grammar_2::base_type{ rule_ } { rule_ = qi::double_; }

private:
qi::rule<It, attr_2()> rule_;
};

typedef boost::variant<attr_1, attr_2> attr_comp;

template <typename It = std::string::const_iterator> struct grammar_comp : qi::grammar<It, attr_comp()> {
grammar_comp() : grammar_comp::base_type{ rule_ } { rule_ = (g1_ | g2_); }

private:
grammar_1<It> g1_;
grammar_2<It> g2_;
qi::rule<It, attr_comp()> rule_;
};

int main() {
std::istringstream iss("3\n13.2\nCIAO\nFOOFOOfoo\n");

grammar_comp<> gg_;
attr_comp aa_;
std::string s;

while (std::getline(iss, s)) {
auto it = s.cbegin();
if (qi::parse(it, s.cend(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
}

打印

3

13.2

CIAO

FOOFOOfoo

关于c++ - boost::spirit::qi 文法使用不同迭代器类型的文法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46202007/

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