[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/macro/src/ -> lmbMacroTreeBuilder.class.php (source)

   1  <?php
   2  /*
   3   * Limb PHP Framework
   4   *
   5   * @link http://limb-project.com 
   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
   8   */
   9  
  10  /**
  11   * Acts on the root lmbMacroNode in response to events within the lmbMacroParser
  12   *
  13   * When adding an open tag to the tree, call pushExpectedTag().  When closing
  14   * a tag, call popExpectedTag(), which ensures the tree is balanced.
  15   *
  16   * These methods do not actually add nodes to the tree, as tags and nodes
  17   * do not necessarily match up.
  18   *
  19   * To add a node to the tree, you have the following choices.  To add a node
  20   * which can have children, use pushNode().  To add a terminal node use addNode(),
  21   * or addTextNode().
  22   * @package macro
  23   * @version $Id$
  24   */
  25  
  26  
  27  lmb_require('limb/macro/src/lmbMacroTextNode.class.php');class lmbMacroTreeBuilder
  28  {
  29    protected $compiler;
  30    protected $node;
  31  
  32    /**

  33    * Stack of tags pushed onto the tree builder

  34    */
  35    var $expected_tags = array();
  36  
  37    function __construct($compiler)
  38    {
  39      $this->compiler = $compiler;
  40    }
  41  
  42    /**

  43    * Returns the current node

  44    */
  45    function getCursor()
  46    {
  47      return $this->node;
  48    }
  49  
  50    /**

  51    * Sets the cursor (the current working node) of the tree builder

  52    */
  53    function setCursor($node)
  54    {
  55      $this->node = $node;
  56    }
  57  
  58    /**

  59    * Begins a node's build phase in relation to the node tree.

  60    * Adds a node to the tree, then makes that node the 'cursor'.

  61    */
  62    function pushNode($node)
  63    {
  64      $this->node->addChild($node);
  65      $this->setCursor($node);
  66      return $this->node->preParse($this->compiler);
  67    }
  68  
  69    /**

  70    * Adds a node to the tree, without descending into it.

  71    * This begins and finishes the node's composition

  72    */
  73    function addNode($node)
  74    {
  75      $node->preParse($this->compiler);
  76      $this->node->addChild($node);
  77    }
  78  
  79    function addTextNode($text)
  80    {
  81      $this->addNode(new lmbMacroTextNode(null, $text));
  82    }
  83  
  84    /**

  85    * Ends a node's build phase in relation to the tree.

  86    * Checks child server ids and moves the 'cursor' up the tree to the parent

  87    * node.

  88    */
  89    function popNode()
  90    {    
  91      $this->node->checkChildrenIds();
  92      $this->setCursor($this->node->getParent());
  93    }
  94  
  95    function pushExpectedTag($tag, $location = null)
  96    {
  97      array_push($this->expected_tags, array($tag, $location));
  98    }
  99  
 100    /**

 101    * Sets the cursor to a new position, and pushes the old cursor onto the

 102    * expected tags stack.

 103    * @see popExpectedTag

 104    */
 105    function pushCursor($newPosition, $location)
 106    {
 107      // use of array() is to preserve reference from array_pop()

 108      array_push($this->expected_tags, array($this->node, $location));
 109      $this->setCursor($newPosition);
 110    }
 111  
 112    /**

 113    * Tests the passed tag against what is expected.  Returns any info that

 114    * was kept about the expected tag.

 115    * If the item in the tag stack is a node, then the cursor is

 116    * restored to that, and popExpectedTag is called again.

 117    */
 118    function popExpectedTag($tag, $location)
 119    {
 120      if(!$expected_tag_item = array_pop($this->expected_tags))
 121      {
 122        throw new lmbMacroException('Lonely closing tag', array('tag' => $tag,
 123                                                            'file' => $location->getFile(),
 124                                                            'line' => $location->getLine()));
 125      }
 126  
 127      // if we have a node on the stack, restore the cursor to that, and

 128      // pop the stack again

 129      if(is_object($expected_tag_item[0]))
 130      {
 131        $this->node = $expected_tag_item[0];
 132        return $this->popExpectedTag($tag, $location);
 133      }
 134  
 135      $expected_tag = $expected_tag_item[0];    
 136      $expected_location = $expected_tag_item[1];
 137  
 138      if(strcasecmp($expected_tag, $tag) === 0)
 139        return $tag;
 140   
 141      throw new lmbMacroException('Unexpected closing tag',
 142                               array('file' => $location->getFile(),
 143                                    'tag' => $tag,
 144                                    'line' => $location->getLine(),
 145                                    'expected_tag' => $expected_tag,
 146                                    'expected_file' => $expected_location->getFile(),
 147                                    'expected_line' => $expected_location->getLine()));
 148    }
 149  
 150    /**

 151    * Return the size of the expected tags stack

 152    */
 153    function getExpectedTagCount()
 154    {
 155      return count($this->expected_tags);
 156    }
 157  
 158    /**

 159    * Returns the current expected tag

 160    */
 161    function getExpectedTag()
 162    {
 163      // Returns the tagname of the first non-node item on the stack

 164      $item = end($this->expected_tags);
 165      while($item && !is_string($item[0]))
 166        $item = prev($this->expected_tags);
 167      return $item ? $item[0] : false;
 168    }
 169  
 170    function getExpectedTagLocation()
 171    {
 172      $item = end($this->expected_tags);
 173      return $item[2];
 174    }
 175  }
 176  ?>


Generated: Fri Aug 29 04:49:26 2008 Cross-referenced by PHPXref 0.7