1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Utils;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17:
18: class TokenIterator
19: {
20:
21: public $tokens;
22:
23:
24: public $position = -1;
25:
26:
27: public $ignored = array();
28:
29:
30: 31: 32:
33: public function __construct(array $tokens)
34: {
35: $this->tokens = $tokens;
36: }
37:
38:
39: 40: 41: 42:
43: public function currentToken()
44: {
45: return isset($this->tokens[$this->position])
46: ? $this->tokens[$this->position]
47: : NULL;
48: }
49:
50:
51: 52: 53: 54:
55: public function currentValue()
56: {
57: return isset($this->tokens[$this->position])
58: ? $this->tokens[$this->position][Tokenizer::VALUE]
59: : NULL;
60: }
61:
62:
63: 64: 65: 66: 67:
68: public function nextToken()
69: {
70: return $this->scan(func_get_args(), TRUE, TRUE);
71: }
72:
73:
74: 75: 76: 77: 78:
79: public function nextValue()
80: {
81: return $this->scan(func_get_args(), TRUE, TRUE, TRUE);
82: }
83:
84:
85: 86: 87: 88: 89:
90: public function nextAll()
91: {
92: return $this->scan(func_get_args(), FALSE, TRUE);
93: }
94:
95:
96: 97: 98: 99: 100:
101: public function nextUntil($arg)
102: {
103: return $this->scan(func_get_args(), FALSE, TRUE, FALSE, TRUE);
104: }
105:
106:
107: 108: 109: 110: 111:
112: public function joinAll()
113: {
114: return $this->scan(func_get_args(), FALSE, TRUE, TRUE);
115: }
116:
117:
118: 119: 120: 121: 122:
123: public function joinUntil($arg)
124: {
125: return $this->scan(func_get_args(), FALSE, TRUE, TRUE, TRUE);
126: }
127:
128:
129: 130: 131: 132: 133:
134: public function isCurrent($arg)
135: {
136: if (!isset($this->tokens[$this->position])) {
137: return FALSE;
138: }
139: $args = func_get_args();
140: $token = $this->tokens[$this->position];
141: return in_array($token[Tokenizer::VALUE], $args, TRUE)
142: || (isset($token[Tokenizer::TYPE]) && in_array($token[Tokenizer::TYPE], $args, TRUE));
143: }
144:
145:
146: 147: 148: 149: 150:
151: public function isNext()
152: {
153: return (bool) $this->scan(func_get_args(), TRUE, FALSE);
154: }
155:
156:
157: 158: 159: 160: 161:
162: public function isPrev()
163: {
164: return (bool) $this->scan(func_get_args(), TRUE, FALSE, FALSE, FALSE, TRUE);
165: }
166:
167:
168: 169: 170:
171: public function reset()
172: {
173: $this->position = -1;
174: return $this;
175: }
176:
177:
178: 179: 180:
181: protected function next()
182: {
183: $this->position++;
184: }
185:
186:
187: 188: 189: 190: 191: 192: 193: 194: 195: 196:
197: protected function scan($wanted, $onlyFirst, $advance, $strings = FALSE, $until = FALSE, $prev = FALSE)
198: {
199: $res = $onlyFirst ? NULL : ($strings ? '' : array());
200: $pos = $this->position + ($prev ? -1 : 1);
201: do {
202: if (!isset($this->tokens[$pos])) {
203: if (!$wanted && $advance && !$prev && $pos <= count($this->tokens)) {
204: $this->next();
205: }
206: return $res;
207: }
208:
209: $token = $this->tokens[$pos];
210: $type = isset($token[Tokenizer::TYPE]) ? $token[Tokenizer::TYPE] : NULL;
211: if (!$wanted || (in_array($token[Tokenizer::VALUE], $wanted, TRUE) || in_array($type, $wanted, TRUE)) ^ $until) {
212: while ($advance && !$prev && $pos > $this->position) {
213: $this->next();
214: }
215:
216: if ($onlyFirst) {
217: return $strings ? $token[Tokenizer::VALUE] : $token;
218: } elseif ($strings) {
219: $res .= $token[Tokenizer::VALUE];
220: } else {
221: $res[] = $token;
222: }
223:
224: } elseif ($until || !in_array($type, $this->ignored, TRUE)) {
225: return $res;
226: }
227: $pos += $prev ? -1 : 1;
228: } while (TRUE);
229: }
230:
231: }
232: