如何在Boost Spirit中设置最大递归

2023-12-25

使用 boost::spirit,如果我有递归规则来解析括号

rule<std::string::iterator, std::string()> term;
term %= string("(") >> *term >> string(")");

如何限制最大递归次数?例如,如果我尝试解析一百万个嵌套括号,则会出现段错误,因为超出了堆栈大小。具体来说,这是一个完整的示例。

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>

int main(void)
{
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    const size_t string_size = 1000000;
    std::string str;
    str.resize(string_size);
    for (size_t s=0; s<str.size()/2; ++s)
      {
        str[s]='(';
        str[str.size() - s -1] = ')';
      }

    rule<std::string::iterator, std::string()> term;
    term %= string("(") >> *term >> string(")");
    std::string h;
    parse(str.begin(), str.end(), term, h);
}

我用命令编译了

g++ simple.cxx -o simple -std=c++11

如果我设置的话效果很好string_size到 1000 而不是 1000000。


跟踪深度qi::local<> or a phx::ref().

在这种情况下,继承属性可以充当qi::local很自然地:

qi::rule<std::string::const_iterator, std::string(size_t depth)> term;
qi::_r1_type _depth;
term %= 
    qi::eps(_depth < 32) >>
    qi::string("(") >> *term(_depth + 1) >> qi::string(")");

term现在当深度超过 32 时将会失败。

完整样本

Live On Coliru http://coliru.stacked-crooked.com/a/cc711f7555962f42

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;

int main(void) {
    for (size_t n : { 2, 4, 8, 16, 32, 64 }) {
        auto const str = [&n] {
            std::string str;
            str.reserve(n);
            while (n--) { str.insert(str.begin(), '('); str.append(1, ')'); }
            return str;
        }();
        std::cout << "Input length " << str.length() << "\n";

        qi::rule<std::string::const_iterator, std::string(size_t depth)> term;
        qi::_r1_type _depth;
        term %= 
            qi::eps(_depth < 32) >>
            qi::string("(") >> *term(_depth + 1) >> qi::string(")");

        std::string h;

        auto f = str.begin(), l = str.end();
        bool ok = qi::parse(f, l, term(0u), h);
        if (ok)
            std::cout << "Ok: " << h << "\n";
        else
            std::cout << "Fail\n";

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

Output:

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

如何在Boost Spirit中设置最大递归 的相关文章

  • Qt 和 Sqlite 示例

    我正在寻找一些使用 Qt 的示例代码 它是带有 Sqlite 驱动程序的 SQL 模块 我需要示例的主要原因是我之前有 Qt 数据库接口的经验 并且 Sqlite 在字段类型方面有一些奇怪的行为 类型是按字段存储的 而不是按列存储的 The
  • 从服务器下载图像(cUrl,但接受建议)C++

    我试图通过从服务器 网站 下载图像来设置旋转背景图像 并尝试使用curl 来执行此操作 但是在执行此操作方面取得了0 成功 我的代码的 缩短的 版本如下 我没有收到错误 但是 如何 临时 保存该图像以将其显示为背景 是否有图像 类型变量 或
  • std::map find 在 C++ 中不起作用[重复]

    这个问题在这里已经有答案了 我使用以下几行创建了一个哈希映射和一个迭代器 std map
  • 地图类容器的专用功能

    我想要专门为矢量和地图之类的容器设计一个函数模板 对于向量 我可以像下面那样做 但我不知道如何才能有一个专门版本的函数 该函数仅用于像地图这样的容器 include
  • 字符串/分段错误

    Program to calculate trip and plan flights define TRIP 6 define NAMEMAX 40 define DEST 1 include
  • 如何在 ASP.NET MVC 中处理会话数据

    假设我想存储一个名为language id在会议中 我想我也许可以做如下的事情 public class CountryController Controller WebMethod EnableSession true AcceptVer
  • 二叉树和快速排序?

    我有一个家庭作业 内容如下 别生气 担心 我是not请你帮我做作业 编写一个程序 通过使用二分查找的快速排序方法对一组数字进行排序 树 推荐的实现是使用递归算法 这是什么意思 到目前为止 这是我的解释 正如我在下面解释的那样 我认为两者都有
  • 如何反序列化 XML 文档

    如何反序列化此 XML 文档
  • .Net 支持柯里化泛型吗?

    假设我们有一个嵌套的泛型类 public class A
  • 在 C++ 中,为什么 const 也可以工作时编译器选择非常量函数? [复制]

    这个问题在这里已经有答案了 例如 假设我有一堂课 class Foo public std string Name m maybe modified true return m name const std string Name cons
  • 如何在 C++11 中返回类成员向量

    我读了几篇关于如何从方法返回向量的文章 其中包括 c11 右值和移动语义混淆返回语句 https stackoverflow com questions 4986673 c11 rvalues and move semantics conf
  • 将 JavaScript 引擎嵌入到 .NET 中 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 只是想知道是否有人尝试过将任何 js 引擎嵌入并实际集成到 net 环境中 我可以找到并实际使用 经过L
  • C 编程中的 rand() 问题? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么我总是用 rand 得到相同的随机数序列 https stackoverflow com questions 1108780 why do i always get the same seque
  • Qt 多重继承和信号

    由于 QObject 我在 QT 中遇到了有关多重继承的问题 我知道很多人也有同样的问题 但我不知道该如何解决 class NavigatableItem public QObject Q OBJECT signals void desel
  • 批量插入,asp.net

    我需要获取与会员相对应的 ID 号列表 在任何给定时间处理的数量可能在 10 到 10 000 之间 我可以毫无问题地收集数据 解析数据并将其加载到 DataTable 或任何内容 C 中 但我想在数据库中执行一些操作 将所有这些数据插入表
  • 括号内声明的对象的范围

    如果我声明一个这样的对象 void main myclass objectA anotherclass true true 0 即 我通过直接调用后者的构造函数来创建一个 objectA 和另一个对象 anotherclass anothe
  • 使用 StartServiceCtrlDispatcher 与 StartService 从 C 语言启动 Windows 服务有什么区别?

    我尝试使用 StartServiceCtrlDispatcher 中所述https msdn microsoft com en us library windows desktop bb540475 v vs 85 aspx https m
  • TCP/IP 传输期间套接字数据损坏

    当我通过预连接的 TCP IP 套接字发送数据时 我发现数据已损坏 Example Station1 正在向 Station2 发送数据 我已经在发送之前 在 S1 和接收之后 在 S2 打印了数据 以下是消息 S1 发送的数据是ACKS2
  • asio::this_coro::executor 的实现是什么

    在协程函数中 我们可以添加auto ex co await asio this coro executor 获取该协程的执行者 但当我想了解它的定义时 我发现了这个 Awaitable type that returns the execu
  • C 中的等效 plpgsql 触发器

    我有一个 PostgreSQL 9 0 服务器 并且在某些表上使用继承 因此我必须通过如下触发器模拟外键 CREATE OR REPLACE FUNCTION othertable before update trigger RETURNS

随机推荐