1<?php 2/** 3 * Handlebars parser (based on mustache) 4 * 5 * This class is responsible for turning raw template source into a set of 6 * Handlebars tokens. 7 * 8 * @category Xamin 9 * @package Handlebars 10 * @author fzerorubigd <fzerorubigd@gmail.com> 11 * @author Behrooz Shabani <everplays@gmail.com> 12 * @author Mardix <https://github.com/mardix> 13 * @copyright 2012 (c) ParsPooyesh Co 14 * @copyright 2013 (c) Behrooz Shabani 15 * @copyright 2013 (c) Mardix 16 * @license MIT 17 * @link http://voodoophp.org/docs/handlebars 18 */ 19 20namespace Handlebars; 21use ArrayIterator; 22use LogicException; 23 24class Parser 25{ 26 /** 27 * Process array of tokens and convert them into parse tree 28 * 29 * @param array $tokens Set of 30 * 31 * @return array Token parse tree 32 */ 33 public function parse(Array $tokens = []) 34 { 35 return $this->buildTree(new ArrayIterator($tokens)); 36 } 37 38 /** 39 * Helper method for recursively building a parse tree. 40 * 41 * @param \ArrayIterator $tokens Stream of tokens 42 * 43 * @throws \LogicException when nesting errors or mismatched section tags 44 * are encountered. 45 * @return array Token parse tree 46 * 47 */ 48 private function buildTree(ArrayIterator $tokens) 49 { 50 $stack = []; 51 52 do { 53 $token = $tokens->current(); 54 $tokens->next(); 55 56 if ($token === null) { 57 continue; 58 } else { 59 switch ($token[Tokenizer::TYPE]) { 60 case Tokenizer::T_END_SECTION: 61 $newNodes = []; 62 do { 63 $result = array_pop($stack); 64 if ($result === null) { 65 throw new LogicException( 66 'Unexpected closing tag: /' . $token[Tokenizer::NAME] 67 ); 68 } 69 70 if (!array_key_exists(Tokenizer::NODES, $result) 71 && isset($result[Tokenizer::NAME]) 72 && $result[Tokenizer::NAME] == $token[Tokenizer::NAME] 73 ) { 74 $result[Tokenizer::NODES] = $newNodes; 75 $result[Tokenizer::END] = $token[Tokenizer::INDEX]; 76 array_push($stack, $result); 77 break 2; 78 } else { 79 array_unshift($newNodes, $result); 80 } 81 } while (true); 82 break; 83 default: 84 array_push($stack, $token); 85 } 86 } 87 88 } while ($tokens->valid()); 89 90 return $stack; 91 92 } 93 94} 95