1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Latte;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17:
18: class MacroTokens extends Nette\Utils\TokenIterator
19: {
20: const T_WHITESPACE = 1,
21: = 2,
22: T_SYMBOL = 3,
23: T_NUMBER = 4,
24: T_VARIABLE = 5,
25: T_STRING = 6,
26: T_CAST = 7,
27: T_KEYWORD = 8,
28: T_CHAR = 9;
29:
30:
31: private static $tokenizer;
32:
33:
34: public $depth = 0;
35:
36:
37: public function __construct($input = NULL)
38: {
39: parent::__construct(is_array($input) ? $input : $this->parse($input));
40: $this->ignored = array(self::T_COMMENT, self::T_WHITESPACE);
41: }
42:
43:
44: public function parse($s)
45: {
46: self::$tokenizer = self::$tokenizer ?: new Nette\Utils\Tokenizer(array(
47: self::T_WHITESPACE => '\s+',
48: self::T_COMMENT => '(?s)/\*.*?\*/',
49: self::T_STRING => Parser::RE_STRING,
50: self::T_KEYWORD => '(?:true|false|null|and|or|xor|clone|new|instanceof|return|continue|break|endif|endforeach|endwhile|endswitch|[A-Z_][A-Z0-9_]{2,})(?![\w\pL_])',
51: self::T_CAST => '\((?:expand|string|array|int|integer|float|bool|boolean|object)\)',
52: self::T_VARIABLE => '\$[\w\pL_]+',
53: self::T_NUMBER => '[+-]?[0-9]+(?:\.[0-9]+)?(?:e[0-9]+)?',
54: self::T_SYMBOL => '[\w\pL_]+(?:-[\w\pL_]+)*',
55: self::T_CHAR => '::|=>|->|\+\+|--|<<|>>|<=|>=|===|!==|==|!=|<>|&&|\|\||[^"\']',
56: ), 'u');
57: return self::$tokenizer->tokenize($s);
58: }
59:
60:
61: 62: 63: 64:
65: public function append($val, $position = NULL)
66: {
67: if ($val != NULL) {
68: array_splice(
69: $this->tokens,
70: $position === NULL ? count($this->tokens) : $position, 0,
71: is_array($val) ? array($val) : $this->parse($val)
72: );
73: }
74: return $this;
75: }
76:
77:
78: 79: 80: 81:
82: public function prepend($val)
83: {
84: if ($val != NULL) {
85: array_splice($this->tokens, 0, 0, is_array($val) ? array($val) : $this->parse($val));
86: }
87: return $this;
88: }
89:
90:
91: 92: 93: 94: 95:
96: public function fetchWord()
97: {
98: $words = $this->fetchWords();
99: return $words ? implode(':', $words) : FALSE;
100: }
101:
102:
103: 104: 105: 106: 107:
108: public function fetchWords()
109: {
110: do {
111: $words[] = $this->joinUntil(self::T_WHITESPACE, ',', ':');
112: } while ($this->nextToken(':'));
113: $this->nextToken(',');
114: $this->nextAll(self::T_WHITESPACE, self::T_COMMENT);
115: return $words === array('') ? array() : $words;
116: }
117:
118:
119: public function reset()
120: {
121: $this->depth = 0;
122: return parent::reset();
123: }
124:
125:
126: protected function next()
127: {
128: parent::next();
129: if ($this->isCurrent('[', '(', '{')) {
130: $this->depth++;
131: } elseif ($this->isCurrent(']', ')', '}')) {
132: $this->depth--;
133: }
134: }
135:
136: }
137: