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