如何设置最大递归在促进精神
How to set max recursion in boost spirit
使用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<>
和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
#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 << "Failn";
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f, std::min(f + 40, l)) << "'...n";
}
}
输出: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: '(((((((((((((((((((((((((((((((((((((((('...
相关文章:
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 如何在C++中递归地按相反顺序打印集合
- 到连接组件算法的问题(递归)
- 给定一个大小的布尔数组,这都是真实的,我将如何仅使用递归将所有值设置为false
- 如何设置最大递归在促进精神
- 基例如何影响使用递归函数的哪些行
- c++设置迭代器后的下一个分隔符递归