Passed
Push — master ( 511e20...91b368 )
by Edward
08:33 queued 05:58
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 applyTokenActions() 0 15 5
F applyProductionActions() 0 569 99
F applySymbolActions() 0 526 72
A __construct() 0 3 1

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