我需要迭代abstract syntax tree。 AST由lemon port to PHP生成。
现在“正常”,我会使用全新且闪亮的(PHP 5.3.1)SPL类来实现它,它看起来像这样:
$it = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator($ast['rule']),
\RecursiveIteratorIterator::SELF_FIRST);
实际上,这就是我在代码的另一部分中所做的,它确定了整个树的粗略类型(即它可以是赋值,条件等)。现在详细说明,唯一重要的是迭代完成RecursiveIteratorIterator :: SELF_FIRST,即自上而下。
回到我的问题,我需要自下而上迭代AST,就像RecursiveIteratorIterator :: CHILD_FIRST一样,以便在树中进行一些替换和优化。
问题是,这些操作需要是上下文感知的,即我需要向下到当前节点的路径。因为我想自下而上迭代,所以我不能使用RecursiveIteratorIterator。
好好想一下。我希望在每次迭代时自下而上迭代并具有当前节点的自上而下的上下文(堆栈)。从技术上讲,它应该是可能的,因为RecursiveIteratorIterator必须首先进入树的尾部,以便向后迭代。在它到尾部的路上,它可以缓存当前位置,并在从递归返回时简单地弹出元素。
现在这是一个关键字:缓存。这就是为什么我怀疑应该可以使用另一个SPL类:RecursiveCachingIterator。
问题是:它真的可能吗?如果是,怎么样?
我一直试图解决一些代码,但没有成功,文档很少。真的,真的很稀缺。
无论谁使用SPL找到最优雅的解决方案,都要大笑!你是一个PHP大师!
PS:如果不清楚,我正在寻找尽可能多的SPL( re )使用。我知道我可以使用自定义堆栈编写自己的递归函数,无需提醒我。
答案 0 :(得分:2)
我已经设法通过继承RecursiveIteratorIterator并分别管理:: endChildren()和:: callGetChildren中的堆栈来实现它。也许这会对某人有所帮助。对自己说: - )