1: <?php
2:
3: namespace Deimos\Flow\Traits;
4:
5: use Deimos\Flow\Configure;
6: use Deimos\Flow\Flow;
7: use Deimos\Flow\FlowFunction;
8: use Deimos\Flow\Lexer;
9: use Deimos\Flow\LexerConst;
10:
11: trait Tokenizer
12: {
13:
14: 15: 16:
17: protected $brace;
18:
19: 20: 21:
22: protected $comment;
23:
24: 25: 26:
27: protected $commandIterator;
28:
29: 30: 31:
32: protected $commands;
33:
34: 35: 36: 37: 38:
39: protected function parseText($source)
40: {
41: 42: 43:
44: $tokens = token_get_all('<?php ' . $source);
45: array_shift($tokens);
46:
47: return $tokens;
48: }
49:
50: 51: 52: 53: 54: 55: 56: 57: 58:
59: public function commandLexer(Flow $flow, Configure $configure, $source)
60: {
61: $source = preg_replace('~([\s\t]+)~', ' ', $source);
62:
63: $commandParser = $this->parseText($source);
64:
65: return $this->commandParser($flow, $configure, $commandParser);
66: }
67:
68: 69: 70: 71: 72:
73: protected function value($data)
74: {
75: if (is_array($data))
76: {
77: return $data[1];
78: }
79:
80: return $data;
81: }
82:
83: 84: 85: 86: 87:
88: protected function commandRef(array $commands)
89: {
90: $command = array_shift($commands);
91: $command = $this->value($command);
92:
93: if (!empty($commands))
94: {
95: if ($command === '/')
96: {
97: $nextCommand = array_shift($commands);
98: $nextCommand = $this->value($nextCommand);
99:
100: $command .= $nextCommand;
101: }
102:
103: $test = $this->value($command[0]);
104:
105: if ($test === ' ')
106: {
107: array_shift($commands);
108: }
109:
110: if ($test === '[')
111: {
112: $command .= $test;
113: $squareBrackets = 1;
114: while ($squareBrackets)
115: {
116: $test = array_shift($commands);
117:
118: switch ($test)
119: {
120: case ']':
121: $squareBrackets--;
122: break;
123:
124: case '[':
125: $squareBrackets++;
126: break;
127: }
128:
129: $command .= $test;
130: }
131: }
132:
133: foreach ($commands as $key => $value)
134: {
135: $commands[$key] = $this->value($value);
136: }
137: }
138:
139: return [$command, $commands];
140: }
141:
142: 143: 144: 145: 146: 147: 148: 149: 150:
151: protected function commandParser(Flow $flow, Configure $configure, array $commands)
152: {
153: $lexer = new Lexer($configure);
154:
155: list ($command, $commands) = $this->commandRef($commands);
156:
157: if (in_array($command{0}, ['$', '\'', '"'], true))
158: {
159: $class = $lexer->get(LexerConst::T_VARIABLE);
160: $commands = array_merge([$command], $commands);
161: }
162: else
163: {
164: $class = $lexer->get($command);
165: }
166:
167: 168: 169:
170: $object = new $class($flow, $configure, $commands);
171:
172: return $object->view();
173: }
174:
175: 176: 177: 178: 179:
180: public function lexer($source)
181: {
182: $this->commands = [];
183: $this->commandIterator = -1;
184: $this->brace = 0;
185: $this->comment = 0;
186:
187: foreach ($this->parseText($source) as $token)
188: {
189: $id = null;
190: $text = $token;
191: if (!is_string($token))
192: {
193: list ($id, $text) = $token;
194: }
195:
196: if ($this->comment)
197: {
198: if ($text === '*')
199: {
200: $this->comment--;
201: }
202: continue;
203: }
204:
205: if ($text === '}')
206: {
207: $this->brace--;
208: }
209:
210: if ($this->brace)
211: {
212: if ($text{0} === '*')
213: {
214: $this->comment++;
215: $this->brace--;
216: continue;
217: }
218:
219: if (!isset($this->commands[$this->commandIterator]))
220: {
221: $this->commands[$this->commandIterator] = '';
222: }
223:
224: $this->commands[$this->commandIterator] .= $text;
225: }
226:
227: if ($text === '{')
228: {
229: $this->brace++;
230: $this->commandIterator++;
231: }
232:
233: }
234:
235: return $this->commands;
236: }
237:
238: }