boost :: spirit两次使用相同的符号

时间:2019-04-02 17:54:11

标签: c++ boost boost-spirit

我的语法与此相似:

 template <class ITER>
struct MessageParser
    : public boost::spirit::qi::grammar<ITER, Message(), boost::spirit::ascii::space_type>
{
    MessageParser()
        : MessageParser::base_type(start_)
    {
        string_ = +(char_("a-zA-Z_") >> *char_("a-zA-Z_0-9"));
        quoted_string_ = lexeme['"' >> +(char_ - '"') >> '"'];
        signal_ %= lit("SG_")  // type is Signal
            >> string_ >> ':'; // Signal name
        message_ %= lit("BO_") // type is Message
            >> int_
            >> string_ >> ':'
            >> +signal_; // std::map<std::string, Signal> (here is my problem)
        start_ %= message_;
    }
    boost::spirit::qi::rule<ITER, Message(), boost::spirit::ascii::space_type> start_;
    boost::spirit::qi::rule<ITER, Message(), boost::spirit::ascii::space_type> message_;
    boost::spirit::qi::rule<ITER, Signal(), boost::spirit::ascii::space_type> signal_;
    boost::spirit::qi::rule<ITER, std::string()> string_;
    boost::spirit::qi::rule<ITER, std::string(), boost::spirit::ascii::space_type> quoted_string_;
};

问题是,我需要使用Signal的名称来创建Signal对象(因为它具有name属性),但我还想映射用规则解析的Signal signal_到消息std::map<std::string, Signal>中的信号名称映射,但是我不知道如何接收信号名称,或者如何为boost::spirit创建所需的信号对,所以可以将其插入地图。 我想我必须以某种方式复制包含信号名称的字符串。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

我用attr_cast解决了这个问题:

namespace boost
{
    namespace spirit
    {
        namespace traits
        {
            template <>
            struct transform_attribute<std::pair<std::string, Signal>, Signal, boost::spirit::qi::domain>
            {
                using type = Signal&;
                using pair_t = std::pair<std::string, Signal>;
                static Signal& pre(pair_t& pair)
                {
                    return pair.second;
                }
                static void post(pair_t& pair, const Signal& sig)
                {
                    pair.first = sig.name;
                    pair.second = sig;
                }
                static void fail(pair_t& pair)
                {
                }
            };
        }
    }
}

然后:

message_ %= lit("BO_")
    >> int_
    >> string_ >> ':'
    >> int_
    >> string_
    >> +attr_cast(signal_);

我希望我使用了所有正确的信息(不保证)。