/**
  * Tokenizer and preparser.
  * @return array
  */
 private function parseMacroArgs($input)
 {
     $this->tokenizer->tokenize($input);
     $inTernary = $lastSymbol = $prev = NULL;
     $tokens = $arrays = array();
     $n = -1;
     while (++$n < count($this->tokenizer->tokens)) {
         $token = $this->tokenizer->tokens[$n];
         $token['depth'] = $depth = count($arrays);
         if ($token['type'] === self::T_COMMENT) {
             continue;
             // remove comments
         } elseif ($token['type'] === self::T_WHITESPACE) {
             $tokens[] = $token;
             continue;
         } elseif ($token['type'] === self::T_SYMBOL && ($prev === NULL || in_array($prev['value'], array(',', '(', '[', '=', '=>', ':', '?')))) {
             $lastSymbol = count($tokens);
             // quoting pre-requirements
         } elseif (is_int($lastSymbol) && in_array($token['value'], array(',', ')', ']', '=', '=>', ':', '|'))) {
             $tokens[$lastSymbol]['value'] = "'" . $tokens[$lastSymbol]['value'] . "'";
             // quote symbols
             $lastSymbol = NULL;
         } else {
             $lastSymbol = NULL;
         }
         if ($token['value'] === '?') {
             // short ternary operators without :
             $inTernary = $depth;
         } elseif ($token['value'] === ':') {
             $inTernary = NULL;
         } elseif ($inTernary === $depth && ($token['value'] === ',' || $token['value'] === ')' || $token['value'] === ']')) {
             // close ternary
             $tokens[] = Tokenizer::createToken(':') + array('depth' => $depth);
             $tokens[] = Tokenizer::createToken('null') + array('depth' => $depth);
             $inTernary = NULL;
         }
         if ($token['value'] === '[') {
             // simplified array syntax [...]
             if ($arrays[] = $prev['value'] !== ']' && $prev['type'] !== self::T_SYMBOL && $prev['type'] !== self::T_VARIABLE) {
                 $tokens[] = Tokenizer::createToken('array') + array('depth' => $depth);
                 $token = Tokenizer::createToken('(');
             }
         } elseif ($token['value'] === ']') {
             if (array_pop($arrays) === TRUE) {
                 $token = Tokenizer::createToken(')');
             }
         } elseif ($token['value'] === '(') {
             // only count
             $arrays[] = '(';
         } elseif ($token['value'] === ')') {
             // only count
             array_pop($arrays);
         }
         $tokens[] = $prev = $token;
     }
     if (is_int($lastSymbol)) {
         $tokens[$lastSymbol]['value'] = "'" . $tokens[$lastSymbol]['value'] . "'";
         // quote symbols
     }
     if ($inTernary !== NULL) {
         // close ternary
         $tokens[] = Tokenizer::createToken(':') + array('depth' => count($arrays));
         $tokens[] = Tokenizer::createToken('null') + array('depth' => count($arrays));
     }
     return $tokens;
 }