是否可以将一个操作附加到 boost::spirit::rule 解析器,该解析器将解析结果分配给(尚)未知实例的成员?

2024-03-21

我试图从 boost::spirit 规则定义的操作中引用(尚)未知实例的成员,因此在伪代码中,

代替 双_[参考(rN) = _1] 我正在寻找类似的东西 X** 像素; double_[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' 无法转换为 ...


有几种方法可以给这只猫剥皮:

  1. 您可能考虑推迟执行绑定表达: phx::bind可以做到这一点
  2. 或者,你可以使用属性传播为此(并且不做语义动作共)
  3. 最后,你可以使用继承属性(例如,当 DataContext 没有默认构造函数或者复制成本很高)

1. 推迟与凤凰的束缚

使用phoenix bind达到目的:这将产生一个Phoenix actor,它将在执行时“延迟执行”语义动作被触发。

以下是您可能需要的缺失代码示例的重建:

#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";
}

Note:

  • 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));

并且不要求上下文是默认可构造的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以将一个操作附加到 boost::spirit::rule 解析器,该解析器将解析结果分配给(尚)未知实例的成员? 的相关文章

随机推荐

  • React-native 在浏览器中打开链接并返回到应用程序

    我正在开发一个反应原生应用程序 它应该与支付网关进行通信 在完成支付过程 成功或失败 后 我需要向用户显示警报 为此 我打开了一个链接WebView之后我得到了 return 的 urlonNavigationStateChange并显示成
  • 一个程序如何控制另一个程序?

    机器人 它们是如何工作的 他们是否告诉视频游戏按下了某个键或点击了鼠标 如果没有 有没有办法让你的程序告诉另一个程序按下了一个键 我想制作一个程序来击败一些游戏 因此 任何资源或示例都值得赞赏 Update 因此一种方法是模拟击键 那么有哪
  • Javascript 中的“柯里化”和“组合”是同一概念吗?

    最近我在一本 Javascript 书中读到了有关函数组合的内容 然后在一个网站上我看到有人将其称为柯里化 它们是同一个概念吗 Omarjmh 的答案很好 但在我看来 撰写示例对于学习者来说极其复杂 它们是同一个概念吗 No 首先 柯里化是
  • 如何在Python中建立和求解联立方程

    对于固定整数n 我有一组2 n 1 联立方程如下 M p 1 n p 1 n M n 1 2 n N p 1 p 1 n M p 1 N p 1 n p 1 n M n 1 p n N p 1 M 1 1 n 2 n M n 1 2 n N
  • 如何编写一个正则表达式来匹配任意顺序的字符?

    我正在尝试编写一个正则表达式来匹配一组字符 而不考虑顺序 例如 str act str scan Insert expression here 将匹配 cat act tca atc tac cta 但不匹配ca ac or cata 我在
  • 从 IPHostEntry 获取有效 IP

    我尝试使用此方法获取我的计算机的 IP 地址 var ipadd Dns GetHostEntry Dns GetHostName foreach var ipAddress in ipadd AddressList Console Wri
  • javascript 中剩余参数和展开运算符的用法

    ECMAScript 6中添加的rest参数有什么用 例如 在 ECMAScript 5 中 您可以执行以下操作来获取从第二个元素开始的参数数组 ES 5 store Joe money store Jane letters certifi
  • 根据 UICollectionView 中的图像动态更改单元格大小

    我正在水平集合视图中显示从服务器接收的动态图像 当我设置集合视图时 我设置了 void setupCollectionView self setupPageControlView self screensCollectionView del
  • 提高识别率的图像预处理步骤

    我正在为我的项目使用 TessBaseAPI 制作一个简单的 OCR Android 应用程序 我已经完成了一些图像预处理步骤 例如二值化和图像增强 但他们的结果是50 到60 怎样才能提高识别率呢 我包括两个示例图像 http image
  • 关于Environment.ProcessorCount的问题

    我很好奇 NET 属性是什么Environment ProcessorCount实际上返回 它返回核心数量 处理器数量还是两者都返回 如果我的计算机有 2 个处理器 每个处理器有 4 个核心 Environment ProcessorCou
  • 如何计算 React Native/JS 中 JSON 响应的长度?

    我想计算我的响应 JSON 的长度 这是我的代码 getMoviesFromApiAsync return fetch http sampleurl com CommonDataManager getInstance getUserID t
  • Android:当应用程序被终止时从服务启动活动

    在我的应用程序中 我有一个Service在后台 和前台 运行 In this Service 有一个CountdownTimer当它完成时 我想在某个特定的时间启动该应用程序Activity并在中做一些事情Activity自动 并且即使我的
  • 如何在 VS Code 中跨多个文件执行命令?

    我想通过运行一些命令来优化我的打字稿代码 例如resolve organizeImports我的所有打字稿 ts 文件中都带有 TS Hero 插件 逐个文件地执行此操作可能非常烦人且耗时 有没有一种简单的方法来进行这种 批量 执行 我已经
  • Moment.js 月份差异

    我已经使用 moment js 有一段时间了 它使日期操作变得更加容易 但我有一个失败的特定案例 我不明白为什么 计算今天 2013 年 10 月 31 日 和 2014 年 2 月 1 日之间的差异时 月份差异返回为 2 尽管两个日期之间
  • JQuery:获取不包括嵌套标签的标签内容

    我有一些如下所示的 HTML span Text I m interested in span Other crap I don t care about span span 我希望获取跨度 A 的文本内容 不包括任何嵌套标签 即上例中跨度
  • Nestjs Mongoose 服务的单元测试

    我一直在试图弄清楚如何对 NestJS 服务进行单元测试 所以我写了一个规范文件来测试这些使用 mongoose 和 jest 的 NestJS 服务 规格文件如下 import Test TestingModule from nestjs
  • 如何获取MEF中的所有方法

    我有属性类 AttributeUsage AttributeTargets Method public class MethodGetterAttribute ExportAttribute 我在几个命名空间的方法中使用它 namespac
  • 使用reduce删除数组中的重复项

    我正在尝试从数组列表中删除重复项 我尝试执行此操作的方法是使用reduce 创建一个空数组 将所有未定义的索引推送到该数组上 但我收到错误 if acc item undefined TypeError Cannot read proper
  • 如何查看CK编辑器版本

    我的项目中有一个现有的 CK 编辑器文件夹 我怎样才能知道它的版本 有记录吗 只需在 config js 文件中发出如下警报 它就会给出值 alert CKEDITOR version 或者您可以直接在文件 ckeditor php4 ph
  • 是否可以将一个操作附加到 boost::spirit::rule 解析器,该解析器将解析结果分配给(尚)未知实例的成员?

    我试图从 boost spirit 规则定义的操作中引用 尚 未知实例的成员 因此在伪代码中 代替 双 参考 rN 1 我正在寻找类似的东西 X 像素 double ref X rN ppx 1 它的解决方法可能是一个简单的 语义操作 其参