Passed
Push — master ( e343f8...43624f )
by Edward
05:18
created

TranslationScheme   F

Complexity

Total Complexity 177

Size/Duplication

Total Lines 1137
Duplicated Lines 0 %

Test Coverage

Coverage 98.1%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 750
dl 0
loc 1137
ccs 724
cts 738
cp 0.981
rs 1.85
c 4
b 0
f 0
wmc 177

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
F applyProductionActions() 0 569 99
A applyTokenActions() 0 15 5
F applySymbolActions() 0 526 72

How to fix   Complexity   

Complex Class

Complex classes like TranslationScheme often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TranslationScheme, and based on these observations, apply Extract Interface, too.

1
<?php /** @noinspection PhpDuplicateSwitchCaseBodyInspection */
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Path\Parser;
5
6
use function array_merge;
7
use Remorhaz\JSON\Path\Query\AstBuilderInterface;
8
use Remorhaz\UniLex\Grammar\SDD\TranslationSchemeInterface;
9
use Remorhaz\UniLex\Lexer\Token;
10
use Remorhaz\UniLex\Parser\Production;
11
use Remorhaz\UniLex\Parser\Symbol;
12
13
class TranslationScheme implements TranslationSchemeInterface
14
{
15
16
    private $queryAstBuilder;
17
18 110
    public function __construct(AstBuilderInterface $queryAstBuilder)
19
    {
20 110
        $this->queryAstBuilder = $queryAstBuilder;
21 110
    }
22
23
    /**
24
     * @param Symbol $symbol
25
     * @param Token $token
26
     */
27 110
    public function applyTokenActions(Symbol $symbol, Token $token): void
28
    {
29 110
        $s = $symbol->getShortcut();
30 110
        $t = $token->getShortcut();
31 110
        switch ($symbol->getSymbolId()) {
32 110
            case SymbolType::T_NAME:
33 110
            case SymbolType::T_UNESCAPED:
34 110
            case SymbolType::T_REGEXP_MOD:
35 66
                $s['s.text'] = $t['text'];
36 66
                break;
37
38 110
            case SymbolType::T_INT:
39 34
                $s['s.text'] = $t['text'];
40 34
                $s['s.int'] = intval($t['text']);
41 34
                break;
42
        }
43 110
    }
44
45
    /**
46
     * @param Production $production
47
     */
48 110
    public function applyProductionActions(Production $production): void
49
    {
50 110
        $header = $production->getHeaderShortcut();
51 110
        $symbols = $production->getSymbolListShortcut();
52 110
        $hash = "{$production->getHeader()->getSymbolId()}.{$production->getIndex()}";
53
        switch ($hash) {
54 110
            case SymbolType::NT_ROOT . '.0':
55
                // [ 0:NT_JSON_PATH, 1:T_EOI ]
56
                $this
57 110
                    ->queryAstBuilder
58 110
                    ->setOutput(
59 110
                        $symbols[0]['s.value_list_id'],
60 110
                        $symbols[0]['s.is_definite'],
61 110
                        $symbols[0]['s.is_addressable']
62
                    );
63 110
                break;
64
65 110
            case SymbolType::NT_JSON_PATH . '.0':
66
                // [ 0:NT_PATH ]
67 110
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
68 110
                $header['s.is_definite'] = $symbols[0]['s.is_definite'];
69 110
                $header['s.is_addressable'] = $symbols[0]['s.is_addressable'];
70 110
                break;
71
72 110
            case SymbolType::NT_PATH . '.0':
73
                // [ 0:T_ROOT_ABSOLUTE, 1:NT_FILTER_LIST ]
74 110
            case SymbolType::NT_PATH . '.1':
75
                // [ 0:T_ROOT_RELATIVE, 1:NT_FILTER_LIST ]
76 110
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
77 110
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
78 110
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
79 110
                break;
80
81 110
            case SymbolType::NT_DOT_FILTER_NEXT . '.0':
82
                // [ 0:T_LEFT_BRACKET, 1:T_RIGHT_BRACKET ]
83 8
                $header['s.value_list_id'] = $this
84 8
                    ->queryAstBuilder
85 8
                    ->aggregate(
86 8
                        $header['i.filter_name'],
87 8
                        $header['i.value_list_id']
88
                    );
89 8
                $header['s.is_definite'] = $header['i.is_definite'];
90 8
                $header['s.is_addressable'] = false;
91 8
                break;
92
93 110
            case SymbolType::NT_DOT_FILTER_NEXT . '.1':
94
                // [ 0:NT_FILTER_LIST ]
95 52
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
96 52
                $header['s.is_definite'] = $symbols[0]['s.is_definite'];
97 52
                $header['s.is_addressable'] = $symbols[0]['s.is_addressable'];
98 52
                break;
99
100 110
            case SymbolType::NT_DOT_FILTER . '.0':
101
                // [ 0:T_NAME, 1:NT_DOT_FILTER_NEXT ]
102 110
            case SymbolType::NT_DOT_FILTER . '.1':
103
                // [ 0:T_STAR, 1:NT_FILTER_LIST ]
104 110
            case SymbolType::NT_DOT_FILTER . '.2':
105
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
106 110
            case SymbolType::NT_DOT_FILTER . '.3':
107
                // [ 0:NT_STRING, 1:NT_FILTER_LIST ]
108 65
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
109 65
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
110 65
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
111 65
                break;
112
113 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.0':
114
                // [ 0:T_NAME, 1:NT_FILTER_LIST ]
115 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.1':
116
                // [ 0:T_STAR, 1:NT_FILTER_LIST ]
117 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.2':
118
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
119 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.3':
120
                // [ 0:NT_STRING, 1:NT_FILTER_LIST ]
121 16
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
122 16
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
123 16
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
124 16
                break;
125
126 110
            case SymbolType::NT_FILTER_LIST . '.0':
127
                // [ 0:T_DOT, 1:NT_DOT_FILTER ]
128 65
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
129 65
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
130 65
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
131 65
                break;
132
133 110
            case SymbolType::NT_FILTER_LIST . '.1':
134
                // [ 0:T_DOUBLE_DOT, 1:NT_DOUBLE_DOT_FILTER ]
135 16
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
136 16
                $header['s.is_definite'] = false;
137 16
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
138 16
                break;
139
140 110
            case SymbolType::NT_FILTER_LIST . '.2':
141
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
142 81
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
143 81
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
144 81
                $header['s.is_addressable'] = $symbols[1]['s.is_addressable'];
145 81
                break;
146
147 110
            case SymbolType::NT_FILTER_LIST . '.3':
148
                // [ ]
149 103
                $header['s.value_list_id'] = $header['i.value_list_id'];
150 103
                $header['s.is_definite'] = $header['i.is_definite'];
151 103
                $header['s.is_addressable'] = $header['i.is_addressable'];
152 103
                break;
153
154 105
            case SymbolType::NT_PREDICATE . '.0':
155
                // [
156
                //   0:T_LEFT_SQUARE_BRACKET,
157
                //   1:NT_WS_OPT,
158
                //   2:NT_BRACKET_FILTER,
159
                //   3:T_RIGHT_SQUARE_BRACKET,
160
                // ]
161 83
                $header['s.value_list_id'] = $symbols[2]['s.value_list_id'];
162 83
                $header['s.is_definite'] = $symbols[2]['s.is_definite'];
163 83
                $header['s.is_addressable'] = $header['i.is_addressable'];
164 83
                break;
165
166 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.0':
167
                // [ 0:NT_EXPR_GROUP, 1:NT_WS_OPT ]
168 4
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
169 4
                break;
170
171 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.1':
172
                // [ 0:NT_PATH, 1:NT_WS_OPT ]
173 44
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
174 44
                break;
175
176 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.2':
177
                // [ 0:NT_INT, 1:NT_WS_OPT ]
178 15
                $header['s.value_list_id'] = $this
179 15
                    ->queryAstBuilder
180 15
                    ->createScalar($header['i.value_list_id'], $symbols[0]['s.int']);
181 15
                break;
182
183 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.3':
184
                // [ 0:NT_ARRAY, 1:NT_WS_OPT ]
185 2
                $header['s.value_list_id'] = $this
186 2
                    ->queryAstBuilder
187 2
                    ->createLiteralArray($header['i.value_list_id'], $symbols[0]['s.array_id']);
188 2
                break;
189
190 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.4':
191
                // [ 0:T_NULL, 1:NT_WS_OPT ]
192 1
                $header['s.value_list_id'] = $this
193 1
                    ->queryAstBuilder
194 1
                    ->createScalar($header['i.value_list_id'], null);
195 1
                break;
196
197 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.5':
198
                // [ 0:T_TRUE, 1:NT_WS_OPT ]
199 6
                $header['s.value_list_id'] = $this
200 6
                    ->queryAstBuilder
201 6
                    ->createScalar($header['i.value_list_id'], true);
202 6
                break;
203
204 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.6':
205
                // [ 0:T_FALSE, 1:NT_WS_OPT ]
206 5
                $header['s.value_list_id'] = $this
207 5
                    ->queryAstBuilder
208 5
                    ->createScalar($header['i.value_list_id'], false);
209 5
                break;
210
211 105
            case SymbolType::NT_EXPR_ARG_SCALAR . '.7':
212
                // [ 0:NT_STRING, 1:NT_WS_OPT ]
213 7
                $header['s.value_list_id'] = $this
214 7
                    ->queryAstBuilder
215 7
                    ->createScalar($header['i.value_list_id'], $symbols[0]['s.text']);
216 7
                break;
217
218 105
            case SymbolType::NT_INT . '.0':
219
                // [ 0:T_HYPHEN, 1:T_INT ]
220 4
                $header['s.int'] = -$symbols[1]['s.int'];
221 4
                break;
222
223 105
            case SymbolType::NT_INT . '.1':
224
                // [ 0:T_INT ]
225 23
                $header['s.int'] = $symbols[0]['s.int'];
226 23
                break;
227
228 105
            case SymbolType::NT_INT_NEXT . '.0':
229
                // [ 0:NT_WS_OPT, 1:NT_INT_NEXT_LIST ]
230 6
                $header['s.matcher_id'] = $this
231 6
                    ->queryAstBuilder
232 6
                    ->matchElementStrictly(...$symbols[1]['s.int_list']);
233 6
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
234 6
                break;
235
236 105
            case SymbolType::NT_INT_NEXT . '.1':
237
                // [ 0:NT_INT_SLICE ]
238 6
                $header['s.matcher_id'] = $symbols[0]['s.matcher_id'];
239 6
                $header['s.is_definite'] = false;
240 6
                break;
241
242 105
            case SymbolType::NT_INT_SLICE_OPT . '.0':
243
                // [ 0:NT_INT_SLICE ]
244 1
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
245 1
                $header['s.matcher_id'] = $symbols[0]['s.matcher_id'];
246 1
                break;
247
248 105
            case SymbolType::NT_INT_SLICE_OPT . '.1':
249
                // [ ]
250 1
                $header['s.value_list_id'] = $header['i.value_list_id'];
251 1
                $header['s.matcher_id'] = $this
252 1
                    ->queryAstBuilder
253 1
                    ->matchElementSlice(
254 1
                        $header['i.int_start'],
255 1
                        null,
256 1
                        null,
257
                    );
258 1
                break;
259
260 105
            case SymbolType::NT_INT_SLICE . '.0':
261
                // [ 0:T_COLON, 1:NT_INT_OPT, 2:NT_INT_SLICE_STEP, 3:NT_WS_OPT ]
262 12
                $header['s.value_list_id'] = $header['i.value_list_id'];
263 12
                $header['s.matcher_id'] = $this
264 12
                    ->queryAstBuilder
265 12
                    ->matchElementSlice(
266 12
                        $header['i.int_start'],
267 12
                        $symbols[1]['s.int'],
268 12
                        $symbols[2]['s.int'],
269
                    );
270 12
                break;
271
272 105
            case SymbolType::NT_INT_OPT . '.0':
273
                // [ 0:NT_INT ]
274 9
                $header['s.int'] = $symbols[0]['s.int'];
275 9
                break;
276
277 105
            case SymbolType::NT_INT_OPT . '.1':
278 7
                $header['s.int'] = null;
279 7
                break;
280
281 105
            case SymbolType::NT_INT_SLICE_STEP . '.0':
282
                // [ 0:T_COLON, 1:NT_INT_OPT ]
283 8
                $header['s.int'] = $symbols[1]['s.int'];
284 8
                break;
285
286 105
            case SymbolType::NT_INT_SLICE_STEP . '.1':
287
                // [ ]
288 4
                $header['s.int'] = null;
289 4
                break;
290
291 105
            case SymbolType::NT_INT_NEXT_LIST . '.0':
292
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_INT, 3:NT_WS_OPT, 4:NT_INT_NEXT_LIST ]
293 3
                $header['s.int_list'] = $symbols[4]['s.int_list'];
294 3
                $header['s.is_definite'] = false;
295 3
                break;
296
297 105
            case SymbolType::NT_INT_NEXT_LIST . '.1':
298
                // [ ]
299 6
                $header['s.int_list'] = $header['i.int_list'];
300 6
                $header['s.is_definite'] = $header['i.is_definite'];
301 6
                break;
302
303 105
            case SymbolType::NT_STRING_NEXT . '.0':
304
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_PROPERTY, 3:NT_WS_OPT, 4:NT_STRING_NEXT ]
305 2
                $header['s.text_list'] = $symbols[4]['s.text_list'];
306 2
                $header['s.is_definite'] = false;
307 2
                break;
308
309 105
            case SymbolType::NT_STRING_NEXT . '.1':
310
                // [ ]
311 5
                $header['s.text_list'] = $header['i.text_list'];
312 5
                $header['s.is_definite'] = $header['i.is_definite'];
313 5
                break;
314
315 105
            case SymbolType::NT_STRING_LIST . '.0':
316
                // [ 0:NT_PROPERTY, 1:NT_WS_OPT, 2:NT_STRING_NEXT ]
317 5
                $header['s.text_list'] = $symbols[2]['s.text_list'];
318 5
                $header['s.is_definite'] = $symbols[2]['s.is_definite'];
319 5
                break;
320
321 105
            case SymbolType::NT_PROPERTY . '.0':
322
                // [ 0:NT_STRING ]
323 105
            case SymbolType::NT_PROPERTY . '.1':
324
                // [ 0:NT_NAME ]
325 5
                $header['s.text'] = $symbols[0]['s.text'];
326 5
                break;
327
328 105
            case SymbolType::NT_STRING . '.0':
329
                // [ 0:T_SINGLE_QUOTE, 1:NT_STRING_CONTENT, 2:T_SINGLE_QUOTE ]
330 105
            case SymbolType::NT_STRING . '.1':
331
                // [ 0:T_DOUBLE_QUOTE, 1:NT_STRING_CONTENT, 2:T_DOUBLE_QUOTE ]
332 13
                $header['s.text'] = $symbols[1]['s.text'];
333 13
                break;
334
335 105
            case SymbolType::NT_STRING_CONTENT . '.0':
336
                // [ 0:T_UNESCAPED, 1:NT_STRING_CONTENT ]
337 13
                $header['s.text'] = $symbols[1]['s.text'];
338 13
                break;
339
340 105
            case SymbolType::NT_STRING_CONTENT . '.1':
341
                // [ 0:T_BACKSLASH, 1:NT_ESCAPED, 2:NT_STRING_CONTENT ]
342
                $header['s.text'] = $symbols[2]['s.text'];
343
                break;
344
345 105
            case SymbolType::NT_STRING_CONTENT . '.2':
346
                // [ ]
347 13
                $header['s.text'] = $header['i.text'];
348 13
                break;
349
350 103
            case SymbolType::NT_ESCAPED . '.0':
351
                // [ 0:T_BACKSLASH ]
352
                $header['s.text'] = '\\';
353
                break;
354
355 103
            case SymbolType::NT_ESCAPED . '.1':
356
                // [ 0:T_SINGLE_QUOTE ]
357
                $header['s.text'] = '\'';
358
                break;
359
360 103
            case SymbolType::NT_ESCAPED . '.2':
361
                // [ 0:T_DOUBLE_QUOTE ]
362
                $header['s.text'] = '"';
363
                break;
364
365 103
            case SymbolType::NT_ESCAPED . '.3':
366
                // [ 0:T_UNESCAPED ]
367
                $header['s.text'] = $symbols[0]['s.text'];
368
                break;
369
370 103
            case SymbolType::NT_BRACKET_FILTER . '.0':
371
                // [ 0:T_STAR, 1:NT_WS_OPT ]
372 2
                $header['s.value_list_id'] = $this
373 2
                    ->queryAstBuilder
374 2
                    ->fetchChildren(
375 2
                        $header['i.value_list_id'],
376 2
                        $this->queryAstBuilder->matchAnyChild()
377
                    );
378 2
                $header['s.is_definite'] = false;
379 2
                break;
380 103
            case SymbolType::NT_BRACKET_FILTER . '.1':
381
                // [ 0:NT_STRING_LIST ]
382 5
                $header['s.value_list_id'] = $this
383 5
                    ->queryAstBuilder
384 5
                    ->fetchChildren(
385 5
                        $header['i.value_list_id'],
386
                        $this
387 5
                            ->queryAstBuilder
388 5
                            ->matchPropertyStrictly(...$symbols[0]['s.text_list'])
389
                    );
390 5
                $header['s.is_definite'] = $symbols[0]['s.is_definite'];
391 5
                break;
392
393 103
            case SymbolType::NT_BRACKET_FILTER . '.2':
394
                // [ 0:T_INT, 1:NT_INT_NEXT ]
395 12
                $header['s.value_list_id'] = $this
396 12
                    ->queryAstBuilder
397 12
                    ->fetchChildren($header['i.value_list_id'], $symbols[1]['s.matcher_id']);
398 12
                $header['s.is_definite'] = $symbols[1]['s.is_definite'];
399 12
                break;
400
401 103
            case SymbolType::NT_BRACKET_FILTER . '.3':
402
                // [ 0:T_HYPHEN, 1:T_INT, 2:NT_INT_SLICE_OPT ]
403 2
                $header['s.value_list_id'] = $this
404 2
                    ->queryAstBuilder
405 2
                    ->fetchChildren($symbols[2]['s.value_list_id'], $symbols[2]['s.matcher_id']);
406 2
                $header['s.is_definite'] = false;
407 2
                break;
408
409 103
            case SymbolType::NT_BRACKET_FILTER . '.4':
410
                // [ 0:NT_INT_SLICE ]
411 5
                $header['s.value_list_id'] = $this
412 5
                    ->queryAstBuilder
413 5
                    ->fetchChildren($symbols[0]['s.value_list_id'], $symbols[0]['s.matcher_id']);
414 5
                $header['s.is_definite'] = false;
415 5
                break;
416
417 103
            case SymbolType::NT_BRACKET_FILTER . '.5':
418
                // [ 0:T_QUESTION, 1:T_LEFT_BRACKET, 2:NT_WS_OPT, 3:NT_EXPR, 4:T_RIGHT_BRACKET ]
419 57
                $header['s.value_list_id'] = $this
420 57
                    ->queryAstBuilder
421 57
                    ->filter(
422 57
                        $symbols[3]['i.context_value_list_id'],
423
                        $this
424 57
                            ->queryAstBuilder
425 57
                            ->joinFilterResults(
426
                                $this
427 57
                                    ->queryAstBuilder
428 57
                                    ->evaluate($symbols[3]['i.value_list_id'], $symbols[3]['s.value_list_id']),
429 57
                                $symbols[3]['i.context_value_list_id'],
430
                            )
431
                    );
432 57
                $header['s.is_definite'] = false;
433 57
                break;
434
435 103
            case SymbolType::NT_EXPR_ARG_COMP . '.0':
436
                // [ 0:T_OP_NOT, 1:NT_EXPR_ARG_SCALAR ]
437 1
                $header['s.value_list_id'] = $this
438 1
                    ->queryAstBuilder
439 1
                    ->evaluateLogicalNot(
440
                        $this
441 1
                            ->queryAstBuilder
442 1
                            ->evaluate($header['i.value_list_id'], $symbols[1]['s.value_list_id'])
443
                    );
444 1
                break;
445
446 103
            case SymbolType::NT_EXPR_ARG_COMP . '.1':
447
                // [ 0:NT_EXPR_ARG_SCALAR ]
448 56
                $header['s.value_list_id'] = $symbols[0]['s.value_list_id'];
449 56
                break;
450
451 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.0':
452
                // [ 0:T_OP_EQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
453 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.1':
454
                // [ 0:T_OP_NEQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
455 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.2':
456
                // [ 0:T_OP_L, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
457 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.3':
458
                // [ 0:T_OP_LE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
459 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.4':
460
                // [ 0:T_OP_G, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
461 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.5':
462
                // [ 0:T_OP_GE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
463 34
                $header['s.value_list_id'] = $symbols[3]['s.value_list_id'];
464 34
                break;
465
466 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.6':
467
                // [ 0:T_OP_REGEX, 1:NT_WS_OPT, 2:NT_REGEXP ],
468 5
                $header['s.value_list_id'] = $this
469 5
                    ->queryAstBuilder
470 5
                    ->calculateIsRegExp($symbols[2]['s.text'], $header['i.left_value_list_id']);
471 5
                break;
472
473 103
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.7':
474
                // [ ]
475 52
                $header['s.value_list_id'] = $header['i.left_value_list_id'];
476 52
                break;
477
478 103
            case SymbolType::NT_EXPR_ARG_AND . '.0':
479
                // [ 0:NT_EXPR_ARG_COMP, 1:NT_EXPR_ARG_COMP_TAIL ]
480 57
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
481 57
                break;
482
483 103
            case SymbolType::NT_EXPR_ARG_AND_TAIL . '.0':
484
                // [ 0:T_OP_AND, 1:NT_WS_OPT, 2:NT_EXPR_ARG_AND, 3:NT_EXPR_ARG_AND_TAIL ]
485 5
                $header['s.value_list_id'] = $symbols[3]['s.value_list_id'];
486 5
                break;
487
488 103
            case SymbolType::NT_EXPR_ARG_AND_TAIL . '.1':
489
                // []
490 57
                $header['s.value_list_id'] = $header['i.left_value_list_id'];
491 57
                break;
492
493 103
            case SymbolType::NT_EXPR_ARG_OR . '.0':
494
                // [ 0:NT_EXPR_ARG_AND, 1:NT_EXPR_ARG_AND_TAIL ]
495 57
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
496 57
                break;
497
498 103
            case SymbolType::NT_EXPR_ARG_OR_TAIL . '.0':
499
                // [ 0:T_OP_OR, 1:NT_WS_OPT, 2:NT_EXPR_ARG_OR, 3:NT_EXPR_ARG_OR_TAIL ]
500 5
                $header['s.value_list_id'] = $symbols[3]['s.value_list_id'];
501 5
                break;
502
503 103
            case SymbolType::NT_EXPR_ARG_OR_TAIL . '.1':
504
                // [ ]
505 57
                $header['s.value_list_id'] = $header['i.left_value_list_id'];
506 57
                break;
507
508 103
            case SymbolType::NT_EXPR . '.0':
509
                // [ 0:NT_EXPR_ARG_OR, 1:NT_EXPR_ARG_OR_TAIL ]
510 57
                $header['s.value_list_id'] = $symbols[1]['s.value_list_id'];
511 57
                break;
512
513 103
            case SymbolType::NT_EXPR_GROUP . '.0':
514
                // [ 0:T_LEFT_BRACKET, 1:NT_WS_OPT, 2:NT_EXPR, 3:T_RIGHT_BRACKET]
515 4
                $header['s.value_list_id'] = $symbols[2]['s.value_list_id'];
516 4
                break;
517
518 103
            case SymbolType::NT_ARRAY . '.0':
519
                // [ 0:T_LEFT_SQUARE_BRACKET, 1:NT_WS_OPT, 2:NT_ARRAY_CONTENT, 3:T_RIGHT_SQUARE_BRACKET ]
520 2
                $header['s.array_id'] = $symbols[2]['s.array_id'];
521 2
                break;
522
523 103
            case SymbolType::NT_ARRAY_CONTENT . '.0':
524
                // [ 0:NT_EXPR, 1:NT_ARRAY_CONTENT_TAIL ]
525 2
                $header['s.array_id'] = $symbols[1]['s.array_id'];
526 2
                break;
527
528 103
            case SymbolType::NT_ARRAY_CONTENT . '.1':
529
                // []
530
                $header['s.array_id'] = $header['i.array_id'];
531
                break;
532
533 103
            case SymbolType::NT_ARRAY_CONTENT_TAIL . '.0':
534
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_ARRAY_CONTENT ]
535 1
                $header['s.array_id'] = $symbols[2]['s.array_id'];
536 1
                break;
537
538 103
            case SymbolType::NT_ARRAY_CONTENT_TAIL . '.1':
539
                // []
540 2
                $header['s.array_id'] = $header['i.array_id'];
541 2
                break;
542
543 103
            case SymbolType::NT_REGEXP . '.0':
544
                // [ 0:T_SLASH, 1:NT_REGEXP_STRING, 2:T_REGEXP_MOD ]
545 5
                $header['s.text'] = $symbols[1]['s.text'] . $symbols[2]['s.text'];
546 5
                break;
547
548 103
            case SymbolType::NT_REGEXP_STRING . '.0':
549
                // [ 0:T_UNESCAPED, 1:NT_REGEXP_STRING ]
550 5
                $header['s.text'] = $symbols[1]['s.text'];
551 5
                break;
552
553 103
            case SymbolType::NT_REGEXP_STRING . '.1':
554
                // [ 0:T_BACKSLASH, 1:NT_REGEXP_ESCAPED, 2:NT_REGEXP_STRING ]
555 3
                $header['s.text'] = $symbols[2]['s.text'];
556 3
                break;
557
558 103
            case SymbolType::NT_REGEXP_STRING . '.2':
559
                // [ ]
560 5
                $header['s.text'] = $header['i.text'];
561 5
                break;
562
563 103
            case SymbolType::NT_REGEXP_ESCAPED . '.0':
564
                // [ 0:T_SLASH ]
565 1
                $header['s.text'] = '\\/';
566 1
                break;
567
568 103
            case SymbolType::NT_REGEXP_ESCAPED . '.1':
569
                // [ 0:T_BACKSLASH ]
570 1
                $header['s.text'] = '\\\\';
571 1
                break;
572
573 103
            case SymbolType::NT_REGEXP_ESCAPED . '.2':
574
                // [ 0:T_UNESCAPED ]
575 1
                $header['s.text'] = $symbols[0]['s.text'];
576 1
                break;
577
578 103
            case SymbolType::NT_NAME . '.0':
579
                // [ 0:T_NAME ]
580 58
                $header['s.text'] = $symbols[0]['s.text'];
581 58
                break;
582
583 103
            case SymbolType::NT_NAME . '.1':
584
                // [ 0:T_NULL ]
585 2
                $header['s.text'] = 'null';
586 2
                break;
587
588 103
            case SymbolType::NT_NAME . '.2':
589
                // [ 0:T_TRUE ]
590 2
                $header['s.text'] = 'true';
591 2
                break;
592
593 103
            case SymbolType::NT_NAME . '.3':
594
                // [ 0:T_FALSE ]
595 2
                $header['s.text'] = 'false';
596 2
                break;
597
598 103
            case SymbolType::NT_DOT_NAME_TAIL . '.0':
599
                // [ 0:NT_NAME ]
600 1
                $header['s.text'] = $header['i.text'] . $symbols[0]['s.text'];
601 1
                break;
602
603 103
            case SymbolType::NT_DOT_NAME_TAIL . '.1':
604
                // [ ]
605 1
                $header['s.text'] = $header['i.text'];
606 1
                break;
607
608 103
            case SymbolType::NT_DOT_NAME . '.0':
609
                // [ 0:NT_NAME ]
610 61
                $header['s.text'] = $symbols[0]['s.text'];
611 61
                break;
612
613 85
            case SymbolType::NT_DOT_NAME . '.1':
614
                // [ 0:NT_INT, 1:NT_DOT_NAME_TAIL ]
615 2
                $header['s.text'] = $symbols[1]['s.text'];
616 2
                break;
617
        }
618 110
    }
619
620
    /**
621
     * @param Production $production
622
     * @param int $symbolIndex
623
     */
624 110
    public function applySymbolActions(Production $production, int $symbolIndex): void
625
    {
626 110
        $header = $production->getHeaderShortcut();
627 110
        $symbols = $production->getSymbolListShortcut();
628 110
        $hash = "{$production->getHeader()->getSymbolId()}.{$production->getIndex()}.{$symbolIndex}";
629
        switch ($hash) {
630 110
            case SymbolType::NT_JSON_PATH . '.0.0':
631
                // [ 0:NT_PATH ]
632 110
                $symbols[0]['i.is_definite'] = true;
633 110
                break;
634
635 110
            case SymbolType::NT_PATH . '.0.1':
636
                // [ 0:T_ROOT_ABSOLUTE, 1:NT_FILTER_LIST ]
637 110
                $symbols[1]['i.value_list_id'] = $this
638 110
                    ->queryAstBuilder
639 110
                    ->getInput();
640 110
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
641 110
                $symbols[1]['i.is_addressable'] = true;
642 110
                break;
643
644 110
            case SymbolType::NT_PATH . '.1.1':
645
                // [ 0:T_ROOT_RELATIVE, 1:NT_FILTER_LIST ]
646 43
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
647 43
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
648 43
                $symbols[1]['i.is_addressable'] = true;
649 43
                break;
650
651 110
            case SymbolType::NT_BRACKET_FILTER . '.1.0':
652
                // [ 0:NT_STRING_LIST ]
653 5
                $symbols[0]['i.is_definite'] = $header['i.is_definite'];
654 5
                break;
655
656 110
            case SymbolType::NT_BRACKET_FILTER . '.2.1':
657
                // [ 0:NT_INT, 1:NT_INT_NEXT ]
658 12
                $symbols[1]['i.int'] = $symbols[0]['s.int'];
659 12
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
660 12
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
661 12
                break;
662
663 110
            case SymbolType::NT_BRACKET_FILTER . '.3.2':
664
                // [ 0:T_HYPHEN, 1:T_INT, 2:NT_INT_SLICE_OPT ]
665 2
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
666 2
                $symbols[2]['i.int_start'] = -$symbols[1]['s.int'];
667 2
                break;
668
669 110
            case SymbolType::NT_BRACKET_FILTER . '.4.0':
670
                // [ 0:NT_INT_SLICE ]
671 5
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
672 5
                $symbols[0]['i.int_start'] = null;
673 5
                break;
674
675 110
            case SymbolType::NT_BRACKET_FILTER . '.5.3':
676
                // [ 0:T_QUESTION, 1:T_LEFT_BRACKET, 2:NT_WS_OPT, 3:NT_EXPR, 4:T_RIGHT_BRACKET ]
677 57
                $symbols[3]['i.context_value_list_id'] = $this
678 57
                    ->queryAstBuilder
679 57
                    ->fetchFilterContext($header['i.value_list_id']);
680 57
                $symbols[3]['i.value_list_id'] = $this
681 57
                    ->queryAstBuilder
682 57
                    ->splitFilterContext($symbols[3]['i.context_value_list_id']);
683 57
                break;
684
685 110
            case SymbolType::NT_DOT_NAME . '.1.1':
686
                // [ 0:T_INT, 1:NT_DOT_NAME_TAIL ]
687 2
                $symbols[1]['i.text'] = $symbols[0]['s.text'];
688 2
                break;
689
690 110
            case SymbolType::NT_EXPR . '.0.0':
691
                // [ 0:NT_EXPR_ARG_OR, 1:NT_EXPR_ARG_OR_TAIL ]
692 57
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
693 57
                break;
694
695 110
            case SymbolType::NT_EXPR . '.0.1':
696
                // [ 0:NT_EXPR_ARG_OR, 1:NT_EXPR_ARG_OR_TAIL ]
697 57
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
698 57
                $symbols[1]['i.left_value_list_id'] = $symbols[0]['s.value_list_id'];
699 57
                break;
700
701 110
            case SymbolType::NT_EXPR_ARG_OR . '.0.0':
702
                // [ 0:NT_EXPR_ARG_AND, 1:NT_EXPR_ARG_AND_TAIL ]
703 57
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
704 57
                break;
705
706 110
            case SymbolType::NT_EXPR_ARG_OR . '.0.1':
707
                // [ 0:NT_EXPR_ARG_AND, 1:NT_EXPR_ARG_AND_TAIL ]
708 57
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
709 57
                $symbols[1]['i.left_value_list_id'] = $symbols[0]['s.value_list_id'];
710 57
                break;
711
712 110
            case SymbolType::NT_EXPR_ARG_OR_TAIL . '.0.2':
713
                // [ 0:T_OP_OR, 1:NT_WS_OPT, 2:NT_EXPR_ARG_OR, 3:NT_EXPR_ARG_OR_TAIL ]
714 5
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
715 5
                break;
716
717 110
            case SymbolType::NT_EXPR_ARG_OR_TAIL . '.0.3':
718
                // [ 0:T_OP_OR, 1:NT_WS_OPT, 2:NT_EXPR_ARG_OR, 3:NT_EXPR_ARG_OR_TAIL ]
719 5
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
720 5
                $symbols[3]['i.left_value_list_id'] = $this
721 5
                    ->queryAstBuilder
722 5
                    ->evaluateLogicalOr(
723
                        $this
724 5
                            ->queryAstBuilder
725 5
                            ->evaluate(
726 5
                                $header['i.value_list_id'],
727 5
                                $header['i.left_value_list_id']
728
                            ),
729
                        $this
730 5
                            ->queryAstBuilder
731 5
                            ->evaluate(
732 5
                                $header['i.value_list_id'],
733 5
                                $symbols[2]['s.value_list_id']
734
                            )
735
                    );
736 5
                break;
737
738 110
            case SymbolType::NT_EXPR_ARG_AND . '.0.0':
739
                // [ 0:NT_EXPR_ARG_COMP, 1:NT_EXPR_ARG_COMP_TAIL ]
740 57
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
741 57
                break;
742
743 110
            case SymbolType::NT_EXPR_ARG_AND . '.0.1':
744
                // [ 0:NT_EXPR_ARG_COMP, 1:NT_EXPR_ARG_COMP_TAIL ]
745 57
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
746 57
                $symbols[1]['i.left_value_list_id'] = $symbols[0]['s.value_list_id'];
747 57
                break;
748
749 110
            case SymbolType::NT_EXPR_ARG_AND_TAIL . '.0.2':
750
                // [ 0:T_OP_AND, 1:NT_WS_OPT, 2:NT_EXPR_ARG_AND, 3:NT_EXPR_ARG_AND_TAIL ]
751 5
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
752 5
                break;
753
754 110
            case SymbolType::NT_EXPR_ARG_AND_TAIL . '.0.3':
755
                // [ 0:T_OP_AND, 1:NT_WS_OPT, 2:NT_EXPR_ARG_AND, 3:NT_EXPR_ARG_AND_TAIL ]
756 5
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
757 5
                $symbols[3]['i.left_value_list_id'] = $this
758 5
                    ->queryAstBuilder
759 5
                    ->evaluateLogicalAnd(
760
                        $this
761 5
                            ->queryAstBuilder
762 5
                            ->evaluate(
763 5
                                $header['i.value_list_id'],
764 5
                                $header['i.left_value_list_id']
765
                            ),
766
                        $this
767 5
                            ->queryAstBuilder
768 5
                            ->evaluate(
769 5
                                $header['i.value_list_id'],
770 5
                                $symbols[2]['s.value_list_id']
771
                            )
772
                    );
773 5
                break;
774
775 110
            case SymbolType::NT_EXPR_ARG_COMP . '.0.1':
776
                // [ 0:T_OP_NOT, 1:NT_EXPR_ARG_SCALAR ]
777 1
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
778 1
                break;
779
780 110
            case SymbolType::NT_EXPR_ARG_COMP . '.1.0':
781
                // [ 0:NT_EXPR_ARG_SCALAR ]
782 56
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
783 56
                break;
784
785 110
            case SymbolType::NT_EXPR_ARG_SCALAR . '.0.0':
786
                // [ 0:NT_EXPR_GROUP, 1:NT_WS_OPT ]
787 4
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
788 4
                break;
789
790 110
            case SymbolType::NT_EXPR_ARG_SCALAR . '.1.0':
791
                // [ 0:NT_PATH, 1:NT_WS_OPT ]
792 44
                $symbols[0]['i.is_definite'] = false;
793 44
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
794 44
                break;
795
796 110
            case SymbolType::NT_EXPR_ARG_SCALAR . '.2.0':
797
                // [ 0:NT_INT, 1:NT_WS_OPT ]
798 15
                break;
799
800 110
            case SymbolType::NT_EXPR_ARG_SCALAR . '.3.0':
801
                // [ 0:NT_ARRAY, 1:NT_WS_OPT ]
802 2
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
803 2
                break;
804
805 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.0.2':
806
                // [ 0:T_OP_EQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
807 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.1.2':
808
                // [ 0:T_OP_NEQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
809 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.2.2':
810
                // [ 0:T_OP_L, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
811 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.3.2':
812
                // [ 0:T_OP_LE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
813 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.4.2':
814
                // [ 0:T_OP_G, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
815 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.5.2':
816
                // [ 0:T_OP_GE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
817 34
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
818 34
                break;
819
820 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.0.3':
821
                // [ 0:T_OP_EQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
822 25
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
823 25
                $symbols[3]['i.left_value_list_id'] = $this
824 25
                    ->queryAstBuilder
825 25
                    ->calculateIsEqual(
826 25
                        $header['i.left_value_list_id'],
827 25
                        $symbols[2]['s.value_list_id']
828
                    );
829 25
                break;
830
831 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.1.3':
832
                // [ 0:T_OP_NEQ, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
833 2
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
834 2
                $symbols[3]['i.left_value_list_id'] = $this
835 2
                    ->queryAstBuilder
836 2
                    ->evaluateLogicalNot(
837
                        $this
838 2
                            ->queryAstBuilder
839 2
                            ->calculateIsEqual(
840 2
                                $header['i.left_value_list_id'],
841 2
                                $symbols[2]['s.value_list_id']
842
                            )
843
                    );
844 2
                break;
845
846 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.2.3':
847
                // [ 0:T_OP_L, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
848 2
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
849 2
                $symbols[3]['i.left_value_list_id'] = $this
850 2
                    ->queryAstBuilder
851 2
                    ->calculateIsGreater(
852 2
                        $symbols[2]['s.value_list_id'],
853 2
                        $header['i.left_value_list_id']
854
                    );
855 2
                break;
856
857 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.3.3':
858
                // [ 0:T_OP_LE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
859 1
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
860 1
                $symbols[3]['i.left_value_list_id'] = $this
861 1
                    ->queryAstBuilder
862 1
                    ->evaluateLogicalNot(
863
                        $this
864 1
                            ->queryAstBuilder
865 1
                            ->calculateIsGreater(
866 1
                                $header['i.left_value_list_id'],
867 1
                                $symbols[2]['s.value_list_id']
868
                            )
869
                    );
870 1
                break;
871
872 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.4.3':
873
                // [ 0:T_OP_G, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
874 3
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
875 3
                $symbols[3]['i.left_value_list_id'] = $this
876 3
                    ->queryAstBuilder
877 3
                    ->calculateIsGreater(
878 3
                        $header['i.left_value_list_id'],
879 3
                        $symbols[2]['s.value_list_id']
880
                    );
881 3
                break;
882
883 110
            case SymbolType::NT_EXPR_ARG_COMP_TAIL . '.5.3':
884
                // [ 0:T_OP_GE, 1:NT_WS_OPT, 2:NT_EXPR_ARG_COMP, 3:NT_EXPR_ARG_COMP_TAIL ]
885 1
                $symbols[3]['i.value_list_id'] = $header['i.value_list_id'];
886 1
                $symbols[3]['i.left_value_list_id'] = $this
887 1
                    ->queryAstBuilder
888 1
                    ->evaluateLogicalNot(
889
                        $this
890 1
                            ->queryAstBuilder
891 1
                            ->calculateIsGreater(
892 1
                                $symbols[2]['s.value_list_id'],
893 1
                                $header['i.left_value_list_id']
894
                            )
895
                    );
896 1
                break;
897
898 110
            case SymbolType::NT_EXPR_GROUP . '.0.2':
899
                // [ 0:T_LEFT_BRACKET, 1:NT_WS_OPT, 2:NT_EXPR, 3:T_RIGHT_BRACKET ]
900 4
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
901 4
                break;
902
903 110
            case SymbolType::NT_STRING_LIST . '.0.2':
904
                // [ 0:NT_PROPERTY, 1:NT_WS_OPT, 2:NT_STRING_NEXT ]
905 5
                $symbols[2]['i.text_list'] = [$symbols[0]['s.text']];
906 5
                $symbols[2]['i.is_definite'] = $header['i.is_definite'];
907 5
                break;
908
909 110
            case SymbolType::NT_STRING_NEXT . '.0.4':
910
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_PROPERTY, 3:NT_WS_OPT, 4:NT_STRING_NEXT ]
911 2
                $symbols[4]['i.text_list'] = array_merge($header['i.text_list'], [$symbols[2]['s.text']]);
912 2
                $symbols[4]['i.is_definite'] = false;
913 2
                break;
914
915 110
            case SymbolType::NT_INT_NEXT . '.0.1':
916
                // [ 0:NT_WS_OPT, 1:NT_INT_NEXT_LIST ]
917 6
                $symbols[1]['i.int_list'] = [$header['i.int']];
918 6
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
919 6
                break;
920
921 110
            case SymbolType::NT_INT_NEXT_LIST . '.0.4':
922
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_INT, 3:NT_WS_OPT, 4:NT_INT_NEXT_LIST ]
923 3
                $symbols[4]['i.int_list'] = array_merge($header['i.int_list'], [$symbols[2]['s.int']]);
924 3
                $symbols[4]['i.is_definite'] = false;
925 3
                break;
926
927 110
            case SymbolType::NT_INT_NEXT . '.1.0':
928
                // [ 0:NT_INT_SLICE ]
929 6
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id']; // TODO: probably useless
930 6
                $symbols[0]['i.int_start'] = $header['i.int'];
931 6
                break;
932
933 110
            case SymbolType::NT_INT_SLICE_OPT . '.0.0':
934
                // [ 0:NT_INT_SLICE ]
935 1
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
936 1
                $symbols[0]['i.int_start'] = $header['i.int_start'];
937 1
                break;
938
939 110
            case SymbolType::NT_FILTER_LIST . '.0.1':
940
                // [ 0:T_DOT, 1:NT_DOT_FILTER ]
941 65
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
942 65
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
943 65
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
944 65
                break;
945
946 110
            case SymbolType::NT_FILTER_LIST . '.1.1':
947
                // [ 0:T_DOUBLE_DOT, 1:NT_DOUBLE_DOT_FILTER ]
948 16
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
949 16
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
950 16
                break;
951
952 110
            case SymbolType::NT_FILTER_LIST . '.2.0':
953
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
954 81
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
955 81
                $symbols[0]['i.is_definite'] = $header['i.is_definite'];
956 81
                $symbols[0]['i.is_addressable'] = $header['i.is_addressable'];
957 81
                break;
958
959 110
            case SymbolType::NT_FILTER_LIST . '.2.1':
960
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
961 81
                $symbols[1]['i.value_list_id'] = $symbols[0]['s.value_list_id'];
962 81
                $symbols[1]['i.is_definite'] = $symbols[0]['s.is_definite'];
963 81
                $symbols[1]['i.is_addressable'] = $symbols[0]['s.is_addressable'];
964 81
                break;
965
966 110
            case SymbolType::NT_PREDICATE . '.0.2':
967
                // [
968
                //   0:T_LEFT_SQUARE_BRACKET,
969
                //   1:NT_WS_OPT,
970
                //   2:NT_BRACKET_FILTER,
971
                //   3:T_RIGHT_SQUARE_BRACKET,
972
                // ]
973 83
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
974 83
                $symbols[2]['i.is_definite'] = $header['i.is_definite'];
975 83
                break;
976
977 110
            case SymbolType::NT_DOT_FILTER . '.0.1':
978
                // [ 0:T_NAME, 1:NT_DOT_FILTER_NEXT ]
979 58
                $symbols[1]['i.filter_name'] = $symbols[0]['s.text'];
980 58
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
981 58
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
982 58
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
983 58
                break;
984
985 110
            case SymbolType::NT_DOT_FILTER . '.3.1':
986
                // [ 0:NT_STRING, 1:NT_FILTER_LIST ]
987 1
                $symbols[1]['i.value_list_id'] = $this
988 1
                    ->queryAstBuilder
989 1
                    ->fetchChildren(
990 1
                        $header['i.value_list_id'],
991
                        $this
992 1
                            ->queryAstBuilder
993 1
                            ->matchPropertyStrictly($symbols[0]['s.text'])
994
                    );
995 1
                $symbols[1]['i.is_definite'] = $header['i.is_definite'];
996 1
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
997 1
                break;
998
999 110
            case SymbolType::NT_DOT_FILTER . '.1.1':
1000
                // [ 0:T_STAR, 1:NT_FILTER_LIST ]
1001 5
                $symbols[1]['i.value_list_id'] = $this
1002 5
                    ->queryAstBuilder
1003 5
                    ->fetchChildren(
1004 5
                        $header['i.value_list_id'],
1005 5
                        $this->queryAstBuilder->matchAnyChild()
1006
                    );
1007 5
                $symbols[1]['i.is_definite'] = false;
1008 5
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
1009 5
                break;
1010
1011 110
            case SymbolType::NT_DOT_FILTER . '.2.0':
1012
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
1013 1
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
1014 1
                $symbols[0]['i.is_definite'] = $header['i.is_definite'];
1015 1
                $symbols[0]['i.is_addressable'] = $header['i.is_addressable'];
1016 1
                break;
1017
1018 110
            case SymbolType::NT_DOT_FILTER . '.2.1':
1019
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
1020 1
                $symbols[1]['i.value_list_id'] = $symbols[0]['s.value_list_id'];
1021 1
                $symbols[1]['i.is_definite'] = $symbols[0]['s.is_definite'];
1022 1
                $symbols[1]['i.is_addressable'] = $symbols[0]['s.is_addressable'];
1023 1
                break;
1024
1025 110
            case SymbolType::NT_DOT_FILTER_NEXT . '.1.0':
1026
                // [ 0:NT_FILTER_LIST ]
1027 52
                $symbols[0]['i.value_list_id'] = $this
1028 52
                    ->queryAstBuilder
1029 52
                    ->fetchChildren(
1030 52
                        $header['i.value_list_id'],
1031
                        $this
1032 52
                            ->queryAstBuilder
1033 52
                            ->matchPropertyStrictly($header['i.filter_name'])
1034
                    );
1035 52
                $symbols[0]['i.is_definite'] = $header['i.is_definite'];
1036 52
                $symbols[0]['i.is_addressable'] = $header['i.is_addressable'];
1037 52
                break;
1038
1039 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.0.1':
1040
                // [ 0:T_NAME, 1:NT_FILTER_LIST ]
1041 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.3.1':
1042
                // [ 0:NT_STRING, 1:NT_FILTER_LIST ]
1043 11
                $symbols[1]['i.value_list_id'] = $this
1044 11
                    ->queryAstBuilder
1045 11
                    ->fetchChildrenDeep(
1046 11
                        $header['i.value_list_id'],
1047
                        $this
1048 11
                            ->queryAstBuilder
1049 11
                            ->matchPropertyStrictly($symbols[0]['s.text'])
1050
                    );
1051 11
                $symbols[1]['i.is_definite'] = false;
1052 11
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
1053 11
                break;
1054
1055 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.1.1':
1056
                // [ 0:T_STAR, 1:NT_FILTER_LIST ]
1057 4
                $symbols[1]['i.value_list_id'] = $this
1058 4
                    ->queryAstBuilder
1059 4
                    ->fetchChildrenDeep(
1060 4
                        $header['i.value_list_id'],
1061 4
                        $this->queryAstBuilder->matchAnyChild()
1062
                    );
1063 4
                $symbols[1]['i.is_definite'] = false;
1064 4
                $symbols[1]['i.is_addressable'] = $header['i.is_addressable'];
1065 4
                break;
1066
1067 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.2.0':
1068
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
1069 1
                $symbols[0]['i.value_list_id'] = $this
1070 1
                    ->queryAstBuilder
1071 1
                    ->merge(
1072 1
                        $header['i.value_list_id'],
1073
                        $this
1074 1
                            ->queryAstBuilder
1075 1
                            ->fetchChildrenDeep(
1076 1
                                $header['i.value_list_id'],
1077 1
                                $this->queryAstBuilder->matchAnyChild()
1078
                            ),
1079
                    );
1080 1
                $symbols[0]['i.is_definite'] = false;
1081 1
                $symbols[0]['i.is_addressable'] = $header['i.is_addressable'];
1082 1
                break;
1083
1084 110
            case SymbolType::NT_DOUBLE_DOT_FILTER . '.2.1':
1085
                // [ 0:NT_PREDICATE, 1:NT_FILTER_LIST ]
1086 1
                $symbols[1]['i.value_list_id'] = $symbols[0]['s.value_list_id'];
1087 1
                $symbols[1]['i.is_definite'] = $symbols[0]['s.is_definite'];
1088 1
                $symbols[1]['i.is_addressable'] = $symbols[0]['s.is_addressable'];
1089 1
                break;
1090
1091 110
            case SymbolType::NT_STRING . '.0.1':
1092
                // [ 0:T_SINGLE_QUOTE, 1:NT_STRING_CONTENT, 2:T_SINGLE_QUOTE ]
1093 110
            case SymbolType::NT_STRING . '.1.1':
1094
                // [ 0:T_DOUBLE_QUOTE, 1:NT_STRING_CONTENT, 2:T_DOUBLE_QUOTE ]
1095 13
                $symbols[1]['i.text'] = '';
1096 13
                break;
1097
1098 110
            case SymbolType::NT_STRING_CONTENT . '.0.1':
1099
                // [ 0:T_UNESCAPED, 1:NT_STRING_CONTENT ]
1100 13
                $symbols[1]['i.text'] = $header['i.text'] . $symbols[0]['s.text'];
1101 13
                break;
1102
1103 110
            case SymbolType::NT_STRING_CONTENT . '.1.2':
1104
                // [ 0:T_BACKSLASH, 1:NT_ESCAPED, 2:NT_STRING_CONTENT ]
1105
                $symbols[2]['i.text'] = $header['i.text'] . $symbols[1]['s.text'];
1106
                break;
1107
1108 110
            case SymbolType::NT_ARRAY . '.0.2':
1109
                // [ 0:T_LEFT_SQUARE_BRACKET, 1:NT_WS_OPT, 2:NT_ARRAY_CONTENT, 3:T_RIGHT_SQUARE_BRACKET ]
1110 2
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
1111 2
                $symbols[2]['i.array_id'] = $this
1112 2
                    ->queryAstBuilder
1113 2
                    ->createArray();
1114 2
                break;
1115
1116 110
            case SymbolType::NT_ARRAY_CONTENT . '.0.0':
1117
                // [ 0:NT_EXPR, 1:NT_ARRAY_CONTENT_TAIL ]
1118 2
                $symbols[0]['i.value_list_id'] = $header['i.value_list_id'];
1119 2
                break;
1120
1121 110
            case SymbolType::NT_ARRAY_CONTENT . '.0.1':
1122
                // [ 0:NT_EXPR, 1:NT_ARRAY_CONTENT_TAIL ]
1123 2
                $symbols[1]['i.value_list_id'] = $header['i.value_list_id'];
1124 2
                $symbols[1]['i.array_id'] = $this
1125 2
                    ->queryAstBuilder
1126 2
                    ->appendToArray($header['i.array_id'], $symbols[0]['s.value_list_id']);
1127
1128 2
                break;
1129
1130 110
            case SymbolType::NT_ARRAY_CONTENT_TAIL . '.0.2':
1131
                // [ 0:T_COMMA, 1:NT_WS_OPT, 2:NT_ARRAY_CONTENT ]
1132 1
                $symbols[2]['i.value_list_id'] = $header['i.value_list_id'];
1133 1
                $symbols[2]['i.array_id'] = $header['i.array_id'];
1134 1
                break;
1135
1136 110
            case SymbolType::NT_REGEXP . '.0.1':
1137
                // [ 0:T_SLASH, 1:NT_REGEXP_STRING, 2:T_REGEXP_MOD ]
1138 5
                $symbols[1]['i.text'] = '/';
1139 5
                break;
1140
1141 110
            case SymbolType::NT_REGEXP_STRING . '.0.1':
1142
                // [ 0:T_UNESCAPED, 1:NT_REGEXP_STRING ]
1143 5
                $symbols[1]['i.text'] = $header['i.text'] . $symbols[0]['s.text'];
1144 5
                break;
1145
1146 110
            case SymbolType::NT_REGEXP_STRING . '.1.2':
1147
                // [ 0:T_BACKSLASH, 1:NT_REGEXP_ESCAPED, 2:NT_REGEXP_STRING ]
1148 3
                $symbols[2]['i.text'] = $header['i.text'] . $symbols[1]['s.text'];
1149 3
                break;
1150
        }
1151 110
    }
1152
}
1153