예제 #1
0
	/**
	 * Tokenizer and preparser.
	 * @return array
	 */
	private function parseMacro($input)
	{
		$this->tokenizer->tokenize($input);
		$this->tokenizer->tokens[] = NULL; // sentinel

		$inTernary = $lastSymbol = $prev = NULL;
		$tokens = $arrays = array();
		$n = -1;
		while (++$n < count($this->tokenizer->tokens)) {
			list($token, $name) = $current = $this->tokenizer->tokens[$n];
			$depth = count($arrays);

			if ($name === self::T_COMMENT) {
				continue; // remove comments

			} elseif ($name === self::T_WHITESPACE) {
				$current[2] = $depth;
				$tokens[] = $current;
				continue;

			} elseif ($name === self::T_SYMBOL && in_array($prev[0], array(',', '(', '[', '=', '=>', ':', '?', NULL), TRUE)) {
				$lastSymbol = count($tokens); // quoting pre-requirements

			} elseif (is_int($lastSymbol) && in_array($token, array(',', ')', ']', '=', '=>', ':', '|', NULL), TRUE)) {
				$tokens[$lastSymbol][0] = "'" . $tokens[$lastSymbol][0] . "'"; // quote symbols
				$lastSymbol = NULL;

			} else {
				$lastSymbol = NULL;
			}

			if ($token === '?') { // short ternary operators without :
				$inTernary = $depth;

			} elseif ($token === ':') {
				$inTernary = NULL;

			} elseif ($inTernary === $depth && ($token === ',' || $token === ')' || $token === ']' || $token === NULL)) { // close ternary
				$tokens[] = array(':', NULL, $depth);
				$tokens[] = array('null', NULL, $depth);
				$inTernary = NULL;
			}

			if ($token === '[') { // simplified array syntax [...]
				if ($arrays[] = $prev[0] !== ']' && $prev[1] !== self::T_SYMBOL && $prev[1] !== self::T_VARIABLE) {
					$tokens[] = array('array', NULL, $depth);
					$current = array('(', NULL);
				}
			} elseif ($token === ']') {
				if (array_pop($arrays) === TRUE) {
					$current = array(')', NULL);
				}
			} elseif ($token === '(') { // only count
				$arrays[] = '(';

			} elseif ($token === ')') { // only count
				array_pop($arrays);
			}

			if ($current) {
				$current[2] = $depth;
				$tokens[] = $prev = $current;
			}
		}
		return $tokens;
	}
예제 #2
0
 private function error($message = "Unexpected '%s'")
 {
     list(, $line, $col) = self::$tokenizer->getOffset($this->n);
     $token = str_replace("\n", '\\n', Nette\String::truncate(self::$tokenizer->tokens[$this->n], 40));
     throw new NeonException(str_replace('%s', $token, $message) . "' on line " . ($line - 1) . ", column {$col}.");
 }
예제 #3
0
	private function error($message = "Unexpected '%s'")
	{
		list(, $line, $col) = self::$tokenizer->getOffset($this->n);
		$token = isset(self::$tokenizer->tokens[$this->n]) ? str_replace("\n", '<new line>', Nette\String::truncate(self::$tokenizer->tokens[$this->n], 40)) : 'end';
		throw new NeonException(str_replace('%s', $token, $message) . " on line $line, column $col.");
	}
예제 #4
0
	/**
	 * Formats parameters to PHP array.
	 * @param  string
	 * @param  string
	 * @return string
	 */
	public static function formatArray($input, $prefix = '')
	{
		$tokenizer = new Tokenizer(array(
			Tokenizer::T_WHITESPACE => '\s+',
			Tokenizer::T_COMMENT => '/\*.*?\*/',
			Tokenizer::RE_STRING,
			'true|false|null|and|or|xor|clone|new|instanceof',
			'\$[_a-z0-9\x7F-\xFF]+', // variable
			self::T_SYMBOL => '[_a-z0-9\x7F-\xFF]+', // string, number
			'=>|[^"\']', // =>, any char except quotes
		), 'i');

		$out = '';
		$quote = TRUE;
		foreach ($tokenizer->tokenize($input) as $n => $token) {
			list($token, $name) = $token;

			if ($name === Tokenizer::T_COMMENT) {
				continue;

			} elseif ($name === self::T_SYMBOL && $quote && !is_numeric($token)
				&& in_array($tokenizer->nextToken($n), array(',', '=>', ')', NULL), TRUE)) {
				$token = "'$token'";
			}
			if ($name !== Tokenizer::T_WHITESPACE) {
				$quote = in_array($token, array('[', ',', '=', '(', '=>'));
			}
			$out .= $token;
		}
		return $out === '' ? '' : $prefix . "array($out)";
	}
예제 #5
0
	private function error()
	{
		list(, $line, $col) = self::$tokenizer->getOffset($this->n);
		throw new NeonException("Unexpected '" . str_replace("\n", '\n', substr(self::$tokenizer->tokens[$this->n], 0, 10))
			. "' on line " . ($line - 1) . ", column $col.");
	}