Test Failed
Push — master ( 59f97c...82a449 )
by Hannes
02:54
created

Parser::parseCODE()   F

Complexity

Conditions 16
Paths 1681

Size

Total Lines 118
Code Lines 68

Duplication

Lines 49
Ratio 41.53 %

Importance

Changes 0
Metric Value
dl 49
loc 118
rs 2
c 0
b 0
f 0
cc 16
eloc 68
nc 1681
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace hanneskod\readmetester\Parser;
4
5
class Parser
6
{
7
    protected $string;
8
    protected $position;
9
    protected $value;
10
    protected $cache;
11
    protected $cut;
12
    protected $errors;
13
    protected $warnings;
14
15
    protected function parseFILE()
16
    {
17
        $_position = $this->position;
18
19
        if (isset($this->cache['FILE'][$_position])) {
20
            $_success = $this->cache['FILE'][$_position]['success'];
21
            $this->position = $this->cache['FILE'][$_position]['position'];
22
            $this->value = $this->cache['FILE'][$_position]['value'];
23
24
            return $_success;
25
        }
26
27
        $_value9 = array();
28
29
        $_value4 = array();
30
        $_cut5 = $this->cut;
31
32
        while (true) {
33
            $_position3 = $this->position;
34
35
            $this->cut = false;
36
            $_position1 = $this->position;
37
            $_cut2 = $this->cut;
38
39
            $this->cut = false;
40
            $_success = $this->parseEXAMPLE();
41
42
            if (!$_success && !$this->cut) {
43
                $this->position = $_position1;
44
45
                $_success = $this->parseVOID_LINE();
46
            }
47
48
            $this->cut = $_cut2;
49
50
            if (!$_success) {
51
                break;
52
            }
53
54
            $_value4[] = $this->value;
55
        }
56
57
        if (!$this->cut) {
58
            $_success = true;
59
            $this->position = $_position3;
60
            $this->value = $_value4;
61
        }
62
63
        $this->cut = $_cut5;
64
65
        if ($_success) {
66
            $examples = $this->value;
67
        }
68
69
        if ($_success) {
70
            $_value9[] = $this->value;
71
72
            $_value7 = array();
73
            $_cut8 = $this->cut;
74
75
            while (true) {
76
                $_position6 = $this->position;
77
78
                $this->cut = false;
79
                if ($this->position < strlen($this->string)) {
80
                    $_success = true;
81
                    $this->value = substr($this->string, $this->position, 1);
82
                    $this->position += 1;
83
                } else {
84
                    $_success = false;
85
                }
86
87
                if (!$_success) {
88
                    break;
89
                }
90
91
                $_value7[] = $this->value;
92
            }
93
94
            if (!$this->cut) {
95
                $_success = true;
96
                $this->position = $_position6;
97
                $this->value = $_value7;
98
            }
99
100
            $this->cut = $_cut8;
101
        }
102
103
        if ($_success) {
104
            $_value9[] = $this->value;
105
106
            $this->value = $_value9;
107
        }
108
109
        if ($_success) {
110
            $this->value = call_user_func(function () use (&$examples) {
111
                return array_values(array_filter($examples));
112
            });
113
        }
114
115
        $this->cache['FILE'][$_position] = array(
116
            'success' => $_success,
117
            'position' => $this->position,
118
            'value' => $this->value
119
        );
120
121
        if (!$_success) {
122
            $this->report($_position, 'FILE');
123
        }
124
125
        return $_success;
126
    }
127
128
    protected function parseEXAMPLE()
129
    {
130
        $_position = $this->position;
131
132
        if (isset($this->cache['EXAMPLE'][$_position])) {
133
            $_success = $this->cache['EXAMPLE'][$_position]['success'];
134
            $this->position = $this->cache['EXAMPLE'][$_position]['position'];
135
            $this->value = $this->cache['EXAMPLE'][$_position]['value'];
136
137
            return $_success;
138
        }
139
140
        $_position10 = $this->position;
141
        $_cut11 = $this->cut;
142
143
        $this->cut = false;
144
        $_success = $this->parseVISIBLE_EXAMPLE();
145
146
        if (!$_success && !$this->cut) {
147
            $this->position = $_position10;
148
149
            $_success = $this->parseHIDDEN_EXAMPLE();
150
        }
151
152
        $this->cut = $_cut11;
153
154
        $this->cache['EXAMPLE'][$_position] = array(
155
            'success' => $_success,
156
            'position' => $this->position,
157
            'value' => $this->value
158
        );
159
160
        if (!$_success) {
161
            $this->report($_position, 'EXAMPLE');
162
        }
163
164
        return $_success;
165
    }
166
167
    protected function parseVISIBLE_EXAMPLE()
168
    {
169
        $_position = $this->position;
170
171
        if (isset($this->cache['VISIBLE_EXAMPLE'][$_position])) {
172
            $_success = $this->cache['VISIBLE_EXAMPLE'][$_position]['success'];
173
            $this->position = $this->cache['VISIBLE_EXAMPLE'][$_position]['position'];
174
            $this->value = $this->cache['VISIBLE_EXAMPLE'][$_position]['value'];
175
176
            return $_success;
177
        }
178
179
        $_value17 = array();
180
181
        $_position12 = $this->position;
182
        $_cut13 = $this->cut;
183
184
        $this->cut = false;
185
        $_success = $this->parseANNOTATION_GROUP();
186
187
        if (!$_success && !$this->cut) {
188
            $_success = true;
189
            $this->position = $_position12;
190
            $this->value = null;
191
        }
192
193
        $this->cut = $_cut13;
194
195
        if ($_success) {
196
            $annots = $this->value;
197
        }
198
199
        if ($_success) {
200
            $_value17[] = $this->value;
201
202
            $_value15 = array();
203
            $_cut16 = $this->cut;
204
205
            while (true) {
206
                $_position14 = $this->position;
207
208
                $this->cut = false;
209
                $_success = $this->parseEMPTY_LINE();
210
211
                if (!$_success) {
212
                    break;
213
                }
214
215
                $_value15[] = $this->value;
216
            }
217
218
            if (!$this->cut) {
219
                $_success = true;
220
                $this->position = $_position14;
221
                $this->value = $_value15;
222
            }
223
224
            $this->cut = $_cut16;
225
        }
226
227
        if ($_success) {
228
            $_value17[] = $this->value;
229
230
            $_success = $this->parseCODE();
231
232
            if ($_success) {
233
                $code = $this->value;
234
            }
235
        }
236
237
        if ($_success) {
238
            $_value17[] = $this->value;
239
240
            $this->value = $_value17;
241
        }
242
243
        if ($_success) {
244
            $this->value = call_user_func(function () use (&$annots, &$code) {
245
                return new Definition($code, ...(array)$annots);
246
            });
247
        }
248
249
        $this->cache['VISIBLE_EXAMPLE'][$_position] = array(
250
            'success' => $_success,
251
            'position' => $this->position,
252
            'value' => $this->value
253
        );
254
255
        if (!$_success) {
256
            $this->report($_position, 'VISIBLE_EXAMPLE');
257
        }
258
259
        return $_success;
260
    }
261
262
    protected function parseHIDDEN_EXAMPLE()
263
    {
264
        $_position = $this->position;
265
266
        if (isset($this->cache['HIDDEN_EXAMPLE'][$_position])) {
267
            $_success = $this->cache['HIDDEN_EXAMPLE'][$_position]['success'];
268
            $this->position = $this->cache['HIDDEN_EXAMPLE'][$_position]['position'];
269
            $this->value = $this->cache['HIDDEN_EXAMPLE'][$_position]['value'];
270
271
            return $_success;
272
        }
273
274
        $_value30 = array();
275
276
        $_success = $this->parseHTML_COMMENT_START();
277
278
        if ($_success) {
279
            $_value30[] = $this->value;
280
281
            $_value19 = array();
282
            $_cut20 = $this->cut;
283
284
            while (true) {
285
                $_position18 = $this->position;
286
287
                $this->cut = false;
288
                $_success = $this->parseEMPTY_LINE();
289
290
                if (!$_success) {
291
                    break;
292
                }
293
294
                $_value19[] = $this->value;
295
            }
296
297
            if (!$this->cut) {
298
                $_success = true;
299
                $this->position = $_position18;
300
                $this->value = $_value19;
301
            }
302
303
            $this->cut = $_cut20;
304
        }
305
306
        if ($_success) {
307
            $_value30[] = $this->value;
308
309
            $_value22 = array();
310
            $_cut23 = $this->cut;
311
312
            while (true) {
313
                $_position21 = $this->position;
314
315
                $this->cut = false;
316
                $_success = $this->parseANNOTATION();
317
318
                if (!$_success) {
319
                    break;
320
                }
321
322
                $_value22[] = $this->value;
323
            }
324
325
            if (!$this->cut) {
326
                $_success = true;
327
                $this->position = $_position21;
328
                $this->value = $_value22;
329
            }
330
331
            $this->cut = $_cut23;
332
333
            if ($_success) {
334
                $annots = $this->value;
335
            }
336
        }
337
338
        if ($_success) {
339
            $_value30[] = $this->value;
340
341
            $_value25 = array();
342
            $_cut26 = $this->cut;
343
344
            while (true) {
345
                $_position24 = $this->position;
346
347
                $this->cut = false;
348
                $_success = $this->parseEMPTY_LINE();
349
350
                if (!$_success) {
351
                    break;
352
                }
353
354
                $_value25[] = $this->value;
355
            }
356
357
            if (!$this->cut) {
358
                $_success = true;
359
                $this->position = $_position24;
360
                $this->value = $_value25;
361
            }
362
363
            $this->cut = $_cut26;
364
        }
365
366
        if ($_success) {
367
            $_value30[] = $this->value;
368
369
            $_success = $this->parseCODE();
370
371
            if ($_success) {
372
                $code = $this->value;
373
            }
374
        }
375
376
        if ($_success) {
377
            $_value30[] = $this->value;
378
379
            $_value28 = array();
380
            $_cut29 = $this->cut;
381
382
            while (true) {
383
                $_position27 = $this->position;
384
385
                $this->cut = false;
386
                $_success = $this->parseEMPTY_LINE();
387
388
                if (!$_success) {
389
                    break;
390
                }
391
392
                $_value28[] = $this->value;
393
            }
394
395
            if (!$this->cut) {
396
                $_success = true;
397
                $this->position = $_position27;
398
                $this->value = $_value28;
399
            }
400
401
            $this->cut = $_cut29;
402
        }
403
404
        if ($_success) {
405
            $_value30[] = $this->value;
406
407
            $_success = $this->parseHTML_COMMENT_END();
408
        }
409
410
        if ($_success) {
411
            $_value30[] = $this->value;
412
413
            $this->value = $_value30;
414
        }
415
416
        if ($_success) {
417
            $this->value = call_user_func(function () use (&$annots, &$code) {
418
                return new Definition($code, ...(array)$annots);
419
            });
420
        }
421
422
        $this->cache['HIDDEN_EXAMPLE'][$_position] = array(
423
            'success' => $_success,
424
            'position' => $this->position,
425
            'value' => $this->value
426
        );
427
428
        if (!$_success) {
429
            $this->report($_position, 'HIDDEN_EXAMPLE');
430
        }
431
432
        return $_success;
433
    }
434
435
    protected function parseANNOTATION_GROUP()
436
    {
437
        $_position = $this->position;
438
439
        if (isset($this->cache['ANNOTATION_GROUP'][$_position])) {
440
            $_success = $this->cache['ANNOTATION_GROUP'][$_position]['success'];
441
            $this->position = $this->cache['ANNOTATION_GROUP'][$_position]['position'];
442
            $this->value = $this->cache['ANNOTATION_GROUP'][$_position]['value'];
443
444
            return $_success;
445
        }
446
447
        $_success = $this->parseANNOTATION_BLOCK();
448
449
        if ($_success) {
450
            $_value32 = array($this->value);
451
            $_cut33 = $this->cut;
452
453
            while (true) {
454
                $_position31 = $this->position;
455
456
                $this->cut = false;
457
                $_success = $this->parseANNOTATION_BLOCK();
458
459
                if (!$_success) {
460
                    break;
461
                }
462
463
                $_value32[] = $this->value;
464
            }
465
466
            if (!$this->cut) {
467
                $_success = true;
468
                $this->position = $_position31;
469
                $this->value = $_value32;
470
            }
471
472
            $this->cut = $_cut33;
473
        }
474
475
        if ($_success) {
476
            $blocks = $this->value;
477
        }
478
479
        if ($_success) {
480
            $this->value = call_user_func(function () use (&$blocks) {
481
                return call_user_func_array('array_merge', $blocks);
482
            });
483
        }
484
485
        $this->cache['ANNOTATION_GROUP'][$_position] = array(
486
            'success' => $_success,
487
            'position' => $this->position,
488
            'value' => $this->value
489
        );
490
491
        if (!$_success) {
492
            $this->report($_position, 'ANNOTATION_GROUP');
493
        }
494
495
        return $_success;
496
    }
497
498
    protected function parseANNOTATION_BLOCK()
499
    {
500
        $_position = $this->position;
501
502
        if (isset($this->cache['ANNOTATION_BLOCK'][$_position])) {
503
            $_success = $this->cache['ANNOTATION_BLOCK'][$_position]['success'];
504
            $this->position = $this->cache['ANNOTATION_BLOCK'][$_position]['position'];
505
            $this->value = $this->cache['ANNOTATION_BLOCK'][$_position]['value'];
506
507
            return $_success;
508
        }
509
510
        $_value39 = array();
511
512
        $_success = $this->parseHTML_COMMENT_START();
513
514
        if ($_success) {
515
            $_value39[] = $this->value;
516
517
            $_position34 = $this->position;
518
            $_cut35 = $this->cut;
519
520
            $this->cut = false;
521
            $_success = $this->parseANNOTATION();
522
523
            if (!$_success && !$this->cut) {
524
                $this->position = $_position34;
525
526
                $_success = $this->parseEMPTY_LINE();
527
            }
528
529
            if (!$_success && !$this->cut) {
530
                $this->position = $_position34;
531
532
                $_success = $this->parseVOID_LINE_IN_COMMENT();
533
            }
534
535
            $this->cut = $_cut35;
536
537
            if ($_success) {
538
                $_value37 = array($this->value);
539
                $_cut38 = $this->cut;
540
541
                while (true) {
542
                    $_position36 = $this->position;
543
544
                    $this->cut = false;
545
                    $_position34 = $this->position;
546
                    $_cut35 = $this->cut;
547
548
                    $this->cut = false;
549
                    $_success = $this->parseANNOTATION();
550
551
                    if (!$_success && !$this->cut) {
552
                        $this->position = $_position34;
553
554
                        $_success = $this->parseEMPTY_LINE();
555
                    }
556
557
                    if (!$_success && !$this->cut) {
558
                        $this->position = $_position34;
559
560
                        $_success = $this->parseVOID_LINE_IN_COMMENT();
561
                    }
562
563
                    $this->cut = $_cut35;
564
565
                    if (!$_success) {
566
                        break;
567
                    }
568
569
                    $_value37[] = $this->value;
570
                }
571
572
                if (!$this->cut) {
573
                    $_success = true;
574
                    $this->position = $_position36;
575
                    $this->value = $_value37;
576
                }
577
578
                $this->cut = $_cut38;
579
            }
580
581
            if ($_success) {
582
                $annots = $this->value;
583
            }
584
        }
585
586
        if ($_success) {
587
            $_value39[] = $this->value;
588
589
            $_success = $this->parseHTML_COMMENT_END();
590
        }
591
592
        if ($_success) {
593
            $_value39[] = $this->value;
594
595
            $this->value = $_value39;
596
        }
597
598
        if ($_success) {
599
            $this->value = call_user_func(function () use (&$annots) {
600
                return array_filter($annots);
601
            });
602
        }
603
604
        $this->cache['ANNOTATION_BLOCK'][$_position] = array(
605
            'success' => $_success,
606
            'position' => $this->position,
607
            'value' => $this->value
608
        );
609
610
        if (!$_success) {
611
            $this->report($_position, 'ANNOTATION_BLOCK');
612
        }
613
614
        return $_success;
615
    }
616
617
    protected function parseANNOTATION()
618
    {
619
        $_position = $this->position;
620
621
        if (isset($this->cache['ANNOTATION'][$_position])) {
622
            $_success = $this->cache['ANNOTATION'][$_position]['success'];
623
            $this->position = $this->cache['ANNOTATION'][$_position]['position'];
624
            $this->value = $this->cache['ANNOTATION'][$_position]['value'];
625
626
            return $_success;
627
        }
628
629
        $_value45 = array();
630
631
        $_success = $this->parse_();
632
633
        if ($_success) {
634
            $_value45[] = $this->value;
635
636
            if (substr($this->string, $this->position, strlen('@')) === '@') {
637
                $_success = true;
638
                $this->value = substr($this->string, $this->position, strlen('@'));
639
                $this->position += strlen('@');
640
            } else {
641
                $_success = false;
642
643
                $this->report($this->position, '\'@\'');
644
            }
645
        }
646
647
        if ($_success) {
648
            $_value45[] = $this->value;
649
650
            $_success = $this->parseSTRING();
651
652
            if ($_success) {
653
                $name = $this->value;
654
            }
655
        }
656
657
        if ($_success) {
658
            $_value45[] = $this->value;
659
660
            $_value41 = array();
661
            $_cut42 = $this->cut;
662
663
            while (true) {
664
                $_position40 = $this->position;
665
666
                $this->cut = false;
667
                $_success = $this->parseSTRING();
668
669
                if (!$_success) {
670
                    break;
671
                }
672
673
                $_value41[] = $this->value;
674
            }
675
676
            if (!$this->cut) {
677
                $_success = true;
678
                $this->position = $_position40;
679
                $this->value = $_value41;
680
            }
681
682
            $this->cut = $_cut42;
683
684
            if ($_success) {
685
                $args = $this->value;
686
            }
687
        }
688
689
        if ($_success) {
690
            $_value45[] = $this->value;
691
692
            $_position43 = $this->position;
693
            $_cut44 = $this->cut;
694
695
            $this->cut = false;
696
            $_success = $this->parseEOL();
697
698
            if (!$_success && !$this->cut) {
699
                $_success = true;
700
                $this->position = $_position43;
701
                $this->value = null;
702
            }
703
704
            $this->cut = $_cut44;
705
        }
706
707
        if ($_success) {
708
            $_value45[] = $this->value;
709
710
            $this->value = $_value45;
711
        }
712
713
        if ($_success) {
714
            $this->value = call_user_func(function () use (&$name, &$args) {
715
                return new Annotation($name, ...$args);
716
            });
717
        }
718
719
        $this->cache['ANNOTATION'][$_position] = array(
720
            'success' => $_success,
721
            'position' => $this->position,
722
            'value' => $this->value
723
        );
724
725
        if (!$_success) {
726
            $this->report($_position, 'ANNOTATION');
727
        }
728
729
        return $_success;
730
    }
731
732
    protected function parseSTRING()
733
    {
734
        $_position = $this->position;
735
736
        if (isset($this->cache['STRING'][$_position])) {
737
            $_success = $this->cache['STRING'][$_position]['success'];
738
            $this->position = $this->cache['STRING'][$_position]['position'];
739
            $this->value = $this->cache['STRING'][$_position]['value'];
740
741
            return $_success;
742
        }
743
744
        $_value48 = array();
745
746
        $_success = $this->parse_();
747
748
        if ($_success) {
749
            $_value48[] = $this->value;
750
751
            $_position46 = $this->position;
752
            $_cut47 = $this->cut;
753
754
            $this->cut = false;
755
            $_success = $this->parseRAW_STRING();
756
757
            if (!$_success && !$this->cut) {
758
                $this->position = $_position46;
759
760
                $_success = $this->parseQUOTED_STRING();
761
            }
762
763
            if (!$_success && !$this->cut) {
764
                $this->position = $_position46;
765
766
                $_success = $this->parseEMPTY_STRING();
767
            }
768
769
            $this->cut = $_cut47;
770
771
            if ($_success) {
772
                $string = $this->value;
773
            }
774
        }
775
776
        if ($_success) {
777
            $_value48[] = $this->value;
778
779
            $_success = $this->parse_();
780
        }
781
782
        if ($_success) {
783
            $_value48[] = $this->value;
784
785
            $this->value = $_value48;
786
        }
787
788
        if ($_success) {
789
            $this->value = call_user_func(function () use (&$string) {
790
                return $string;
791
            });
792
        }
793
794
        $this->cache['STRING'][$_position] = array(
795
            'success' => $_success,
796
            'position' => $this->position,
797
            'value' => $this->value
798
        );
799
800
        if (!$_success) {
801
            $this->report($_position, 'STRING');
802
        }
803
804
        return $_success;
805
    }
806
807
    protected function parseEMPTY_STRING()
808
    {
809
        $_position = $this->position;
810
811
        if (isset($this->cache['EMPTY_STRING'][$_position])) {
812
            $_success = $this->cache['EMPTY_STRING'][$_position]['success'];
813
            $this->position = $this->cache['EMPTY_STRING'][$_position]['position'];
814
            $this->value = $this->cache['EMPTY_STRING'][$_position]['value'];
815
816
            return $_success;
817
        }
818
819
        if (substr($this->string, $this->position, strlen('""')) === '""') {
820
            $_success = true;
821
            $this->value = substr($this->string, $this->position, strlen('""'));
822
            $this->position += strlen('""');
823
        } else {
824
            $_success = false;
825
826
            $this->report($this->position, '\'""\'');
827
        }
828
829
        if ($_success) {
830
            $this->value = call_user_func(function () {
831
                return '';
832
            });
833
        }
834
835
        $this->cache['EMPTY_STRING'][$_position] = array(
836
            'success' => $_success,
837
            'position' => $this->position,
838
            'value' => $this->value
839
        );
840
841
        if (!$_success) {
842
            $this->report($_position, 'EMPTY_STRING');
843
        }
844
845
        return $_success;
846
    }
847
848
    protected function parseQUOTED_STRING()
849
    {
850
        $_position = $this->position;
851
852
        if (isset($this->cache['QUOTED_STRING'][$_position])) {
853
            $_success = $this->cache['QUOTED_STRING'][$_position]['success'];
854
            $this->position = $this->cache['QUOTED_STRING'][$_position]['position'];
855
            $this->value = $this->cache['QUOTED_STRING'][$_position]['value'];
856
857
            return $_success;
858
        }
859
860
        $_value54 = array();
861
862
        if (substr($this->string, $this->position, strlen('"')) === '"') {
863
            $_success = true;
864
            $this->value = substr($this->string, $this->position, strlen('"'));
865
            $this->position += strlen('"');
866
        } else {
867
            $_success = false;
868
869
            $this->report($this->position, '\'"\'');
870
        }
871
872
        if ($_success) {
873
            $_value54[] = $this->value;
874
875
            $_value52 = array();
876
            $_cut53 = $this->cut;
877
878
            while (true) {
879
                $_position51 = $this->position;
880
881
                $this->cut = false;
882
                $_position49 = $this->position;
883
                $_cut50 = $this->cut;
884
885
                $this->cut = false;
886
                $_success = $this->parseESCAPED_QUOTE();
887
888
                if (!$_success && !$this->cut) {
889
                    $this->position = $_position49;
890
891
                    if (substr($this->string, $this->position, strlen(' ')) === ' ') {
892
                        $_success = true;
893
                        $this->value = substr($this->string, $this->position, strlen(' '));
894
                        $this->position += strlen(' ');
895
                    } else {
896
                        $_success = false;
897
898
                        $this->report($this->position, '\' \'');
899
                    }
900
                }
901
902
                if (!$_success && !$this->cut) {
903
                    $this->position = $_position49;
904
905
                    $_success = $this->parseRAW_STRING();
906
                }
907
908
                $this->cut = $_cut50;
909
910
                if (!$_success) {
911
                    break;
912
                }
913
914
                $_value52[] = $this->value;
915
            }
916
917
            if (!$this->cut) {
918
                $_success = true;
919
                $this->position = $_position51;
920
                $this->value = $_value52;
921
            }
922
923
            $this->cut = $_cut53;
924
925
            if ($_success) {
926
                $string = $this->value;
927
            }
928
        }
929
930
        if ($_success) {
931
            $_value54[] = $this->value;
932
933
            if (substr($this->string, $this->position, strlen('"')) === '"') {
934
                $_success = true;
935
                $this->value = substr($this->string, $this->position, strlen('"'));
936
                $this->position += strlen('"');
937
            } else {
938
                $_success = false;
939
940
                $this->report($this->position, '\'"\'');
941
            }
942
        }
943
944
        if ($_success) {
945
            $_value54[] = $this->value;
946
947
            $this->value = $_value54;
948
        }
949
950
        if ($_success) {
951
            $this->value = call_user_func(function () use (&$string) {
952
                return implode($string);
953
            });
954
        }
955
956
        $this->cache['QUOTED_STRING'][$_position] = array(
957
            'success' => $_success,
958
            'position' => $this->position,
959
            'value' => $this->value
960
        );
961
962
        if (!$_success) {
963
            $this->report($_position, 'QUOTED_STRING');
964
        }
965
966
        return $_success;
967
    }
968
969
    protected function parseESCAPED_QUOTE()
970
    {
971
        $_position = $this->position;
972
973
        if (isset($this->cache['ESCAPED_QUOTE'][$_position])) {
974
            $_success = $this->cache['ESCAPED_QUOTE'][$_position]['success'];
975
            $this->position = $this->cache['ESCAPED_QUOTE'][$_position]['position'];
976
            $this->value = $this->cache['ESCAPED_QUOTE'][$_position]['value'];
977
978
            return $_success;
979
        }
980
981
        if (substr($this->string, $this->position, strlen('\"')) === '\"') {
982
            $_success = true;
983
            $this->value = substr($this->string, $this->position, strlen('\"'));
984
            $this->position += strlen('\"');
985
        } else {
986
            $_success = false;
987
988
            $this->report($this->position, '\'\\"\'');
989
        }
990
991
        if ($_success) {
992
            $this->value = call_user_func(function () {
993
                return '"';
994
            });
995
        }
996
997
        $this->cache['ESCAPED_QUOTE'][$_position] = array(
998
            'success' => $_success,
999
            'position' => $this->position,
1000
            'value' => $this->value
1001
        );
1002
1003
        if (!$_success) {
1004
            $this->report($_position, 'ESCAPED_QUOTE');
1005
        }
1006
1007
        return $_success;
1008
    }
1009
1010
    protected function parseRAW_STRING()
1011
    {
1012
        $_position = $this->position;
1013
1014
        if (isset($this->cache['RAW_STRING'][$_position])) {
1015
            $_success = $this->cache['RAW_STRING'][$_position]['success'];
1016
            $this->position = $this->cache['RAW_STRING'][$_position]['position'];
1017
            $this->value = $this->cache['RAW_STRING'][$_position]['value'];
1018
1019
            return $_success;
1020
        }
1021
1022
        $_position63 = $this->position;
1023
1024
        $_value59 = array();
1025
1026
        $_position57 = $this->position;
1027
        $_cut58 = $this->cut;
1028
1029
        $this->cut = false;
1030
        $_position55 = $this->position;
1031
        $_cut56 = $this->cut;
1032
1033
        $this->cut = false;
1034
        if (substr($this->string, $this->position, strlen(' ')) === ' ') {
1035
            $_success = true;
1036
            $this->value = substr($this->string, $this->position, strlen(' '));
1037
            $this->position += strlen(' ');
1038
        } else {
1039
            $_success = false;
1040
1041
            $this->report($this->position, '\' \'');
1042
        }
1043
1044
        if (!$_success && !$this->cut) {
1045
            $this->position = $_position55;
1046
1047
            if (substr($this->string, $this->position, strlen("\r")) === "\r") {
1048
                $_success = true;
1049
                $this->value = substr($this->string, $this->position, strlen("\r"));
1050
                $this->position += strlen("\r");
1051
            } else {
1052
                $_success = false;
1053
1054
                $this->report($this->position, '"\\r"');
1055
            }
1056
        }
1057
1058
        if (!$_success && !$this->cut) {
1059
            $this->position = $_position55;
1060
1061
            if (substr($this->string, $this->position, strlen("\n")) === "\n") {
1062
                $_success = true;
1063
                $this->value = substr($this->string, $this->position, strlen("\n"));
1064
                $this->position += strlen("\n");
1065
            } else {
1066
                $_success = false;
1067
1068
                $this->report($this->position, '"\\n"');
1069
            }
1070
        }
1071
1072
        if (!$_success && !$this->cut) {
1073
            $this->position = $_position55;
1074
1075
            if (substr($this->string, $this->position, strlen("\t")) === "\t") {
1076
                $_success = true;
1077
                $this->value = substr($this->string, $this->position, strlen("\t"));
1078
                $this->position += strlen("\t");
1079
            } else {
1080
                $_success = false;
1081
1082
                $this->report($this->position, '"\\t"');
1083
            }
1084
        }
1085
1086
        if (!$_success && !$this->cut) {
1087
            $this->position = $_position55;
1088
1089
            $_success = $this->parseCOMMENT_END();
1090
        }
1091
1092
        if (!$_success && !$this->cut) {
1093
            $this->position = $_position55;
1094
1095
            $_success = $this->parseCOMMENT_END_COLD_FUSION();
1096
        }
1097
1098
        if (!$_success && !$this->cut) {
1099
            $this->position = $_position55;
1100
1101
            if (substr($this->string, $this->position, strlen('"')) === '"') {
1102
                $_success = true;
1103
                $this->value = substr($this->string, $this->position, strlen('"'));
1104
                $this->position += strlen('"');
1105
            } else {
1106
                $_success = false;
1107
1108
                $this->report($this->position, '\'"\'');
1109
            }
1110
        }
1111
1112
        $this->cut = $_cut56;
1113
1114
        if (!$_success) {
1115
            $_success = true;
1116
            $this->value = null;
1117
        } else {
1118
            $_success = false;
1119
        }
1120
1121
        $this->position = $_position57;
1122
        $this->cut = $_cut58;
1123
1124
        if ($_success) {
1125
            $_value59[] = $this->value;
1126
1127
            if ($this->position < strlen($this->string)) {
1128
                $_success = true;
1129
                $this->value = substr($this->string, $this->position, 1);
1130
                $this->position += 1;
1131
            } else {
1132
                $_success = false;
1133
            }
1134
        }
1135
1136
        if ($_success) {
1137
            $_value59[] = $this->value;
1138
1139
            $this->value = $_value59;
1140
        }
1141
1142
        if ($_success) {
1143
            $_value61 = array($this->value);
1144
            $_cut62 = $this->cut;
1145
1146
            while (true) {
1147
                $_position60 = $this->position;
1148
1149
                $this->cut = false;
1150
                $_value59 = array();
1151
1152
                $_position57 = $this->position;
1153
                $_cut58 = $this->cut;
1154
1155
                $this->cut = false;
1156
                $_position55 = $this->position;
1157
                $_cut56 = $this->cut;
1158
1159
                $this->cut = false;
1160
                if (substr($this->string, $this->position, strlen(' ')) === ' ') {
1161
                    $_success = true;
1162
                    $this->value = substr($this->string, $this->position, strlen(' '));
1163
                    $this->position += strlen(' ');
1164
                } else {
1165
                    $_success = false;
1166
1167
                    $this->report($this->position, '\' \'');
1168
                }
1169
1170
                if (!$_success && !$this->cut) {
1171
                    $this->position = $_position55;
1172
1173
                    if (substr($this->string, $this->position, strlen("\r")) === "\r") {
1174
                        $_success = true;
1175
                        $this->value = substr($this->string, $this->position, strlen("\r"));
1176
                        $this->position += strlen("\r");
1177
                    } else {
1178
                        $_success = false;
1179
1180
                        $this->report($this->position, '"\\r"');
1181
                    }
1182
                }
1183
1184
                if (!$_success && !$this->cut) {
1185
                    $this->position = $_position55;
1186
1187
                    if (substr($this->string, $this->position, strlen("\n")) === "\n") {
1188
                        $_success = true;
1189
                        $this->value = substr($this->string, $this->position, strlen("\n"));
1190
                        $this->position += strlen("\n");
1191
                    } else {
1192
                        $_success = false;
1193
1194
                        $this->report($this->position, '"\\n"');
1195
                    }
1196
                }
1197
1198
                if (!$_success && !$this->cut) {
1199
                    $this->position = $_position55;
1200
1201
                    if (substr($this->string, $this->position, strlen("\t")) === "\t") {
1202
                        $_success = true;
1203
                        $this->value = substr($this->string, $this->position, strlen("\t"));
1204
                        $this->position += strlen("\t");
1205
                    } else {
1206
                        $_success = false;
1207
1208
                        $this->report($this->position, '"\\t"');
1209
                    }
1210
                }
1211
1212
                if (!$_success && !$this->cut) {
1213
                    $this->position = $_position55;
1214
1215
                    $_success = $this->parseCOMMENT_END();
1216
                }
1217
1218
                if (!$_success && !$this->cut) {
1219
                    $this->position = $_position55;
1220
1221
                    $_success = $this->parseCOMMENT_END_COLD_FUSION();
1222
                }
1223
1224
                if (!$_success && !$this->cut) {
1225
                    $this->position = $_position55;
1226
1227
                    if (substr($this->string, $this->position, strlen('"')) === '"') {
1228
                        $_success = true;
1229
                        $this->value = substr($this->string, $this->position, strlen('"'));
1230
                        $this->position += strlen('"');
1231
                    } else {
1232
                        $_success = false;
1233
1234
                        $this->report($this->position, '\'"\'');
1235
                    }
1236
                }
1237
1238
                $this->cut = $_cut56;
1239
1240
                if (!$_success) {
1241
                    $_success = true;
1242
                    $this->value = null;
1243
                } else {
1244
                    $_success = false;
1245
                }
1246
1247
                $this->position = $_position57;
1248
                $this->cut = $_cut58;
1249
1250
                if ($_success) {
1251
                    $_value59[] = $this->value;
1252
1253
                    if ($this->position < strlen($this->string)) {
1254
                        $_success = true;
1255
                        $this->value = substr($this->string, $this->position, 1);
1256
                        $this->position += 1;
1257
                    } else {
1258
                        $_success = false;
1259
                    }
1260
                }
1261
1262
                if ($_success) {
1263
                    $_value59[] = $this->value;
1264
1265
                    $this->value = $_value59;
1266
                }
1267
1268
                if (!$_success) {
1269
                    break;
1270
                }
1271
1272
                $_value61[] = $this->value;
1273
            }
1274
1275
            if (!$this->cut) {
1276
                $_success = true;
1277
                $this->position = $_position60;
1278
                $this->value = $_value61;
1279
            }
1280
1281
            $this->cut = $_cut62;
1282
        }
1283
1284
        if ($_success) {
1285
            $this->value = strval(substr($this->string, $_position63, $this->position - $_position63));
1286
        }
1287
1288
        $this->cache['RAW_STRING'][$_position] = array(
1289
            'success' => $_success,
1290
            'position' => $this->position,
1291
            'value' => $this->value
1292
        );
1293
1294
        if (!$_success) {
1295
            $this->report($_position, 'RAW_STRING');
1296
        }
1297
1298
        return $_success;
1299
    }
1300
1301
    protected function parseCODE()
1302
    {
1303
        $_position = $this->position;
1304
1305
        if (isset($this->cache['CODE'][$_position])) {
1306
            $_success = $this->cache['CODE'][$_position]['success'];
1307
            $this->position = $this->cache['CODE'][$_position]['position'];
1308
            $this->value = $this->cache['CODE'][$_position]['value'];
1309
1310
            return $_success;
1311
        }
1312
1313
        $_value71 = array();
1314
1315
        $_success = $this->parseCODE_START();
1316
1317
        if ($_success) {
1318
            $_value71[] = $this->value;
1319
1320
            $_position70 = $this->position;
1321
1322
            $_value68 = array();
1323
            $_cut69 = $this->cut;
1324
1325
            while (true) {
1326
                $_position67 = $this->position;
1327
1328
                $this->cut = false;
1329
                $_value66 = array();
1330
1331
                $_position64 = $this->position;
1332
                $_cut65 = $this->cut;
1333
1334
                $this->cut = false;
1335
                $_success = $this->parseCODE_END();
1336
1337
                if (!$_success) {
1338
                    $_success = true;
1339
                    $this->value = null;
1340
                } else {
1341
                    $_success = false;
1342
                }
1343
1344
                $this->position = $_position64;
1345
                $this->cut = $_cut65;
1346
1347
                if ($_success) {
1348
                    $_value66[] = $this->value;
1349
1350
                    if ($this->position < strlen($this->string)) {
1351
                        $_success = true;
1352
                        $this->value = substr($this->string, $this->position, 1);
1353
                        $this->position += 1;
1354
                    } else {
1355
                        $_success = false;
1356
                    }
1357
                }
1358
1359
                if ($_success) {
1360
                    $_value66[] = $this->value;
1361
1362
                    $this->value = $_value66;
1363
                }
1364
1365
                if (!$_success) {
1366
                    break;
1367
                }
1368
1369
                $_value68[] = $this->value;
1370
            }
1371
1372
            if (!$this->cut) {
1373
                $_success = true;
1374
                $this->position = $_position67;
1375
                $this->value = $_value68;
1376
            }
1377
1378
            $this->cut = $_cut69;
1379
1380
            if ($_success) {
1381
                $this->value = strval(substr($this->string, $_position70, $this->position - $_position70));
1382
            }
1383
1384
            if ($_success) {
1385
                $code = $this->value;
1386
            }
1387
        }
1388
1389
        if ($_success) {
1390
            $_value71[] = $this->value;
1391
1392
            $_success = $this->parseCODE_END();
1393
        }
1394
1395
        if ($_success) {
1396
            $_value71[] = $this->value;
1397
1398
            $this->value = $_value71;
1399
        }
1400
1401
        if ($_success) {
1402
            $this->value = call_user_func(function () use (&$code) {
1403
                return new CodeBlock($code);
1404
            });
1405
        }
1406
1407
        $this->cache['CODE'][$_position] = array(
1408
            'success' => $_success,
1409
            'position' => $this->position,
1410
            'value' => $this->value
1411
        );
1412
1413
        if (!$_success) {
1414
            $this->report($_position, 'CODE');
1415
        }
1416
1417
        return $_success;
1418
    }
1419
1420
    protected function parseCODE_START()
1421
    {
1422
        $_position = $this->position;
1423
1424
        if (isset($this->cache['CODE_START'][$_position])) {
1425
            $_success = $this->cache['CODE_START'][$_position]['success'];
1426
            $this->position = $this->cache['CODE_START'][$_position]['position'];
1427
            $this->value = $this->cache['CODE_START'][$_position]['value'];
1428
1429
            return $_success;
1430
        }
1431
1432
        $_value72 = array();
1433
1434
        if (strtolower(substr($this->string, $this->position, strlen('```php'))) === strtolower('```php')) {
1435
            $_success = true;
1436
            $this->value = substr($this->string, $this->position, strlen('```php'));
1437
            $this->position += strlen('```php');
1438
        } else {
1439
            $_success = false;
1440
1441
            $this->report($this->position, '\'```php\'');
1442
        }
1443
1444
        if ($_success) {
1445
            $_value72[] = $this->value;
1446
1447
            $_success = $this->parseEOL();
1448
        }
1449
1450
        if ($_success) {
1451
            $_value72[] = $this->value;
1452
1453
            $this->value = $_value72;
1454
        }
1455
1456
        $this->cache['CODE_START'][$_position] = array(
1457
            'success' => $_success,
1458
            'position' => $this->position,
1459
            'value' => $this->value
1460
        );
1461
1462
        if (!$_success) {
1463
            $this->report($_position, 'CODE_START');
1464
        }
1465
1466
        return $_success;
1467
    }
1468
1469
    protected function parseCODE_END()
1470
    {
1471
        $_position = $this->position;
1472
1473
        if (isset($this->cache['CODE_END'][$_position])) {
1474
            $_success = $this->cache['CODE_END'][$_position]['success'];
1475
            $this->position = $this->cache['CODE_END'][$_position]['position'];
1476
            $this->value = $this->cache['CODE_END'][$_position]['value'];
1477
1478
            return $_success;
1479
        }
1480
1481
        $_value75 = array();
1482
1483
        if (substr($this->string, $this->position, strlen('```')) === '```') {
1484
            $_success = true;
1485
            $this->value = substr($this->string, $this->position, strlen('```'));
1486
            $this->position += strlen('```');
1487
        } else {
1488
            $_success = false;
1489
1490
            $this->report($this->position, '\'```\'');
1491
        }
1492
1493
        if ($_success) {
1494
            $_value75[] = $this->value;
1495
1496
            $_position73 = $this->position;
1497
            $_cut74 = $this->cut;
1498
1499
            $this->cut = false;
1500
            $_success = $this->parseEOL();
1501
1502
            if (!$_success && !$this->cut) {
1503
                $this->position = $_position73;
1504
1505
                $_success = $this->parseEOF();
1506
            }
1507
1508
            $this->cut = $_cut74;
1509
        }
1510
1511
        if ($_success) {
1512
            $_value75[] = $this->value;
1513
1514
            $this->value = $_value75;
1515
        }
1516
1517
        $this->cache['CODE_END'][$_position] = array(
1518
            'success' => $_success,
1519
            'position' => $this->position,
1520
            'value' => $this->value
1521
        );
1522
1523
        if (!$_success) {
1524
            $this->report($_position, 'CODE_END');
1525
        }
1526
1527
        return $_success;
1528
    }
1529
1530
    protected function parseVOID_LINE_IN_COMMENT()
1531
    {
1532
        $_position = $this->position;
1533
1534
        if (isset($this->cache['VOID_LINE_IN_COMMENT'][$_position])) {
1535
            $_success = $this->cache['VOID_LINE_IN_COMMENT'][$_position]['success'];
1536
            $this->position = $this->cache['VOID_LINE_IN_COMMENT'][$_position]['position'];
1537
            $this->value = $this->cache['VOID_LINE_IN_COMMENT'][$_position]['value'];
1538
1539
            return $_success;
1540
        }
1541
1542
        $_value78 = array();
1543
1544
        $_position76 = $this->position;
1545
        $_cut77 = $this->cut;
1546
1547
        $this->cut = false;
1548
        $_success = $this->parseHTML_COMMENT_END();
1549
1550
        if (!$_success) {
1551
            $_success = true;
1552
            $this->value = null;
1553
        } else {
1554
            $_success = false;
1555
        }
1556
1557
        $this->position = $_position76;
1558
        $this->cut = $_cut77;
1559
1560
        if ($_success) {
1561
            $_value78[] = $this->value;
1562
1563
            $_success = $this->parseVOID_LINE();
1564
        }
1565
1566
        if ($_success) {
1567
            $_value78[] = $this->value;
1568
1569
            $this->value = $_value78;
1570
        }
1571
1572
        if ($_success) {
1573
            $this->value = call_user_func(function () {
1574
                
1575
            });
1576
        }
1577
1578
        $this->cache['VOID_LINE_IN_COMMENT'][$_position] = array(
1579
            'success' => $_success,
1580
            'position' => $this->position,
1581
            'value' => $this->value
1582
        );
1583
1584
        if (!$_success) {
1585
            $this->report($_position, 'VOID_LINE_IN_COMMENT');
1586
        }
1587
1588
        return $_success;
1589
    }
1590
1591
    protected function parseVOID_LINE()
1592
    {
1593
        $_position = $this->position;
1594
1595
        if (isset($this->cache['VOID_LINE'][$_position])) {
1596
            $_success = $this->cache['VOID_LINE'][$_position]['success'];
1597
            $this->position = $this->cache['VOID_LINE'][$_position]['position'];
1598
            $this->value = $this->cache['VOID_LINE'][$_position]['value'];
1599
1600
            return $_success;
1601
        }
1602
1603
        $_value85 = array();
1604
1605
        $_value83 = array();
1606
        $_cut84 = $this->cut;
1607
1608
        while (true) {
1609
            $_position82 = $this->position;
1610
1611
            $this->cut = false;
1612
            $_value81 = array();
1613
1614
            $_position79 = $this->position;
1615
            $_cut80 = $this->cut;
1616
1617
            $this->cut = false;
1618
            $_success = $this->parseEOL();
1619
1620
            if (!$_success) {
1621
                $_success = true;
1622
                $this->value = null;
1623
            } else {
1624
                $_success = false;
1625
            }
1626
1627
            $this->position = $_position79;
1628
            $this->cut = $_cut80;
1629
1630
            if ($_success) {
1631
                $_value81[] = $this->value;
1632
1633
                if ($this->position < strlen($this->string)) {
1634
                    $_success = true;
1635
                    $this->value = substr($this->string, $this->position, 1);
1636
                    $this->position += 1;
1637
                } else {
1638
                    $_success = false;
1639
                }
1640
            }
1641
1642
            if ($_success) {
1643
                $_value81[] = $this->value;
1644
1645
                $this->value = $_value81;
1646
            }
1647
1648
            if (!$_success) {
1649
                break;
1650
            }
1651
1652
            $_value83[] = $this->value;
1653
        }
1654
1655
        if (!$this->cut) {
1656
            $_success = true;
1657
            $this->position = $_position82;
1658
            $this->value = $_value83;
1659
        }
1660
1661
        $this->cut = $_cut84;
1662
1663
        if ($_success) {
1664
            $_value85[] = $this->value;
1665
1666
            $_success = $this->parseEOL();
1667
        }
1668
1669
        if ($_success) {
1670
            $_value85[] = $this->value;
1671
1672
            $this->value = $_value85;
1673
        }
1674
1675
        if ($_success) {
1676
            $this->value = call_user_func(function () {
1677
                
1678
            });
1679
        }
1680
1681
        $this->cache['VOID_LINE'][$_position] = array(
1682
            'success' => $_success,
1683
            'position' => $this->position,
1684
            'value' => $this->value
1685
        );
1686
1687
        if (!$_success) {
1688
            $this->report($_position, 'VOID_LINE');
1689
        }
1690
1691
        return $_success;
1692
    }
1693
1694
    protected function parseEMPTY_LINE()
1695
    {
1696
        $_position = $this->position;
1697
1698
        if (isset($this->cache['EMPTY_LINE'][$_position])) {
1699
            $_success = $this->cache['EMPTY_LINE'][$_position]['success'];
1700
            $this->position = $this->cache['EMPTY_LINE'][$_position]['position'];
1701
            $this->value = $this->cache['EMPTY_LINE'][$_position]['value'];
1702
1703
            return $_success;
1704
        }
1705
1706
        $_value86 = array();
1707
1708
        $_success = $this->parse_();
1709
1710
        if ($_success) {
1711
            $_value86[] = $this->value;
1712
1713
            $_success = $this->parseEOL();
1714
        }
1715
1716
        if ($_success) {
1717
            $_value86[] = $this->value;
1718
1719
            $this->value = $_value86;
1720
        }
1721
1722
        if ($_success) {
1723
            $this->value = call_user_func(function () {
1724
                
1725
            });
1726
        }
1727
1728
        $this->cache['EMPTY_LINE'][$_position] = array(
1729
            'success' => $_success,
1730
            'position' => $this->position,
1731
            'value' => $this->value
1732
        );
1733
1734
        if (!$_success) {
1735
            $this->report($_position, 'EMPTY_LINE');
1736
        }
1737
1738
        return $_success;
1739
    }
1740
1741
    protected function parseHTML_COMMENT_START()
1742
    {
1743
        $_position = $this->position;
1744
1745
        if (isset($this->cache['HTML_COMMENT_START'][$_position])) {
1746
            $_success = $this->cache['HTML_COMMENT_START'][$_position]['success'];
1747
            $this->position = $this->cache['HTML_COMMENT_START'][$_position]['position'];
1748
            $this->value = $this->cache['HTML_COMMENT_START'][$_position]['value'];
1749
1750
            return $_success;
1751
        }
1752
1753
        $_value91 = array();
1754
1755
        $_success = $this->parse_();
1756
1757
        if ($_success) {
1758
            $_value91[] = $this->value;
1759
1760
            if (substr($this->string, $this->position, strlen('<!--')) === '<!--') {
1761
                $_success = true;
1762
                $this->value = substr($this->string, $this->position, strlen('<!--'));
1763
                $this->position += strlen('<!--');
1764
            } else {
1765
                $_success = false;
1766
1767
                $this->report($this->position, '\'<!--\'');
1768
            }
1769
        }
1770
1771
        if ($_success) {
1772
            $_value91[] = $this->value;
1773
1774
            $_position87 = $this->position;
1775
            $_cut88 = $this->cut;
1776
1777
            $this->cut = false;
1778
            if (substr($this->string, $this->position, strlen('-')) === '-') {
1779
                $_success = true;
1780
                $this->value = substr($this->string, $this->position, strlen('-'));
1781
                $this->position += strlen('-');
1782
            } else {
1783
                $_success = false;
1784
1785
                $this->report($this->position, '\'-\'');
1786
            }
1787
1788
            if (!$_success && !$this->cut) {
1789
                $_success = true;
1790
                $this->position = $_position87;
1791
                $this->value = null;
1792
            }
1793
1794
            $this->cut = $_cut88;
1795
        }
1796
1797
        if ($_success) {
1798
            $_value91[] = $this->value;
1799
1800
            $_position89 = $this->position;
1801
            $_cut90 = $this->cut;
1802
1803
            $this->cut = false;
1804
            $_success = $this->parseEOL();
1805
1806
            if (!$_success && !$this->cut) {
1807
                $_success = true;
1808
                $this->position = $_position89;
1809
                $this->value = null;
1810
            }
1811
1812
            $this->cut = $_cut90;
1813
        }
1814
1815
        if ($_success) {
1816
            $_value91[] = $this->value;
1817
1818
            $this->value = $_value91;
1819
        }
1820
1821
        $this->cache['HTML_COMMENT_START'][$_position] = array(
1822
            'success' => $_success,
1823
            'position' => $this->position,
1824
            'value' => $this->value
1825
        );
1826
1827
        if (!$_success) {
1828
            $this->report($_position, 'HTML_COMMENT_START');
1829
        }
1830
1831
        return $_success;
1832
    }
1833
1834
    protected function parseHTML_COMMENT_END()
1835
    {
1836
        $_position = $this->position;
1837
1838
        if (isset($this->cache['HTML_COMMENT_END'][$_position])) {
1839
            $_success = $this->cache['HTML_COMMENT_END'][$_position]['success'];
1840
            $this->position = $this->cache['HTML_COMMENT_END'][$_position]['position'];
1841
            $this->value = $this->cache['HTML_COMMENT_END'][$_position]['value'];
1842
1843
            return $_success;
1844
        }
1845
1846
        $_value96 = array();
1847
1848
        $_success = $this->parse_();
1849
1850
        if ($_success) {
1851
            $_value96[] = $this->value;
1852
1853
            $_position92 = $this->position;
1854
            $_cut93 = $this->cut;
1855
1856
            $this->cut = false;
1857
            $_success = $this->parseCOMMENT_END();
1858
1859
            if (!$_success && !$this->cut) {
1860
                $this->position = $_position92;
1861
1862
                $_success = $this->parseCOMMENT_END_COLD_FUSION();
1863
            }
1864
1865
            $this->cut = $_cut93;
1866
        }
1867
1868
        if ($_success) {
1869
            $_value96[] = $this->value;
1870
1871
            $_position94 = $this->position;
1872
            $_cut95 = $this->cut;
1873
1874
            $this->cut = false;
1875
            $_success = $this->parseEOL();
1876
1877
            if (!$_success && !$this->cut) {
1878
                $_success = true;
1879
                $this->position = $_position94;
1880
                $this->value = null;
1881
            }
1882
1883
            $this->cut = $_cut95;
1884
        }
1885
1886
        if ($_success) {
1887
            $_value96[] = $this->value;
1888
1889
            $this->value = $_value96;
1890
        }
1891
1892
        $this->cache['HTML_COMMENT_END'][$_position] = array(
1893
            'success' => $_success,
1894
            'position' => $this->position,
1895
            'value' => $this->value
1896
        );
1897
1898
        if (!$_success) {
1899
            $this->report($_position, 'HTML_COMMENT_END');
1900
        }
1901
1902
        return $_success;
1903
    }
1904
1905
    protected function parseCOMMENT_END()
1906
    {
1907
        $_position = $this->position;
1908
1909
        if (isset($this->cache['COMMENT_END'][$_position])) {
1910
            $_success = $this->cache['COMMENT_END'][$_position]['success'];
1911
            $this->position = $this->cache['COMMENT_END'][$_position]['position'];
1912
            $this->value = $this->cache['COMMENT_END'][$_position]['value'];
1913
1914
            return $_success;
1915
        }
1916
1917
        if (substr($this->string, $this->position, strlen('-->')) === '-->') {
1918
            $_success = true;
1919
            $this->value = substr($this->string, $this->position, strlen('-->'));
1920
            $this->position += strlen('-->');
1921
        } else {
1922
            $_success = false;
1923
1924
            $this->report($this->position, '\'-->\'');
1925
        }
1926
1927
        $this->cache['COMMENT_END'][$_position] = array(
1928
            'success' => $_success,
1929
            'position' => $this->position,
1930
            'value' => $this->value
1931
        );
1932
1933
        if (!$_success) {
1934
            $this->report($_position, "-->");
1935
        }
1936
1937
        return $_success;
1938
    }
1939
1940
    protected function parseCOMMENT_END_COLD_FUSION()
1941
    {
1942
        $_position = $this->position;
1943
1944
        if (isset($this->cache['COMMENT_END_COLD_FUSION'][$_position])) {
1945
            $_success = $this->cache['COMMENT_END_COLD_FUSION'][$_position]['success'];
1946
            $this->position = $this->cache['COMMENT_END_COLD_FUSION'][$_position]['position'];
1947
            $this->value = $this->cache['COMMENT_END_COLD_FUSION'][$_position]['value'];
1948
1949
            return $_success;
1950
        }
1951
1952
        if (substr($this->string, $this->position, strlen('--->')) === '--->') {
1953
            $_success = true;
1954
            $this->value = substr($this->string, $this->position, strlen('--->'));
1955
            $this->position += strlen('--->');
1956
        } else {
1957
            $_success = false;
1958
1959
            $this->report($this->position, '\'--->\'');
1960
        }
1961
1962
        $this->cache['COMMENT_END_COLD_FUSION'][$_position] = array(
1963
            'success' => $_success,
1964
            'position' => $this->position,
1965
            'value' => $this->value
1966
        );
1967
1968
        if (!$_success) {
1969
            $this->report($_position, "--->");
1970
        }
1971
1972
        return $_success;
1973
    }
1974
1975
    protected function parseEOL()
1976
    {
1977
        $_position = $this->position;
1978
1979
        if (isset($this->cache['EOL'][$_position])) {
1980
            $_success = $this->cache['EOL'][$_position]['success'];
1981
            $this->position = $this->cache['EOL'][$_position]['position'];
1982
            $this->value = $this->cache['EOL'][$_position]['value'];
1983
1984
            return $_success;
1985
        }
1986
1987
        $_value99 = array();
1988
1989
        $_success = $this->parse_();
1990
1991
        if ($_success) {
1992
            $_value99[] = $this->value;
1993
1994
            $_position97 = $this->position;
1995
            $_cut98 = $this->cut;
1996
1997
            $this->cut = false;
1998
            if (substr($this->string, $this->position, strlen("\r")) === "\r") {
1999
                $_success = true;
2000
                $this->value = substr($this->string, $this->position, strlen("\r"));
2001
                $this->position += strlen("\r");
2002
            } else {
2003
                $_success = false;
2004
2005
                $this->report($this->position, '"\\r"');
2006
            }
2007
2008
            if (!$_success && !$this->cut) {
2009
                $_success = true;
2010
                $this->position = $_position97;
2011
                $this->value = null;
2012
            }
2013
2014
            $this->cut = $_cut98;
2015
        }
2016
2017
        if ($_success) {
2018
            $_value99[] = $this->value;
2019
2020
            if (substr($this->string, $this->position, strlen("\n")) === "\n") {
2021
                $_success = true;
2022
                $this->value = substr($this->string, $this->position, strlen("\n"));
2023
                $this->position += strlen("\n");
2024
            } else {
2025
                $_success = false;
2026
2027
                $this->report($this->position, '"\\n"');
2028
            }
2029
        }
2030
2031
        if ($_success) {
2032
            $_value99[] = $this->value;
2033
2034
            $this->value = $_value99;
2035
        }
2036
2037
        $this->cache['EOL'][$_position] = array(
2038
            'success' => $_success,
2039
            'position' => $this->position,
2040
            'value' => $this->value
2041
        );
2042
2043
        if (!$_success) {
2044
            $this->report($_position, "END_OF_LINE");
2045
        }
2046
2047
        return $_success;
2048
    }
2049
2050
    protected function parseEOF()
2051
    {
2052
        $_position = $this->position;
2053
2054
        if (isset($this->cache['EOF'][$_position])) {
2055
            $_success = $this->cache['EOF'][$_position]['success'];
2056
            $this->position = $this->cache['EOF'][$_position]['position'];
2057
            $this->value = $this->cache['EOF'][$_position]['value'];
2058
2059
            return $_success;
2060
        }
2061
2062
        $_position100 = $this->position;
2063
        $_cut101 = $this->cut;
2064
2065
        $this->cut = false;
2066
        if ($this->position < strlen($this->string)) {
2067
            $_success = true;
2068
            $this->value = substr($this->string, $this->position, 1);
2069
            $this->position += 1;
2070
        } else {
2071
            $_success = false;
2072
        }
2073
2074
        if (!$_success) {
2075
            $_success = true;
2076
            $this->value = null;
2077
        } else {
2078
            $_success = false;
2079
        }
2080
2081
        $this->position = $_position100;
2082
        $this->cut = $_cut101;
2083
2084
        $this->cache['EOF'][$_position] = array(
2085
            'success' => $_success,
2086
            'position' => $this->position,
2087
            'value' => $this->value
2088
        );
2089
2090
        if (!$_success) {
2091
            $this->report($_position, "END_OF_FILE");
2092
        }
2093
2094
        return $_success;
2095
    }
2096
2097
    protected function parse_()
2098
    {
2099
        $_position = $this->position;
2100
2101
        if (isset($this->cache['_'][$_position])) {
2102
            $_success = $this->cache['_'][$_position]['success'];
2103
            $this->position = $this->cache['_'][$_position]['position'];
2104
            $this->value = $this->cache['_'][$_position]['value'];
2105
2106
            return $_success;
2107
        }
2108
2109
        $_value105 = array();
2110
        $_cut106 = $this->cut;
2111
2112
        while (true) {
2113
            $_position104 = $this->position;
2114
2115
            $this->cut = false;
2116
            $_position102 = $this->position;
2117
            $_cut103 = $this->cut;
2118
2119
            $this->cut = false;
2120
            if (substr($this->string, $this->position, strlen(" ")) === " ") {
2121
                $_success = true;
2122
                $this->value = substr($this->string, $this->position, strlen(" "));
2123
                $this->position += strlen(" ");
2124
            } else {
2125
                $_success = false;
2126
2127
                $this->report($this->position, '" "');
2128
            }
2129
2130
            if (!$_success && !$this->cut) {
2131
                $this->position = $_position102;
2132
2133
                if (substr($this->string, $this->position, strlen("\t")) === "\t") {
2134
                    $_success = true;
2135
                    $this->value = substr($this->string, $this->position, strlen("\t"));
2136
                    $this->position += strlen("\t");
2137
                } else {
2138
                    $_success = false;
2139
2140
                    $this->report($this->position, '"\\t"');
2141
                }
2142
            }
2143
2144
            $this->cut = $_cut103;
2145
2146
            if (!$_success) {
2147
                break;
2148
            }
2149
2150
            $_value105[] = $this->value;
2151
        }
2152
2153
        if (!$this->cut) {
2154
            $_success = true;
2155
            $this->position = $_position104;
2156
            $this->value = $_value105;
2157
        }
2158
2159
        $this->cut = $_cut106;
2160
2161
        $this->cache['_'][$_position] = array(
2162
            'success' => $_success,
2163
            'position' => $this->position,
2164
            'value' => $this->value
2165
        );
2166
2167
        if (!$_success) {
2168
            $this->report($_position, '_');
2169
        }
2170
2171
        return $_success;
2172
    }
2173
2174
    private function line()
2175
    {
2176
        if (!empty($this->errors)) {
2177
            $positions = array_keys($this->errors);
2178
        } else {
2179
            $positions = array_keys($this->warnings);
2180
        }
2181
2182
        return count(explode("\n", substr($this->string, 0, max($positions))));
2183
    }
2184
2185
    private function rest()
2186
    {
2187
        return '"' . substr($this->string, $this->position) . '"';
2188
    }
2189
2190
    protected function report($position, $expecting)
2191
    {
2192
        if ($this->cut) {
2193
            $this->errors[$position][] = $expecting;
2194
        } else {
2195
            $this->warnings[$position][] = $expecting;
2196
        }
2197
    }
2198
2199
    private function expecting()
2200
    {
2201
        if (!empty($this->errors)) {
2202
            ksort($this->errors);
2203
2204
            return end($this->errors)[0];
2205
        }
2206
2207
        ksort($this->warnings);
2208
2209
        return implode(', ', end($this->warnings));
2210
    }
2211
2212
    public function parse($_string)
2213
    {
2214
        $this->string = $_string;
2215
        $this->position = 0;
2216
        $this->value = null;
2217
        $this->cache = array();
2218
        $this->cut = false;
2219
        $this->errors = array();
2220
        $this->warnings = array();
2221
2222
        $_success = $this->parseFILE();
2223
2224
        if ($_success && $this->position < strlen($this->string)) {
2225
            $_success = false;
2226
2227
            $this->report($this->position, "end of file");
2228
        }
2229
2230
        if (!$_success) {
2231
            throw new \InvalidArgumentException("Syntax error, expecting {$this->expecting()} on line {$this->line()}");
2232
        }
2233
2234
        return $this->value;
2235
    }
2236
}