1<?php 2 3/** 4 * Hoa 5 * 6 * 7 * @license 8 * 9 * New BSD License 10 * 11 * Copyright © 2007-2017, Hoa community. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions are met: 15 * * Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * * Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * * Neither the name of the Hoa nor the names of its contributors may be 21 * used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37namespace Hoa\Compiler\Llk; 38 39use Hoa\Visitor; 40 41/** 42 * Class \Hoa\Compiler\Llk\TreeNode. 43 * 44 * Provide a generic node for the AST produced by LL(k) parser. 45 * 46 * @copyright Copyright © 2007-2017 Hoa community 47 * @license New BSD License 48 */ 49class TreeNode implements Visitor\Element 50{ 51 /** 52 * ID (should be something like #ruleName or token). 53 * 54 * @var string 55 */ 56 protected $_id = null; 57 58 /** 59 * Value of the node (non-null for token nodes). 60 * 61 * @var array 62 */ 63 protected $_value = null; 64 65 /** 66 * Children. 67 * 68 * @var array 69 */ 70 protected $_children = null; 71 72 /** 73 * Parent. 74 * 75 * @var \Hoa\Compiler\Llk\TreeNode 76 */ 77 protected $_parent = null; 78 79 /** 80 * Attached data. 81 * 82 * @var array 83 */ 84 protected $_data = []; 85 86 87 88 /** 89 * Constructor. 90 * 91 * @param string $id ID. 92 * @param array $value Value. 93 * @param array $children Children. 94 * @param \Hoa\Compiler\Llk\TreeNode $parent Parent. 95 */ 96 public function __construct( 97 $id, 98 array $value = null, 99 array $children = [], 100 self $parent = null 101 ) { 102 $this->setId($id); 103 104 if (!empty($value)) { 105 $this->setValue($value); 106 } 107 108 $this->setChildren($children); 109 110 if (null !== $parent) { 111 $this->setParent($parent); 112 } 113 114 return; 115 } 116 117 /** 118 * Set ID. 119 * 120 * @param string $id ID. 121 * @return string 122 */ 123 public function setId($id) 124 { 125 $old = $this->_id; 126 $this->_id = $id; 127 128 return $old; 129 } 130 131 /** 132 * Get ID. 133 * 134 * @return string 135 */ 136 public function getId() 137 { 138 return $this->_id; 139 } 140 141 /** 142 * Set value. 143 * 144 * @param array $value Value (token & value). 145 * @return array 146 */ 147 public function setValue(array $value) 148 { 149 $old = $this->_value; 150 $this->_value = $value; 151 152 return $old; 153 } 154 155 /** 156 * Get value. 157 * 158 * @return array 159 */ 160 public function getValue() 161 { 162 return $this->_value; 163 } 164 165 /** 166 * Get value token. 167 * 168 * @return string 169 */ 170 public function getValueToken() 171 { 172 return 173 isset($this->_value['token']) 174 ? $this->_value['token'] 175 : null; 176 } 177 178 /** 179 * Get value value. 180 * 181 * @return string 182 */ 183 public function getValueValue() 184 { 185 return 186 isset($this->_value['value']) 187 ? $this->_value['value'] 188 : null; 189 } 190 191 /** 192 * Check if the node represents a token or not. 193 * 194 * @return bool 195 */ 196 public function isToken() 197 { 198 return !empty($this->_value); 199 } 200 201 /** 202 * Prepend a child. 203 * 204 * @param \Hoa\Compiler\Llk\TreeNode $child Child. 205 * @return \Hoa\Compiler\Llk\TreeNode 206 */ 207 public function prependChild(TreeNode $child) 208 { 209 array_unshift($this->_children, $child); 210 211 return $this; 212 } 213 214 /** 215 * Append a child. 216 * 217 * @param \Hoa\Compiler\Llk\TreeNode $child Child. 218 * @return \Hoa\Compiler\Llk\TreeNode 219 */ 220 public function appendChild(TreeNode $child) 221 { 222 $this->_children[] = $child; 223 224 return $this; 225 } 226 227 /** 228 * Set children. 229 * 230 * @param array $children Children. 231 * @return array 232 */ 233 public function setChildren(array $children) 234 { 235 $old = $this->_children; 236 $this->_children = $children; 237 238 return $old; 239 } 240 241 /** 242 * Get child. 243 * 244 * @param int $i Index. 245 * @return \Hoa\Compiler\Llk\TreeNode 246 */ 247 public function getChild($i) 248 { 249 return 250 true === $this->childExists($i) 251 ? $this->_children[$i] 252 : null; 253 } 254 255 /** 256 * Get children. 257 * 258 * @return array 259 */ 260 public function getChildren() 261 { 262 return $this->_children; 263 } 264 265 /** 266 * Get number of children. 267 * 268 * @return int 269 */ 270 public function getChildrenNumber() 271 { 272 return count($this->_children); 273 } 274 275 /** 276 * Check if a child exists. 277 * 278 * @param int $i Index. 279 * @return bool 280 */ 281 public function childExists($i) 282 { 283 return array_key_exists($i, $this->_children); 284 } 285 286 /** 287 * Set parent. 288 * 289 * @param \Hoa\Compiler\Llk\TreeNode $parent Parent. 290 * @return \Hoa\Compiler\Llk\TreeNode 291 */ 292 public function setParent(TreeNode $parent) 293 { 294 $old = $this->_parent; 295 $this->_parent = $parent; 296 297 return $old; 298 } 299 300 /** 301 * Get parent. 302 * 303 * @return \Hoa\Compiler\Llk\TreeNode 304 */ 305 public function getParent() 306 { 307 return $this->_parent; 308 } 309 310 /** 311 * Get data. 312 * 313 * @return array 314 */ 315 public function &getData() 316 { 317 return $this->_data; 318 } 319 320 /** 321 * Accept a visitor. 322 * 323 * @param \Hoa\Visitor\Visit $visitor Visitor. 324 * @param mixed &$handle Handle (reference). 325 * @param mixed $eldnah Handle (no reference). 326 * @return mixed 327 */ 328 public function accept( 329 Visitor\Visit $visitor, 330 &$handle = null, 331 $eldnah = null 332 ) { 333 return $visitor->visit($this, $handle, $eldnah); 334 } 335 336 /** 337 * Remove circular reference to the parent (help the garbage collector). 338 * 339 * @return void 340 */ 341 public function __destruct() 342 { 343 unset($this->_parent); 344 345 return; 346 } 347} 348