提升::精神 使用相同的符号两次

boost::spirit use same symbol twice

本文关键字:两次 符号 精神 提升      更新时间:2023-10-16

我有一个类似于那个的语法:

 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属性(,但我也希望将使用规则解析的信号映射到消息std::map<std::string, Signal>映射中的信号名称signal_,但我不知道如何接收信号的名称, 或者如何为boost::spirit创建所需的对,以便它可以将配对插入到映射中。我想我必须以某种方式复制保存信号名称的字符串。

我该怎么做?

我用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_);

我希望我正确使用了所有内容(不保证(。