(Sözdizimi ağaçları) ardışık mevcut top-down yolu ile ağaçlar alt-up üzerinde yineleme

1 Cevap php

Ben yinelemek gerekiyor bir abstract syntax tree, hangi var. AST lemon port to PHP tarafından oluşturulur.

Şimdi "normal" olarak, ben yeni ve parlak bir marka (PHP 5.3.1) SPL sınıfları ile bunu istiyorum, ve bu gibi görünecektir:

$it = new \RecursiveIteratorIterator(
  new \RecursiveArrayIterator($ast['rule']),
  \RecursiveIteratorIterator::SELF_FIRST);

Aslında bu (yani, vb, bir durum bir atama olabilir) Zaten bütün ağacın kaba bir türü belirlemiştir kodun başka bir yerinde yapıyorum. Şimdi bir kenara ayrıntıları, tek önemli şey yineleme RecursiveIteratorIterator :: SELF_FIRST, yani yukarıdan aşağıya yapılmasıdır.

Geri benim sorunum oluyor, ben, AST alt-up yineleme ağacında bazı değiştirmelerin ve optimizasyonlar yapmak için RecursiveIteratorIterator :: CHILD_FIRST gibi yani, bir şey lazım.

Sorun, bu işlemler yani ben aşağı geçerli düğümün yolunu gerekir, bağlam farkında olması gerekir, olduğunu. Ben alt-up yinelemek istiyorum çünkü, ben RecursiveIteratorIterator ile bu olamaz.

Peki bir saniye düşün. Ben alt-up yinelemek ve her tekrarında, geçerli düğümün yukarıdan aşağıya bağlam (bir yığın) olmasını istiyorum. RecursiveIteratorIterator ilk geriye doğru yineleme için, ağacın kuyruk gitmek gerekir beri teknik olarak mümkün olmalıdır. Kuyruk yolunda, bu mevcut konumunu önbelleğe ve sadece geri özyineleme döner gibi öğeleri dışarı pop olabilir.

Şimdi bu bir anahtar kelime: caching. Ben başka bir SPL sınıf ile mümkün olmalıdır şüpheli nedeni budur: RecursiveCachingIterator.

Soru: bu gerçekten mümkün olduğunu? Evetse, nasıl?

Ben başarı olmadan, bazı kod ile etrafında bulmaca çalışıyorum ve dokümantasyon azdır. Gerçekten, gerçekten kıt.

Whoever finds the most elegant solution to this using SPL, hats off! You're a PHP guru!

PS: net değil durumda, ben mümkün as much SPL (re) kullanım için arıyorum. Ben, özel bir yığını ile bu konuda bana hatırlatmak gerek kendi özyinelemeli işlevler yazabilirsiniz biliyorum.

1 Cevap

Ben sırasıyla callGetChildren RecursiveIteratorIterator miras ve :: endChildren (yığını yöneterek bu çalışma almak için yönetilen) ve :: var. Belki bu birisi yardımcı olacaktır. :-) Kendime şapka kapalı