Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用具有不同迭代器类型的语法的boost::spirit::qi语法_C++_Parsing_Boost_Boost Spirit Qi - Fatal编程技术网

C++ 使用具有不同迭代器类型的语法的boost::spirit::qi语法

C++ 使用具有不同迭代器类型的语法的boost::spirit::qi语法,c++,parsing,boost,boost-spirit-qi,C++,Parsing,Boost,Boost Spirit Qi,我正面临着一个关于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::gramm

我正面临着一个关于
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_;
};

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

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

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

#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;
        }
    }
}
#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;
}
#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