C++ 向量置换解析器<;bool>;,通过火柴

C++ 向量置换解析器<;bool>;,通过火柴,c++,boost-spirit,boost-spirit-qi,C++,Boost Spirit,Boost Spirit Qi,在我的boost中,我有以下规则::spirit语法 rule = (qi::token(ABSTRACT) ^ qi::token(STATIC) ^ qi::token(FINAL)) 该结构具有以下类型: boost::fusion::vector3<boost::optional<boost::iterator_range<std::string::iterator>>, boost::optional<boost::iterator_range&l

在我的boost中,我有以下规则::spirit语法

rule = (qi::token(ABSTRACT) ^ qi::token(STATIC) ^ qi::token(FINAL))
该结构具有以下类型:

boost::fusion::vector3<boost::optional<boost::iterator_range<std::string::iterator>>, boost::optional<boost::iterator_range<std::string::iterator>>, boost::optional<boost::iterator_range<std::string::iterator>>>
哪一个有类型

boost::fusion::vector3<boost::optional<bool>, boost::optional<bool>, boost::optional<bool>>
boost::fusion::vector3

这确实不是我想要的,那么我该怎么做,以随机顺序匹配这三个标记,并得到它们是否匹配为布尔值?

我假设你并不真的需要一个
fusion::vector
,你只是想让它工作。如果这个假设是错误的,只需在评论中说些什么


如图所示,置换解析器的属性为
tuple@P0W这是一个boost fusion向量,而不是您希望避免bools的
std::vector
。我猜缺少一些上下文?置换解析器的属性将始终是
fusion::vector
。我认为这个向量应该与
fusion::vector
兼容(它应该将每个非空的可选项分配给相应的元素)。我看到您的代码存在的问题是,
qi::matches
总是成功的,因此我认为只有当这三个关键字都存在并且顺序正确时,您的代码才能工作。@Skeen注意,在我的“艺术家印象”(artist impression)中,我显示了。@sehe应该是。。。习惯性地将此作为回答;)我使用了一些与显式属性方法类似的方法。
(qi::matches[qi::raw_token(ABSTRACT)] ^ qi::matches[qi::raw_token(STATIC)] ^ qi::matches[qi::raw_token(FINAL)])
boost::fusion::vector3<boost::optional<bool>, boost::optional<bool>, boost::optional<bool>>
USING MATCHES: final abstract static

<abstract1>

  <try>final abstract stati</try>

  <success>final abstract stati</success>

  <attributes>[0]</attributes>

</abstract1>

<static1>

  <try>final abstract stati</try>

  <success>final abstract stati</success>

  <attributes>[0]</attributes>

</static1>

<final1>

  <try>final abstract stati</try>

  <success> abstract static</success>

  <attributes>[1]</attributes>

</final1>
#include <iostream>
#include <string>
#include <vector>

#define BOOST_SPIRIT_DEBUG

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

struct class_info
{
    class_info():abstract_(),static_(),final_(){}
    bool abstract_;
    bool static_;
    bool final_;
};

BOOST_FUSION_ADAPT_STRUCT
(
    class_info,
    (bool, abstract_)
    (bool, static_)
    (bool, final_)
)

namespace qi=boost::spirit::qi;

template <typename Parser>
void parse_triplet(const std::string& test, const Parser& parser)
{
    std::string::const_iterator iter=test.begin(), end=test.end();
    class_info parsed_class;

    bool result=qi::phrase_parse(iter,end,parser,qi::space,parsed_class);

    if(!result)
    {
        std::cout << "The triplet could not be parsed. Unparsed: " << std::string(iter,end) << std::endl;
    }
    else
    {
        if(iter==end)
        {
            std::cout << "A triplet was parsed." << std::endl;
            std::cout << parsed_class.abstract_ << parsed_class.static_ << parsed_class.final_ << std::endl;
        }
        else
        {
            std::cout << "A triplet was parsed, but part of the input remained unparsed." << std::endl;
            std::cout << parsed_class.abstract_ << parsed_class.static_ << parsed_class.final_ << std::endl;
            std::cout << "Unparsed: " << std::string(iter,end) << std::endl;
        }
    }

}


int main()
{
    std::vector<std::string> tests;
    tests.push_back("final abstract static");
    tests.push_back("final abstract");
    tests.push_back("static");
    tests.push_back("static abstract");
    qi::rule<std::string::const_iterator,bool(),qi::space_type> abstract1, abstract2, static1, static2, final1, final2;
    abstract1 = qi::matches[qi::lit("abstract")];
    abstract2 = qi::lit("abstract") >> qi::attr(true);
    static1 = qi::matches[qi::lit("static")];
    static2 = qi::lit("static") >> qi::attr(true);
    final1 = qi::matches[qi::lit("final")];
    final2 = qi::lit("final") >> qi::attr(true);

    BOOST_SPIRIT_DEBUG_NODES( (abstract1)(abstract2)(static1)(static2)(final1)(final2) );

    for(std::size_t cont=0; cont < tests.size(); ++cont)
    {
            //THIS IS WRONG
        std::cout << "USING MATCHES: " << tests[cont] << std::endl;
        parse_triplet(tests[cont],abstract1 ^ static1 ^ final1);

            //THIS WORKS
        std::cout << "USING EXPLICIT ATTRIBUTE: " << tests[cont] << std::endl;
        parse_triplet(tests[cont],abstract2 ^ static2 ^ final2);


    }
}