Boost.Spirit 解析可选前缀

2023-12-07

我正在尝试解析一串以空格分隔、可选标记的关键字。例如

descr:expense type:receivable customer 27.3

其中冒号之前的表达式是标签,并且它是可选的(即假定默认标签)。

我无法让解析器完成我想要的事情。我对一个版本做了一些小的修改典型的例子其目的是解析键/值对(很像 HTTP 查询字符串)。

typedef std::pair<boost::optional<std::string>, std::string> pair_type;
typedef std::vector<pair_type> pairs_type;

template <typename Iterator>
struct field_value_sequence_default_field
  : qi::grammar<Iterator, pairs_type()>
{
    field_value_sequence_default_field()
      : field_value_sequence_default_field::base_type(query)
    {
        query =  pair >> *(qi::lit(' ') >> pair);
        pair  = -(field >> ':') >> value;
        field = +qi::char_("a-zA-Z0-9");
        value = +qi::char_("a-zA-Z0-9+-\\.");
    }

    qi::rule<Iterator, pairs_type()> query;
    qi::rule<Iterator, pair_type()> pair;
    qi::rule<Iterator, std::string()> field, value;
};

然而,当我解析它时,当标签被省略时,optional<string>不是空/假。相反,它有该值的副本。该对的第二部分也具有价值。

如果未标记的关键字不能是标记(语法规则,例如有小数点),那么事情就会像我期望的那样工作。

我究竟做错了什么?这是 PEG 的概念错误吗?


相反,它有该值的副本。该对的第二部分也具有价值。

这是容器属性和回溯的常见陷阱:使用qi::hold, e.g. 理解 Boost.spirit 的字符串解析器

    pair  = -qi::hold[field >> ':'] >> value;

Complete sample Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/optional/optional_io.hpp>
#include <iostream>

namespace qi    = boost::spirit::qi;

typedef std::pair<boost::optional<std::string>, std::string> pair_type;
typedef std::vector<pair_type> pairs_type;

template <typename Iterator>
struct Grammar : qi::grammar<Iterator, pairs_type()>
{
    Grammar() : Grammar::base_type(query) {
        query =  pair % ' ';
        pair  = -qi::hold[field >> ':'] >> value;
        field = +qi::char_("a-zA-Z0-9");
        value = +qi::char_("a-zA-Z0-9+-\\.");
    }
  private:
    qi::rule<Iterator, pairs_type()> query;
    qi::rule<Iterator, pair_type()> pair;
    qi::rule<Iterator, std::string()> field, value;
};

int main()
{
    using It = std::string::const_iterator;

    for (std::string const input : {
            "descr:expense type:receivable customer 27.3",
            "expense type:receivable customer 27.3",
            "descr:expense receivable customer 27.3",
            "expense receivable customer 27.3",
    }) {
        It f = input.begin(), l = input.end();

        std::cout << "==== '" << input << "' =============\n";
        pairs_type data;
        if (qi::parse(f, l, Grammar<It>(), data)) {
            std::cout << "Parsed: \n";
            for (auto& p : data) {
                std::cout << p.first << "\t->'" << p.second << "'\n";
            }
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}

Printing

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

Boost.Spirit 解析可选前缀 的相关文章

  • VLC 媒体播放器有 C# 界面吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否可以使用 C 控制台应用程序中的包装器从 VLC 播放中当前播放的文件中读取曲目统计信息 时间 标
  • 使用链表进行堆排序

    我想知道是否有人曾经使用链表进行堆排序 如果他们可以提供代码 我已经能够使用数组进行堆排序 但尝试在链表中进行排序似乎不切实际 而且在你知道的地方很痛苦 我必须为我正在做的项目实现链接列表 任何帮助将不胜感激 我也用C 答案是 你不想在链表
  • 是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

    我正在使用 DirectShow Net 库创建一个过滤器图 该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频 然后 在网页上 我可以使用对象元素在 Windows Media Player 对象中呈现视频源
  • C#.Net 邮件将进入垃圾邮件文件夹

    我正在从 ASP net Web 应用程序发送电子邮件 邮件发送成功 没有失败 但大多数都进入了垃圾邮件文件夹 请帮助我克服垃圾邮件过滤器 我的发送邮件代码 public void SendMail string FromAddress s
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • Unity3D - 将 UI 对象移动到屏幕中心,同时保持其父子关系

    我有一个 UI 图像 它的父级是 RectTransform 容器 该容器的父级是 UI 面板 而 UI 面板的父级是 Canvas 我希望能够将此 UI 图像移动到屏幕中心 即画布 同时保留父级层次结构 我的目标是将 UI 图像从中心动画
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • winform c# 中的弹出窗口

    我正在开发一个需要弹出窗口的项目 但问题是我还希望能够通过表单设计器在此弹出窗口中添加文本框等 所以基本上我有一个按钮 当您单击它时 它将打开我在表单设计器中设计的另一个窗口 我一直在谷歌搜索 但还没有找到我需要的东西 所以我希望你们能帮助
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其
  • 如何在 ASP.NET Core 中注入泛型的依赖关系

    我有以下存储库类 public class TestRepository Repository

随机推荐

  • 替换字符串中特定索引处的字符?

    我正在尝试替换字符串中特定索引处的字符 我正在做的是 String myName domanokz myName charAt 4 x 这会产生错误 有什么方法可以做到这一点吗 Java 中的字符串是不可变的 你无法改变它们 您需要创建一个
  • Java枚举和迭代器的区别

    这两个接口的具体区别是什么 做Enumeration比使用有好处Iterator 如果有人能详细说明 参考文章将不胜感激 查看 Java API 规范Iterator界面上 有关于之间差异的解释Enumeration 迭代器不同于 枚举有两
  • python asyncio 无法同时运行两个无限函数

    我一直在尝试同时运行两个功能 但一个功能似乎永远无法工作 除非我停止另一个功能 第一个函数每 30 秒发送一封电子邮件 而第二个函数每 5 秒打印一条简单的语句 组合起来 每 6 个 Hello Worlds 输出应发送一封电子邮件 然而
  • 如何在 AChartEngine 中禁用显示缩放窗格

    任何人都可以帮助我了解 AChartEngine 在这里 我需要的第一件事是不要在图表中显示缩放图标 也不显示 x y 标签 但我找不到任何解决方案 您可以使用XYMultipleSeriesRenderer方法 启用或禁用缩放和平移 如下
  • 使用Python的词云库时,为什么停用词没有被排除在词云之外?

    我想排除 The they 和 My 在我的词云中显示 我正在使用 python 库 wordcloud 如下所示 并使用这 3 个附加停用词更新停用词列表 但 wordcloud 仍然包含它们 我需要更改什么才能排除这 3 个单词 我导入
  • Angular 2:将 *ngFor 加 2 或在 Pagination 中实现两个分页

    我对 Angular 还很陌生 我想知道是否有任何方法可以将 ngFor 循环增加 2 而不是 1 我正在尝试在一个分页中实现两个分页 为此需要将循环增加 2 我正在获取包含带有 in 的对象的对象 假设用户及其地址列表 第一个NgFor是
  • 如何在 ASP.NET MVC 模型中保存选定的 DropDownList 值以进行 POST?

    我的模型中有一个属性 如下所示 public IList
  • Shell 脚本中的字符小写到大写

    我的价值在于 詹姆斯 亚当 约翰我正在努力做到詹姆斯 亚当 约翰 每个名称的第一个字符应大写 根据 kev 下 echo 詹姆斯 亚当 约翰 sed s 我无法在不同的系统中执行相同的操作 我正在使用 ksh 但我不知道是否是因为 ksh
  • 如何从我的全局热键粘贴其他应用程序

    我编写了一个小型生产力工具 可以通过剪贴板进行一些字符串操作 它当前正在注册一个热键 在其中提取剪贴板文本 对其进行处理 然后将结果转储回剪贴板上 我已将其安装在 CMD SHIFT V 上 目前 您需要从另一个应用程序执行的操作是复制 C
  • 如何在 VisualForce 页面中实现“保存并新建”功能

    我知道这就是保存记录的方法
  • 识别常见模式[重复]

    这个问题在这里已经有答案了 是否有 简单 可能识别两个字符串共享的公共模式 这是一个小例子来阐明我的意思 我有两个包含字符串的变量 两者都包含相同的模式 ABC 以及一些 噪音 a lt xxxxxxxxxxxABCxxxxxxxxxxxx
  • 逻辑 AND、OR:是否保证从左到右求值? [复制]

    这个问题在这里已经有答案了 是从左到右计算逻辑运算符 有保证吗 假设我有这个 SDL Event event if SDL PollEvent event if event type SDL QUIT do stuff 这保证和这个一样吗
  • 在map()中,什么时候需要使用波形符和句点。 (〜和。)

    我正在查看以下示例map 来自 R 数据科学 一个例子是 library dplyr library purrr df lt tibble a rnorm 10 b rnorm 10 c rnorm 10 d rnorm 10 df gt
  • JavaScript - 如何检测选择元素(下拉列表)上的编程值更改

    在 JavaScript 中 我需要检测某个 select 元素的值何时发生变化any原因 包括以编程方式 仅当用户手动更改所选值时才会触发 onchange 事件 not当其他 JavaScript 以编程方式更改该值时 这是一个包含各种
  • CSS 背景图像未加载

    我最近在 Chrome 中遇到了一个非常奇怪的错误 那就是当您第一次加载页面时 或者在隐身模式下 没有任何背景图像显示 当您 F5 页面时 背景图像全部加载 当您检查 css 时 它会在 css 面板中显示图像 url 但是当您将鼠标悬停在
  • Firebase google auth 未完全注销

    使用Google提供的非常清晰的简单示例 Firebase Google Auth 我一直无法从google注销 每次我使用按钮调用此方法时 它都允许我登录并将我导航到本地主机 function logGoogle firebase aut
  • 正则表达式匹配 MySQL 注释

    我需要找到并删除 MySQL 查询中的所有注释 我遇到的问题是避免引号或反引号内的注释标记 在 PHP 中 我使用以下代码取消注释 SQL sqlComments 2 R s lt s ms Commented version sqlCom
  • HTML“按钮”是否应该与其他所有内容具有相同的盒子模型?

    参考两者button元素和input元素与一个type of button 我遇到了一个我认为是错误的行为 在 Firefox 和 Chrome 的最新版本中 但考虑到表单元素通常是我认为的 w3 规则的例外 我想在假设我是对的之前我会要求
  • Jquery Spinner 箭头未加载(可见性)

    微调器上的向上和向下箭头没有显示 我不确定为什么 除了这些箭头之外 所有其他 UI 图像似乎都在加载 这是一个网站 网站链接 这些图像不显示的原因是因为在您指定的路径中找不到它们 您可能忘记上传它们 或者您将它们上传到了错误的目录
  • Boost.Spirit 解析可选前缀

    我正在尝试解析一串以空格分隔 可选标记的关键字 例如 descr expense type receivable customer 27 3 其中冒号之前的表达式是标签 并且它是可选的 即假定默认标签 我无法让解析器完成我想要的事情 我对一