Boost::精神非法_回溯异常
Boost::spirit illegal_backtracking exception
我在一个简单的计算器项目中使用Boost.SSpirit.Lex和.Qi,(像往常一样)它给我调试和使用带来了一些困难。调试打印:
<expression>
<try>boost::spirit::multi_pass::illegal_backtracking
这个异常被抛出了,我不明白为什么。我在代码中使用宏,如果给出一个最小的例子,那将是一种痛苦,所以我给出了整个项目。只需在根执行"make",然后启动/如果您想测试,只需执行"-echoo$5-8"即可。
谷歌似乎没有发现任何类似的问题关于这个例外。。。
解析器在算术/中,解析器的调用在算术/评估器.cpp 的末尾
非常感谢任何帮助。
您的代码正在崩溃,因为BOOstrongPIRIT_QI_DEBUG和on_error<>
处理程序似乎在迭代器可能无效后使用迭代器。
老实说,我不完全确定这是怎么发生的。
背景
AFAICT lexertl使用具有split_functor
输入策略和split_std_deque
存储策略的spirit::multipass<>
[1]。
现在,(幸运的是?)检查策略是buf_id_check
,这意味着迭代器将在取消引用时检查是否无效。
如果
- 迭代器被解除围栏,将缓冲区增加到>16个标记和迭代器是唯一引用共享状态的迭代器
- 或者沿着线
clear_queue
的某个地方被显式调用(例如,来自Spirit Repository中的flush_multi_path
原语)
老实说,我认为这两个条件都没有得到满足。快速而肮脏的
token_iterator_type clone = iter; // just to make it non-unique...
在evaluator.cpp
中没有区别(排除原因#1)
暂时禁用buf_id_check_policy
中的docheck
实现使valgrind指出on_error<>
和BOOstrongPIRIT_DEBUG*导致无效内存引用。评论和确实可以消除所有问题(eval_expression
现在可以工作了)。
然而,这可能不是您的首选解决方案。
建议的解决方案
自
- 您正在处理一个固定的内存容器,该容器表示您并不真正需要
multi_pass
行为模拟的输入 - 如果您使用的是一种琐碎的语法,那么您并没有真正从lexertl中受益,同时您会增加很多复杂性(正如您所看到的)
我很快重构了一些代码:https://github.com/sehe/sash-refactor/commits/master
提交dec31496
sanity - lets do without macros
4个文件已更改,59个插入(+),146个删除(-)提交6056574c
dead code, excess scope, excess instantiation
5个文件已更改,38个插入(+),62个删除(-)提交99d441db
remove lexer
9个文件已更改,25个插入(+),177个删除(-)
现在,您会发现您的代码通常要简单得多,也要短得多,不会遇到多路径限制,并且您仍然可以使用SPIRIT_DEBUG和on_error
处理:)最终
- -g3中的二进制大小从16Mb减少到6.5Mb
- a已删除263行代码
- 更重要的是,它有效
以下是一些示例(没有调试输出):
$ ./sash <<< '-echo $8-9'
-1
Warning: Empty environment variable "8-9".
$ ./sash <<< '-echo $8*9'
72
Warning: Empty environment variable "8*9".
$ ./sash <<< '-echo $8*(9-1)'
64
Warning: Empty environment variable "8*(9-1)".
$ ./sash <<< '-echo $--+-+8*(9-1)'
-64
Warning: Empty environment variable "--+-+8*(9-1)".
[1]不管它的名称如何,它都缓冲std::vector<>
中以前看到的令牌
- 当回溯以零开始时,如何调试崩溃
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 回溯C++不打印函数,因此文件
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 重新引发异常保留回溯
- C/C++ 未生成 Python 异常回溯
- 在 C++/STL/MFC 应用程序启动早期发生的致命异常中,是否可以信任堆栈回溯符号名称?
- Boost::精神非法_回溯异常
- 如何同时获取 what() 和回溯跟踪未捕获的异常
- Mac OSX上未捕获异常时的回溯
- 如何从谷歌测试中的异常中获取回溯信息