我使用Boost.Spirit.Lex和.Qi作为一个简单的计算器项目,并且(像往常一样)它给我一些调试和使用的痛苦。调试打印:
<expression>
<try>boost::spirit::multi_pass::illegal_backtracking
抛出此异常,我无法理解原因。我在我的代码中使用宏,给出一个最小的例子是很痛苦所以我给了whole project。只需在root上执行“make”,然后启动./sash,会出现一个提示,如果你想测试只做“-echo $ 5-8”。
Google似乎没有发现任何有关此异常的类似问题......
解析器处于arithmetic /中,解析器的调用位于arithmetic / evaluator.cpp的末尾
任何帮助都非常感激。
答案 0 :(得分:3)
您的代码正在破坏,因为BOOST_SPIRIT_QI_DEBUG以及on_error<>
处理程序似乎在它们可能已失效后使用迭代器。
说实话,我不完全确定这是怎么发生的。
AFAICT lexertl使用spirit::multipass<>
split_functor
输入政策和split_std_deque
存储政策 [1] 。
现在,(幸运的是?)检查策略是buf_id_check
,这意味着迭代器将在取消引用时检查失效。
如果
,预计迭代器将失效clear_queue
行的某个地方被明确地称为(例如来自Spirit Repository中的flush_multi_path
原语)老实说,我没有看到满足这两个条件中的任何一个。快速而肮脏
token_iterator_type clone = iter; // just to make it non-unique...
evaluator.cpp
中的没有区别(排除原因#1)
临时禁用docheck
中的buf_id_check_policy
实现使得valgrind指出on_error<>
和BOOST_SPIRIT_DEBUG *导致无效的内存引用。评论两者确实会使所有问题都消失(eval_expression
现在可以正常工作)。
但是,这可能不是您首选的解决方案。
自
multi_pass
行为模拟的输入我已经快速重构了一些代码: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个删除( - )
现在,您会发现您的代码通常更简单,更短,没有遇到multi_pass限制,您仍然可以使用SPIRIT_DEBUG以及on_error
处理:)最后
这是一些示例(没有调试输出):
$ ./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<>