是否有可能将一个动作附加到boost::spirit::规则解析器,该解析器将解析结果分配给(尚未)未知实例的成员
Is it possible to attach an action to a boost::spirit::rule parser which assigns the parsed result to a member of a (yet) unknown instance?
我试图从boost::spirit规则定义的动作中引用一个(尚未)未知实例的成员,所以在伪代码中,
代替double_[ref(rN) = _1]我在找类似的X * * ppx;[ref(&X::rN, ppx) = _1]
一个解决方法可以是一个简单的"语义操作",带有一个参数,该参数知道实例并能够写入它,如
qi::rule<Iterator, Skipper> start;
my_grammar(DataContext*& dataContext) : my_grammar::base_type(start) , execContext(execContext) {
start = qi::double_[ boost::bind(&my_grammar::newValueForXY, dataContext, ::_1) ];
然而,我想知道是否有可能直接"绑定"到成员变量,就像可以通过使用"phoenix::ref(…)= value"绑定到"局部"变量一样。
我尝试了以下语法:
start = qi::int_[ boost::bind<int&>(&DataContext::newValueForXY, boost::ref(dataContext))() = ::_1] ];
,但在VS2010SP1上失败,错误信息
错误C2440: '=': 'boost::arg'无法转换为…
有几种方法可以为这只猫添加皮肤:
- 你可能想过延迟绑定表达式的执行:
phx::bind
可以这样做 或者,您可以使用属性传播(并且完全不使用语义操作)最后,您可以使用继承属性(例如,当DataContext没有默认构造函数或复制成本很高时)
1。使用Phoenix延迟绑定
使用phoenix绑定的目的:这将导致一个phoenix参与者,它将在触发语义动作时被"延迟执行"。
下面是您可能需要的缺失代码示例的重建:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx= boost::phoenix;
struct DataContext
{
double xy;
};
template <typename Iterator, typename Skipper>
struct my_grammar : qi::grammar<Iterator, Skipper>
{
my_grammar(DataContext& dataContext) : my_grammar::base_type(start)
{
start = qi::double_
[ phx::bind(&my_grammar::newValueForXY,
phx::ref(dataContext),
qi::_1) ];
}
private:
static void newValueForXY(DataContext& dc, double value)
{
dc.xy = value;
}
qi::rule<Iterator, Skipper> start;
};
int main()
{
const std::string s = "3.14";
DataContext ctx;
my_grammar<decltype(begin(s)), qi::space_type> p(ctx);
auto f(begin(s)), l(end(s));
if (qi::phrase_parse(f, l, p, qi::space))
std::cout << "Success: " << ctx.xy << "n";
}
注意:
- phx::ref()将引用包装到数据上下文
- qi::_1代替boost::_1作为占位符
给出
newValueForXY
的这个实现,你可以很容易地写start = qi::double_ [ phx::bind(&DataContext::xy, phx::ref(dataContext)) = qi::_1 ];
2。使用属性语法,而不是语义操作
但是,我可能会使用属性而不是语义操作来编写相同的示例(因为这基本上是用于的):#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx= boost::phoenix;
struct DataContext {
double xy;
};
BOOST_FUSION_ADAPT_STRUCT(DataContext, (double, xy))
template <typename Iterator, typename Skipper>
struct my_grammar : qi::grammar<Iterator, DataContext(), Skipper>
{
my_grammar() : my_grammar::base_type(start) {
start = qi::double_;
}
private:
qi::rule<Iterator, DataContext(), Skipper> start;
};
int main()
{
const std::string s = "3.14";
static const my_grammar<decltype(begin(s)), qi::space_type> p;
DataContext ctx;
if (qi::phrase_parse(begin(s), end(s), p, qi::space, ctx))
std::cout << "Success: " << ctx.xy << "n";
}
3。使用继承属性在上下文中传递引用
如果你绝对坚持,你甚至可以使用 inherited attributes
来达到目的:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx= boost::phoenix;
struct DataContext {
double xy;
};
template <typename Iterator, typename Skipper>
struct my_grammar : qi::grammar<Iterator, void(DataContext&), Skipper> {
my_grammar() : my_grammar::base_type(start)
{
start = qi::double_ [ phx::bind(&DataContext::xy, qi::_r1) = qi::_1 ];
}
qi::rule<Iterator, void(DataContext&), Skipper> start;
};
int main() {
const std::string s = "3.14";
const static my_grammar<std::string::const_iterator, qi::space_type> p;
DataContext ctx;
if(qi::phrase_parse(begin(s), end(s), p(phx::ref(ctx)), qi::space)) {
std::cout << "Success: " << ctx.xy << "n";
}
}
这在调用站点更有表现力:
qi::phrase_parse(begin(s), end(s), p(phx::ref(ctx)), qi::space));
相关文章:
- 如何通过查找迭代器结果分配给一组对的元素
- 分配给浮点数的积分文字除法 - 为什么结果是错误的?
- 分段错误分配函数结果
- 使用动态分配的数组进行矩阵乘法;结果不正确
- 具有预分配结果C++的重载加运算符
- 贪婪地分配分数以最大化最终结果
- Valarray 就地操作作为临时分配给出不同的结果
- 为什么在C 中不确定,为签名类型的对象分配范围的值的结果
- 左col结果分配给相同的矩阵会导致分割故障
- 是否可以为 #define 分配定义的结果?
- 将稀疏 mat-vec-mult 的结果存储到预分配的向量中
- 如何在 c++ 中将 std:fixed << setprecision(5) 的结果分配给变量
- 只有当声明一个对象时,内存空间才会分配给类的数据成员,那么为什么 Sizeof(class_name) 给我结果
- 为什么无法将 std::bind 的结果分配给函数指针
- 将函数结果分配给变量的问题
- 返回新对象的函数与将函数的结果分配给调用它的对象的 C++ 区别
- 将更改此静态变量内部的函数的结果分配给静态变量
- 对结构进行操作并将结果分配给同一结构是否是一种不好的做法?为什么
- 是否有可能将一个动作附加到boost::spirit::规则解析器,该解析器将解析结果分配给(尚未)未知实例的成员
- C++:将按位 AND 的结果分配给布尔值