使用 Boost.Spirit.Lex 和流迭代器

2023-12-22

我想使用 Boost.Spirit.Lex 来 lex 二进制文件;为此,我编写了以下程序(这是摘录):

#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <fstream>
#include <iterator>
#include <string>

namespace spirit = boost::spirit;
namespace lex = spirit::lex;

#define X 1
#define Y 2
#define Z 3

template<typename L>
class word_count_tokens : public lex::lexer<L>
{
    public:
        word_count_tokens () {
            this->self.add
                ("[^ \t\n]+", X)
                ("\n", Y)
                (".", Z);
        }
};

class counter
{
    public:
        typedef bool result_type;

        template<typename T>
        bool operator () (const T &t, size_t &c, size_t &w, size_t &l) const {
            switch (t.id ()) {
               case X:
                   ++w; c += t.value ().size ();
                    break;
               case Y:
                   ++l; ++c;
                    break;
                case Z:
                    ++c;
                    break;
            }

            return true;
        }
};

int main (int argc, char **argv)
{
    std::ifstream ifs (argv[1], std::ios::in | std::ios::binary);
    auto first = spirit::make_default_multi_pass (std::istream_iterator<char> (ifs));
    auto last = spirit::make_default_multi_pass (std::istream_iterator<char> ());
    size_t w, c, l;
    word_count_tokens<lex::lexertl::lexer<>> word_count_functor;

    w = c = l = 0;

    bool r = lex::tokenize (first, last, word_count_functor, boost::bind (counter (), _1, boost::ref (c), boost::ref (w), boost::ref (l)));

    ifs.close ();

    if (r) {
        std::cout << l << ", " << w << ", " << c << std::endl;
    }

    return 0;
}

构建返回以下错误:

lexer.hpp:390:46: error: non-const lvalue reference to type 'const char *' cannot bind to a value of unrelated type

现在,错误是由于定义造成的concrete lexer, lex::lexer<>;事实上它的第一个参数默认为const char *。如果我使用,我也会得到同样的错误spirit::istream_iterator or spirit::make_default_multi_pass (.....).
但是如果我指定正确的模板参数lex::lexer<>我收到很多错误!

解决方案?

Update

我已经把所有源文件都放了;这是 word_counter 网站的示例。


好的,既然问题改变了,这里有一个新的答案,用完整的代码示例解决了一些问题。

  1. 首先,您需要使用自定义令牌类型。 IE。

    word_count_tokens<lex::lexertl::lexer<lex::lexertl::token<boost::spirit::istream_iterator>>> word_count_functor;
    // instead of:
    // word_count_tokens<lex::lexertl::lexer<>> word_count_functor;
    

    显然,习惯上是 typedeflex::lexertl::token<boost::spirit::istream_iterator>

  2. 你需要使用min_token_id而不是令牌 ID 1、2、3。另外,将其设为枚举以便于维护:

    enum token_ids {
        X = lex::min_token_id + 1,
        Y,
        Z,
    };
    
  3. 你不能再仅仅使用.size()在默认令牌上value()因为迭代器范围不再是 RandomAccessRange。相反,雇用boost::distance()这是专门用于iterator_range:

            ++w; c += boost::distance(t.value()); // t.value ().size ();
    

结合这些修复:住在科里鲁 http://coliru.stacked-crooked.com/a/e2228051e17f6fbc

#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/bind.hpp>
#include <fstream>

namespace spirit = boost::spirit;
namespace lex    = spirit::lex;

enum token_ids {
    X = lex::min_token_id + 1,
    Y,
    Z,
};

template<typename L>
class word_count_tokens : public lex::lexer<L>
{
    public:
        word_count_tokens () {
            this->self.add
                ("[^ \t\n]+", X)
                ("\n"       , Y)
                ("."        , Z);
        }
};

struct counter
{
    typedef bool result_type;

    template<typename T>
    bool operator () (const T &t, size_t &c, size_t &w, size_t &l) const {
        switch (t.id ()) {
            case X:
                ++w; c += boost::distance(t.value()); // t.value ().size ();
                break;
            case Y:
                ++l; ++c;
                break;
            case Z:
                ++c;
                break;
        }

        return true;
    }
};

int main (int argc, char **argv)
{
    std::ifstream ifs (argv[1], std::ios::in | std::ios::binary);
    ifs >> std::noskipws;
    boost::spirit::istream_iterator first(ifs), last;
    word_count_tokens<lex::lexertl::lexer<lex::lexertl::token<boost::spirit::istream_iterator>>> word_count_functor;

    size_t w = 0, c = 0, l = 0;
    bool r = lex::tokenize (first, last, word_count_functor, 
            boost::bind (counter (), _1, boost::ref (c), boost::ref (w), boost::ref (l)));

    ifs.close ();

    if (r) {
        std::cout << l << ", " << w << ", " << c << std::endl;
    }
}

当自身运行时,打印

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

使用 Boost.Spirit.Lex 和流迭代器 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub

随机推荐

  • Swift“文本”不可用:自 iOS7 起已弃用 API。文本标签不起作用

    我一直有这个错误 我已经看到使用 textLabel text 回答了其他问题 但它在我的情况下不起作用 我是 swift 的新手 所以有人可以解释一下为什么以及如何解决这个问题 你需要打开包装textLabel通过使用 after tex
  • 将可变 Arc 引用传递给 hyper service_fn 处理程序时出现问题

    我一直在尝试以下 显示相关导入和代码 use std sync Arc Mutex use std thread use hyper rt self Future Stream use hyper service service fn us
  • 设置图例符号不透明度

    我正在绘制带有半透明 x 标记 20 alpha 的绘图 如何使图例中的标记以 100 不透明度显示 import matplotlib pyplot as plt plt plot date x xaxis y yaxis marker
  • C# 代码片段和汇编 TBB 有什么区别?

    据我了解 C 代码片段和 NET 程序集为模块化模板开发提供相同的功能 我们在 CME 中管理代码片段 在 Visual Studio 中管理汇编代码 但在模板生成器中使用相同的方式 在代码方面 我可以创建一个C 代码片段模板构建块 TBB
  • 更改 XSL 转换中的命名空间值?

    我不确定这是否可能 因为我对 XSLT 之类的东西非常陌生 但也许你们中的一些人可以在这里帮助我 这有点棘手 我在互联网上没有找到类似的东西 问题是我有一个输入 xml 其中声明了名称空间和所有内容 我只需要对其进行轻微更改 添加或删除属性
  • Django 静态文件应用程序帮助

    我对 Django 有一个小问题静态文件应用程序 https docs djangoproject com en dev ref contrib staticfiles 我已经添加了 django contrib staticfiles 到
  • React.js - Flux 与全局事件总线

    与全局事件总线相比 使用 Flux 有何优势 我认为调度程序就是所需要的 组件将带有数据的 用户事件 发布到调度程序 调度程序执行订阅商店的处理程序 处理程序发布 更新事件 以及商店的更新属性 调度程序执行订阅组件的处理程序 并使用存储的更
  • 在 python 中将 RAW 图像转换为 TIFF 但保留元数据

    我尝试将原始图像转换为 tiff 但我希望它保留元数据 这是我之前使用的代码 import rawpy imageio os with rawpy imread path as raw rgb raw postprocess imageio
  • Python 浮点格式

    我已经看到了一些与此相关的问题 但我读到的这些问题都没有帮助我真正理解为什么我想做的事情失败了 所以我有一堆浮点值 它们有不同的精度 有些是 0 1 其他是 1 759374 等 我想格式化它们 以便它们全部采用我尝试做的 0 000000
  • ilasm / ildasm 的 Java 字节码等效项

    对于 CIL MSIL 我可以在文本编辑器中编写代码并使用 ilasm ildasm 进行编译 反编译 我可以使用 Reflector 来查看 NET 类生成的 CIL 在Java世界中 javap c显示反汇编的字节代码 如何编译 Jav
  • 保存和删除 NSManagedObject 和 NSManagedObjectContext

    三个问题 但它们都是相关的 如果您愿意 我可以将它们分为三个问题 以便您获得更多学分 如果您愿意我这样做 请告诉我 我有以下代码允许我访问 NSManagedObject self managedObjectContext STAppDel
  • 使用 ipdb 默认进入粘性模式

    调试时使用ipdb 我发现输入很有用sticky模式遵循代码源 有没有办法在粘滞模式下自动输入而无需输入sticky 是的 从REAMDE https github com mverteuil pdbpp configuration and
  • 在 XAML 中为一个事件添加多个事件处理程序?

    在程序代码中可以执行以下操作 Add two event handler for the button click event button1 Click new RoutedEventHandler button1 Click 1 but
  • pow 函数中发生了什么?

    我在这里看到了各种描述奇怪行为的答案powC 中的函数 但我在这里有一些不同的问题要问 在下面的代码中我已经初始化了int x pow 10 2 and int y pow 10 n int n 2 在第一种情况下 当我打印它显示的结果时1
  • 如何在React Native中使用axios将图像上传到服务器?

    我想以本机方式将图像作为文件发送到服务器 我怎样才能做到这一点 这是我的代码 export const editUserProfile sessionId firstName lastName image countryCode phone
  • 如何在javascript中访问对象原型?

    所有文章都写到 JavaScript 是一种基于原型的语言 这意味着每个对象都有一个原型 或者更准确地说 原型链 到目前为止 我已经尝试过以下代码片段 var F function F prototype member1 1 var obj
  • EntityFrameworkCore 不存在于 Microsoft 命名空间中

    我试图在这里逐步完成本教程 https learn microsoft com en us aspnet core data ef mvc intro https learn microsoft com en us aspnet core
  • chrome_omniboxView 类不再可用?

    FindWindowEx Hwnd 0 Chrome OmniboxView Nothing Chrome OmniboxView 不再可用 我怎样才能获得谷歌浏览器的当前网址 我刚刚编写了一个 Chrome 扩展程序来解决这个问题 我已将
  • pandas 输出时间戳 to_excel 以微秒为单位

    我的 df 中有微秒分辨率 这非常重要 但无论我尝试什么 我都无法让 Excel 用 xls 或 xlsx 显示微秒分辨率 关于如何在不显式转换为字符串的情况下显示它们的任何想法 使用 GitHub 上最新版本的 Pandas 以及即将发布
  • 使用 Boost.Spirit.Lex 和流迭代器

    我想使用 Boost Spirit Lex 来 lex 二进制文件 为此 我编写了以下程序 这是摘录 include