Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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++ 精神:将弦对从Qi移植到X3_C++_Boost_Boost Spirit_Boost Spirit Qi_Boost Spirit X3 - Fatal编程技术网

C++ 精神:将弦对从Qi移植到X3

C++ 精神:将弦对从Qi移植到X3,c++,boost,boost-spirit,boost-spirit-qi,boost-spirit-x3,C++,Boost,Boost Spirit,Boost Spirit Qi,Boost Spirit X3,我有以下工作Qi代码: struct query_grammar : public boost::spirit::qi::grammar<Iterator, string_map<std::string>()> { query_grammar() : query_grammar::base_type(query) { query = pair >> *(boost::spirit::qi::lit('&') >> p

我有以下工作Qi代码:

struct query_grammar
    : public boost::spirit::qi::grammar<Iterator, string_map<std::string>()>
{
  query_grammar() : query_grammar::base_type(query)
  {
    query = pair >> *(boost::spirit::qi::lit('&') >> pair);
    pair = +qchar >> -(boost::spirit::qi::lit('=') >> +qchar);
    qchar = ~boost::spirit::qi::char_("&=");
  }

  boost::spirit::qi::rule<Iterator, std::map<std::string,std::string>()> query;
  boost::spirit::qi::rule<Iterator, std::map<std::string,std::string>::value_type()> pair;
  boost::spirit::qi::rule<Iterator, char()> qchar;
};
我看到了这个答案:我试着把我的线对弄成生的,但没有用


编辑:

spirit示例中的示例代码也未编译,因此我猜问题更为严重:

#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;
int main()
{
  std::string input( "cosmic  pizza  " );
  auto iter = input.begin();
  auto end_iter = input.end();
  std::pair<std::string, std::string> result;
  x3::parse( iter, end_iter, *(~x3::char_(' ')) >> ' ' >> *x3::char_, result);
}
#包括
名称空间x3=boost::spirit::x3;
int main()
{
std::字符串输入(“宇宙比萨饼”);
auto iter=input.begin();
auto end_iter=input.end();
std::配对结果;
x3::parse(iter,end_iter,*(~x3::char_u('')>'>'>'>>*x3::char_u,result);
}
Qi修复程序 首先,我必须用Qi变量修复规则声明,然后它才能工作:

qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
印刷品

======= foo=bar&baz=boo
Parsed 2 pairs
气改善 以下更简单的语法似乎更好:

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>

namespace qi = boost::spirit::qi;

template <typename T> using string_map = std::map<T, T>;

template <typename Iterator>
struct query_grammar : public qi::grammar<Iterator, string_map<std::string>()>
{
    query_grammar() : query_grammar::base_type(query)
    {
        qchar = ~qi::char_("&=");
        pair  = +qchar >> -(qi::lit('=') >> +qchar);
        query = pair >> *(qi::lit('&') >> pair);
    }

  private:
    qi::rule<Iterator, std::map<std::string,std::string>()> query;
    qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
    qi::rule<Iterator, char()> qchar;
};

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, query_grammar<It>{}, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
template <typename Iterator, typename T = std::string>
struct query_grammar : public qi::grammar<Iterator, string_map<T>()>
{
    query_grammar() : query_grammar::base_type(query) {
        using namespace qi;
        pair  =  +~char_("&=") >> '=' >> *~char_("&");
        query = pair % '&';
    }

  private:
    qi::rule<Iterator, std::pair<T,T>()> pair;
    qi::rule<Iterator, std::map<T,T>()> query;
};
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <iostream>
#include <map>

namespace x3 = boost::spirit::x3;

template <typename T> using string_map = std::map<T, T>;

namespace grammar {
    using namespace x3;
    auto pair  =  +~char_("&=") >> '=' >> *~char_("&");
    auto query = pair % '&';
}

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, grammar::query, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
很明显,(--)打印了

X3改进 您可能需要强制规则的属性类型,因为自动属性传播可能会有令人惊讶的启发

namespace grammar {

    template <typename T = std::string> auto& query() {
        using namespace x3;

        static const auto s_pair  
            = rule<struct pair_, std::pair<T, T> > {"pair"} 
            = +~char_("&=") >> -('=' >> *~char_("&"));
        static const auto s_query
            = rule<struct query_, std::map<T, T> > {"query"}
            = s_pair % '&';

        return s_query;
    };

}
名称空间语法{
模板自动查询(&query)(){
使用名称空间x3;
静态常数自动s_对
=规则{“对”}
=+~char_u(“&=”)>>-(“='>>*~char_u(“&”);
静态常量自动s_查询
=规则{“查询”}
=s_对%'&';
返回s_查询;
};
}
查看它

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>

namespace qi = boost::spirit::qi;

template <typename T> using string_map = std::map<T, T>;

template <typename Iterator>
struct query_grammar : public qi::grammar<Iterator, string_map<std::string>()>
{
    query_grammar() : query_grammar::base_type(query)
    {
        qchar = ~qi::char_("&=");
        pair  = +qchar >> -(qi::lit('=') >> +qchar);
        query = pair >> *(qi::lit('&') >> pair);
    }

  private:
    qi::rule<Iterator, std::map<std::string,std::string>()> query;
    qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
    qi::rule<Iterator, char()> qchar;
};

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, query_grammar<It>{}, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
template <typename Iterator, typename T = std::string>
struct query_grammar : public qi::grammar<Iterator, string_map<T>()>
{
    query_grammar() : query_grammar::base_type(query) {
        using namespace qi;
        pair  =  +~char_("&=") >> '=' >> *~char_("&");
        query = pair % '&';
    }

  private:
    qi::rule<Iterator, std::pair<T,T>()> pair;
    qi::rule<Iterator, std::map<T,T>()> query;
};
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <iostream>
#include <map>

namespace x3 = boost::spirit::x3;

template <typename T> using string_map = std::map<T, T>;

namespace grammar {
    using namespace x3;
    auto pair  =  +~char_("&=") >> '=' >> *~char_("&");
    auto query = pair % '&';
}

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, grammar::query, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
出了什么问题? X3版本在
std::map::value\u type

Qi修复中遇到了与const key type相同的问题 首先,我必须用Qi变量修复规则声明,然后它才能工作:

qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
印刷品

======= foo=bar&baz=boo
Parsed 2 pairs
气改善 以下更简单的语法似乎更好:

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>

namespace qi = boost::spirit::qi;

template <typename T> using string_map = std::map<T, T>;

template <typename Iterator>
struct query_grammar : public qi::grammar<Iterator, string_map<std::string>()>
{
    query_grammar() : query_grammar::base_type(query)
    {
        qchar = ~qi::char_("&=");
        pair  = +qchar >> -(qi::lit('=') >> +qchar);
        query = pair >> *(qi::lit('&') >> pair);
    }

  private:
    qi::rule<Iterator, std::map<std::string,std::string>()> query;
    qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
    qi::rule<Iterator, char()> qchar;
};

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, query_grammar<It>{}, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
template <typename Iterator, typename T = std::string>
struct query_grammar : public qi::grammar<Iterator, string_map<T>()>
{
    query_grammar() : query_grammar::base_type(query) {
        using namespace qi;
        pair  =  +~char_("&=") >> '=' >> *~char_("&");
        query = pair % '&';
    }

  private:
    qi::rule<Iterator, std::pair<T,T>()> pair;
    qi::rule<Iterator, std::map<T,T>()> query;
};
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <iostream>
#include <map>

namespace x3 = boost::spirit::x3;

template <typename T> using string_map = std::map<T, T>;

namespace grammar {
    using namespace x3;
    auto pair  =  +~char_("&=") >> '=' >> *~char_("&");
    auto query = pair % '&';
}

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, grammar::query, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
很明显,(--)打印了

X3改进 您可能需要强制规则的属性类型,因为自动属性传播可能会有令人惊讶的启发

namespace grammar {

    template <typename T = std::string> auto& query() {
        using namespace x3;

        static const auto s_pair  
            = rule<struct pair_, std::pair<T, T> > {"pair"} 
            = +~char_("&=") >> -('=' >> *~char_("&"));
        static const auto s_query
            = rule<struct query_, std::map<T, T> > {"query"}
            = s_pair % '&';

        return s_query;
    };

}
名称空间语法{
模板自动查询(&query)(){
使用名称空间x3;
静态常数自动s_对
=规则{“对”}
=+~char_u(“&=”)>>-(“='>>*~char_u(“&”);
静态常量自动s_查询
=规则{“查询”}
=s_对%'&';
返回s_查询;
};
}
查看它

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>

namespace qi = boost::spirit::qi;

template <typename T> using string_map = std::map<T, T>;

template <typename Iterator>
struct query_grammar : public qi::grammar<Iterator, string_map<std::string>()>
{
    query_grammar() : query_grammar::base_type(query)
    {
        qchar = ~qi::char_("&=");
        pair  = +qchar >> -(qi::lit('=') >> +qchar);
        query = pair >> *(qi::lit('&') >> pair);
    }

  private:
    qi::rule<Iterator, std::map<std::string,std::string>()> query;
    qi::rule<Iterator, std::pair<std::string,std::string>()> pair;
    qi::rule<Iterator, char()> qchar;
};

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, query_grammar<It>{}, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
template <typename Iterator, typename T = std::string>
struct query_grammar : public qi::grammar<Iterator, string_map<T>()>
{
    query_grammar() : query_grammar::base_type(query) {
        using namespace qi;
        pair  =  +~char_("&=") >> '=' >> *~char_("&");
        query = pair % '&';
    }

  private:
    qi::rule<Iterator, std::pair<T,T>()> pair;
    qi::rule<Iterator, std::map<T,T>()> query;
};
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <iostream>
#include <map>

namespace x3 = boost::spirit::x3;

template <typename T> using string_map = std::map<T, T>;

namespace grammar {
    using namespace x3;
    auto pair  =  +~char_("&=") >> '=' >> *~char_("&");
    auto query = pair % '&';
}

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : { "foo=bar&baz=boo" })
    {
        std::cout << "======= " << input << "\n";
        It f = input.begin(), l = input.end();
        string_map<std::string> sm;
        if (parse(f, l, grammar::query, sm)) {
            std::cout << "Parsed " << sm.size() << " pairs\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}
出了什么问题?
X3版本在
std::map::value\u type

mhh中遇到了与const key type相同的问题。。。一定是出了什么问题,因为在这里尝试幻灯片42上的字符串对示例时:它也不起作用。输入示例是什么我的原始代码用于解析http请求:foo=bar&baz=booCool。现在看看它。。。一定是出了什么问题,因为在这里尝试幻灯片42上的字符串对示例时:它也不起作用。输入示例是什么我的原始代码用于解析http请求:foo=bar&baz=booCool。现在就看,谢谢语法的改进!我的编译错误是由于其他人无意中发现了include而导致的:
#include
(也谢谢@K-ballo)。不是的:(我非常了解include)我还想知道为什么我发布的Qi版本(带有const std::string)对我来说确实有效。我测试了大约10分钟的错误版本;)这里确认的是,
:value_type
的const键确实是一个障碍(注意,由于所述原因,我的答案/评论中的版本仍然更好),感谢改进的语法!我的编译错误是由于其他人无意中发现了include而导致的:
#include
(也谢谢@K-ballo)。不是的:(我非常了解include)我还想知道为什么我发布的Qi版本(带有const std::string)对我来说确实有效。我测试了大约10分钟的错误版本;)这里确认的是,
:value_type
的const键确实是一个障碍(注意,由于所述原因,我的答案/评论中的版本仍然更好)