Location: PHPKode > projects > Harmony preview > harmony-preview/libraries/Harmony/Parser/String.php
<?php
/**
 * Harmony
 * Copyright (c) 2008 Maxime Bouroumeau-Fuseau
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * @category Harmony
 * @package Harmony_Parser 
 * @author Maxime Bouroumeau-Fuseau
 * @copyright 2008 (c) Maxime Bouroumeau-Fuseau
 * @license http://www.opensource.org/licenses/mit-license.php
 * @link http://www.harmony-framework.com
 */

/** Harmony_Parser_Abstract */
require_once 'Harmony/Parser/Abstract.php';

/**
 * @category Harmony
 * @package Harmony_Parser 
 * @copyright 2008 (c) Maxime Bouroumeau-Fuseau
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class Harmony_Parser_String extends Harmony_Parser_Abstract
{	
	/**
	 * Current offset
	 *
	 * @var int
	 */
	protected $_offset;
	
	/**
	 * String length
	 *
	 * @var int
	 */
	protected $_length;
	
	/**
	 * Parse the specified string. 
	 * Must specify the starting context
	 *
	 * @param string $data
	 * @param string $context
	 * @param array $params OPTIONAL Context parameters
	 * @return mixed Data returned by the context
	 */
	public function parse($string, $context, $params = array())
	{
		$this->_data = $string;
		$this->_offset = 0;
		$this->_length = strlen($string);
		
		return $this->enterContext($context, $params);
	}
	
	/**
	 * Enters a next context
	 *
	 * @param string $context
	 * @param array $params OPTIONAL Context parameters
	 * @return mixed Data returned by context
	 */
	public function enterContext($context, $params = array())
	{
		/* create the context instance */
		$classname = $this->getContextClassName($context);
		$instance = new $classname($this, $params);
		
		/* parser loop */
		while ($this->_offset <= $this->_length) {
			/* search for the next token */
			list($token, $text) = $this->_gotoNextToken($instance->_getTokens());
			/* execute action for the token */
			$contextEnd = $instance->_doActionForToken($token, $text);
			if ($contextEnd) {
				break;
			}
		}
		
		$data = $instance->_getExitData();
		return $data;
	}
	
	/**
	 * Goto the next token and return the text between the last token and the newly found one
	 *
	 * @return array An array with the token name as first element and the text as second
	 */
	public function _gotoNextToken($additionalTokens = array())
	{
		list($token, $nextOffset) = $this->_getNextToken($additionalTokens);
		
		$text = substr($this->_data, $this->_offset, $nextOffset - $this->_offset);
		$this->_offset = $nextOffset + 1;
		
		return array($token, $text);
	}
	
	/**
	 * Get the next token
	 *
	 * @return array Array with the token name as the first element and the offset as the second
	 */
	public function _getNextToken($additionalTokens = array())
	{
		$tokens = array_merge($this->_tokens, $additionalTokens);
		$token = self::EOF;
		$nextOffset = $this->_length;
		foreach ($tokens as $name => $regexp) {
			if(preg_match('/' . $regexp . '/', $this->_data, $matches, PREG_OFFSET_CAPTURE, $this->_offset)) {
				if ($nextOffset > $matches[0][1]) {
					$token = $name;
					$nextOffset = $matches[0][1];
				}
			}
		}
		return array($token, $nextOffset);
	}
	
	/**
	 * Sets the offset
	 *
	 * @param int $offset
	 */
	public function _setOffset($offset)
	{
		if ($offset > $this->_length) {
			require_once 'Harmony/Parser/Exception.php';
			throw new Harmony_Parser_Exception('Offset must be less than the length');
		}
		$this->_offset = $offset;
	}
	
	/**
	 * Gets the current offset
	 *
	 * @return int
	 */
	public function _getOffset()
	{
		return $this->_offset;
	}
	
	/**
	 * Gets the length of the string being parsed
	 *
	 * @return int
	 */
	public function _getLength()
	{
		return $this->_length;
	}
}
Return current item: Harmony preview