c++ - 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_
到消息std::map<std::string, 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_);
我希望我使用的一切都是正确的(不保证)。
推荐阅读
- azure - 使用 validate-jwt 验证 jwt 令牌时如何检查错误(上一篇:如何在 validate-jwt 中使用自定义构建的 jwt?)
- python - 从数据集中删除 NaN 并设置转换类型
- azure - Azure SDK C# - 计划虚拟机自动关闭
- android - Nativescript-vue 将光标设置在 TextInput RTL 的末尾
- javascript - 如何选择数组中的唯一元素?
- c++ - 在 OpenGL 上单击鼠标时无法旋转和更改对象的颜色
- rest - 通过 REST/SOAP 更改 LDAP 密码
- python - 如何在需要命令行参数的脚本上使用 pdoc?
- sql - 从 time_delta 列 python 中获取总秒数
- laravel - 在 laravel 刀片视图中显示刀片代码片段