c-lexer-stable 0.1.4

C lexer
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
use crate::{
    equivalence::{Equivalence, EQUIVALENCE_CLASS},
    error::Error,
    identifier,
    number::{parse_exponent, parse_number, parse_number_decimal, parse_number_radix},
    state::*,
    string,
    token::Token,
};
use std::str;

#[derive(Debug)]
struct StateMachine<S: State> {
    state: S,
}

impl<S: State> StateMachine<S> {
    #[allow(clippy::new_ret_no_self)]
    fn new() -> StateMachine<InputElementDiv> {
        StateMachine {
            state: InputElementDiv,
        }
    }

    fn is_final(&self) -> bool {
        self.state.is_final()
    }
}

#[derive(Debug)]
enum StateMachineWrapper {
    LineTerminator(StateMachine<LineTerminator>),
    WhiteSpace(StateMachine<WhiteSpace>),
    SingleLineCommentAcc(StateMachine<SingleLineCommentAcc>),
    MultiLineCommentAcc(StateMachine<MultiLineCommentAcc>),
    DotPart(StateMachine<DotPart>),
    Comma(StateMachine<Comma>),
    CommaAcc(StateMachine<CommaAcc>),
    Semicolon(StateMachine<Semicolon>),
    SemicolonAcc(StateMachine<SemicolonAcc>),
    LtAcc(StateMachine<LtAcc>),
    GtAcc(StateMachine<GtAcc>),
    AssignAcc(StateMachine<AssignAcc>),
    ExclamationAcc(StateMachine<ExclamationAcc>),
    PlusAcc(StateMachine<PlusAcc>),
    MinusAcc(StateMachine<MinusAcc>),
    MultiAcc(StateMachine<MultiAcc>),
    ModAcc(StateMachine<ModAcc>),
    AndAcc(StateMachine<AndAcc>),
    OrAcc(StateMachine<OrAcc>),
    Tilde(StateMachine<Tilde>),
    TildeAcc(StateMachine<TildeAcc>),
    QuestionMark(StateMachine<QuestionMark>),
    QuestionMarkAcc(StateMachine<QuestionMarkAcc>),
    ColonAcc(StateMachine<ColonAcc>),
    ExclusiveOrAcc(StateMachine<ExclusiveOrAcc>),
    String(StateMachine<String>),
    Char(StateMachine<Char>),
    BinaryAcc(StateMachine<BinaryAcc>),
    OctalAcc(StateMachine<OctalAcc>),
    HexAcc(StateMachine<HexAcc>),
    DecimalAcc(StateMachine<DecimalAcc>),
    DecimalDigitsAcc(StateMachine<DecimalDigitsAcc>),
    DecimalExponentAcc(StateMachine<DecimalExponentAcc>),
    DecimalExponentSignedAcc(StateMachine<DecimalExponentSignedAcc>),
    Identifier(StateMachine<Identifier>),
    SlashAcc(StateMachine<SlashAcc>),
    LBraceAcc(StateMachine<LBraceAcc>),
    RBraceAcc(StateMachine<RBraceAcc>),
    LParenAcc(StateMachine<LParenAcc>),
    RParenAcc(StateMachine<RParenAcc>),
    LBracketAcc(StateMachine<LBracketAcc>),
    RBracketAcc(StateMachine<RBracketAcc>),

    InputElementDiv(StateMachine<InputElementDiv>),
    Slash(StateMachine<Slash>),
    SingleLineComment(StateMachine<SingleLineComment>),
    MultiLineComment(StateMachine<MultiLineComment>),
    MultiLineCommentStar(StateMachine<MultiLineCommentStar>),
    Lt(StateMachine<Lt>),
    Gt(StateMachine<Gt>),
    Colon(StateMachine<Colon>),
    LBrace(StateMachine<LBrace>),
    LParen(StateMachine<LParen>),
    RParen(StateMachine<RParen>),
    LBracket(StateMachine<LBracket>),
    RBracket(StateMachine<RBracket>),
    RBrace(StateMachine<RBrace>),
    Assign(StateMachine<Assign>),
    Exclamation(StateMachine<Exclamation>),
    Plus(StateMachine<Plus>),
    Minus(StateMachine<Minus>),
    Multi(StateMachine<Multi>),
    Mod(StateMachine<Mod>),
    And(StateMachine<And>),
    Or(StateMachine<Or>),
    ExclusiveOr(StateMachine<ExclusiveOr>),
    SawZero(StateMachine<SawZero>),
    Binary(StateMachine<Binary>),
    Octal(StateMachine<Octal>),
    Hex(StateMachine<Hex>),
    Decimal(StateMachine<Decimal>),
    DecimalDigits(StateMachine<DecimalDigits>),
    DecimalExponent(StateMachine<DecimalExponent>),
    DecimalExponentSigned(StateMachine<DecimalExponentSigned>),
}

edge!(InputElementDiv, LineTerminator);
edge!(InputElementDiv, WhiteSpace);
edge!(InputElementDiv, Slash);
edge!(InputElementDiv, DotPart);
edge!(Slash, SlashAcc);
edge!(Slash, SingleLineComment);
edge!(Slash, MultiLineComment);
edge!(SingleLineComment, SingleLineCommentAcc);
edge!(MultiLineComment, MultiLineCommentStar);
edge!(MultiLineCommentStar, MultiLineCommentAcc);
edge!(InputElementDiv, Identifier);
edge!(InputElementDiv, LBrace);
edge!(LBrace, LBraceAcc);
edge!(InputElementDiv, RBrace);
edge!(RBrace, RBraceAcc);
edge!(InputElementDiv, LParen);
edge!(LParen, LParenAcc);
edge!(InputElementDiv, RParen);
edge!(RParen, RParenAcc);
edge!(InputElementDiv, LBracket);
edge!(LBracket, LBracketAcc);
edge!(InputElementDiv, RBracket);
edge!(RBracket, RBracketAcc);
edge!(InputElementDiv, Semicolon);
edge!(Semicolon, SemicolonAcc);
edge!(InputElementDiv, Comma);
edge!(Comma, CommaAcc);
edge!(InputElementDiv, Colon);
edge!(Colon, ColonAcc);
edge!(InputElementDiv, QuestionMark);
edge!(QuestionMark, QuestionMarkAcc);
edge!(InputElementDiv, Tilde);
edge!(Tilde, TildeAcc);
edge!(InputElementDiv, Lt);
edge!(Lt, LtAcc);
edge!(InputElementDiv, Gt);
edge!(Gt, GtAcc);
edge!(InputElementDiv, Assign);
edge!(Assign, AssignAcc);
edge!(InputElementDiv, Exclamation);
edge!(Exclamation, ExclamationAcc);
edge!(InputElementDiv, Plus);
edge!(Plus, PlusAcc);
edge!(InputElementDiv, Multi);
edge!(Multi, MultiAcc);
edge!(InputElementDiv, Mod);
edge!(Mod, ModAcc);
edge!(InputElementDiv, Minus);
edge!(Minus, MinusAcc);
edge!(InputElementDiv, Or);
edge!(Or, OrAcc);
edge!(InputElementDiv, ExclusiveOr);
edge!(ExclusiveOr, ExclusiveOrAcc);
edge!(InputElementDiv, String);
edge!(InputElementDiv, Char);
edge!(And, AndAcc);
edge!(InputElementDiv, And);
edge!(InputElementDiv, SawZero);
edge!(SawZero, Decimal);
edge!(SawZero, DecimalAcc);
edge!(InputElementDiv, Decimal);
edge!(Decimal, DecimalAcc);
edge!(Decimal, DecimalExponent);
edge!(DecimalDigits, DecimalExponent);
edge!(DecimalDigits, DecimalDigitsAcc);
edge!(DecimalExponent, DecimalExponentSigned);
edge!(DecimalExponentSigned, DecimalExponentSignedAcc);
edge!(DecimalExponent, DecimalExponentAcc);
edge!(Decimal, DecimalDigits);
edge!(InputElementDiv, Hex);
edge!(Hex, HexAcc);
edge!(SawZero, Hex);
edge!(InputElementDiv, Binary);
edge!(Binary, BinaryAcc);
edge!(SawZero, Binary);
edge!(InputElementDiv, Octal);
edge!(Octal, OctalAcc);
edge!(SawZero, Octal);
edge!(MultiLineCommentStar, MultiLineComment);
edge!(LineTerminator, HELL);

impl StateMachineWrapper {
    #[inline]
    fn step(self, e: Equivalence) -> Self {
        match (self, e) {
            (StateMachineWrapper::InputElementDiv(s), Equivalence::LineTerminator) => {
                StateMachineWrapper::LineTerminator(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::White) => {
                StateMachineWrapper::WhiteSpace(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Slash) => {
                StateMachineWrapper::Slash(s.into())
            } // /
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Dot) => {
                StateMachineWrapper::DotPart(s.into())
            }
            (StateMachineWrapper::Slash(s), Equivalence::Assign) => {
                StateMachineWrapper::SlashAcc(s.into())
            } // /
            (StateMachineWrapper::Slash(s), Equivalence::Slash) => {
                StateMachineWrapper::SingleLineComment(s.into())
            } // //
            (StateMachineWrapper::Slash(s), Equivalence::Multi) => {
                StateMachineWrapper::MultiLineComment(s.into())
            }
            (StateMachineWrapper::Slash(s), _) => StateMachineWrapper::SlashAcc(s.into()),

            // single line comment
            (StateMachineWrapper::SingleLineComment(s), Equivalence::LineTerminator) => {
                StateMachineWrapper::SingleLineCommentAcc(s.into())
            }
            (StateMachineWrapper::SingleLineComment(s), _) => {
                StateMachineWrapper::SingleLineComment(s)
            }

            // Multiline comment
            (StateMachineWrapper::MultiLineComment(s), Equivalence::Multi) => {
                StateMachineWrapper::MultiLineCommentStar(s.into())
            }
            (StateMachineWrapper::MultiLineCommentStar(s), Equivalence::Multi) => {
                StateMachineWrapper::MultiLineCommentStar(s)
            }
            (StateMachineWrapper::MultiLineCommentStar(s), Equivalence::Slash) => {
                StateMachineWrapper::MultiLineCommentAcc(s.into())
            }

            (StateMachineWrapper::MultiLineComment(s), _) => {
                StateMachineWrapper::MultiLineComment(s)
            }
            (StateMachineWrapper::MultiLineCommentStar(s), _) => {
                StateMachineWrapper::MultiLineComment(s.into())
            }
            // Identifier
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Letter) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::A) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::B) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::C) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::D) => {
                StateMachineWrapper::Identifier(s.into())
            }

            (StateMachineWrapper::InputElementDiv(s), Equivalence::E) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::F) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::O) => {
                StateMachineWrapper::Identifier(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::X) => {
                StateMachineWrapper::Identifier(s.into())
            }

            // Punctuator
            (StateMachineWrapper::LBrace(s), _) => StateMachineWrapper::LBraceAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::LBrace) => {
                StateMachineWrapper::LBrace(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::RBrace) => {
                StateMachineWrapper::RBrace(s.into())
            }
            (StateMachineWrapper::RBrace(s), _) => StateMachineWrapper::RBraceAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::LParen) => {
                StateMachineWrapper::LParen(s.into())
            }
            (StateMachineWrapper::LParen(s), _) => StateMachineWrapper::LParenAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::RParen) => {
                StateMachineWrapper::RParen(s.into())
            }
            (StateMachineWrapper::RParen(s), _) => StateMachineWrapper::RParenAcc(s.into()),

            (StateMachineWrapper::InputElementDiv(s), Equivalence::LBracket) => {
                StateMachineWrapper::LBracket(s.into())
            }
            (StateMachineWrapper::LBracket(s), _) => StateMachineWrapper::LBracketAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::RBracket) => {
                StateMachineWrapper::RBracket(s.into())
            }

            (StateMachineWrapper::RBracket(s), _) => StateMachineWrapper::RBracketAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Semicolon) => {
                StateMachineWrapper::Semicolon(s.into())
            }
            (StateMachineWrapper::Semicolon(s), _) => StateMachineWrapper::SemicolonAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Comma) => {
                StateMachineWrapper::Comma(s.into())
            }
            (StateMachineWrapper::Comma(s), _) => StateMachineWrapper::CommaAcc(s.into()),
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Colon) => {
                StateMachineWrapper::Colon(s.into())
            }
            (StateMachineWrapper::Colon(s), _) => StateMachineWrapper::ColonAcc(s.into()),

            (StateMachineWrapper::InputElementDiv(s), Equivalence::QuestionMark) => {
                StateMachineWrapper::QuestionMark(s.into())
            }
            (StateMachineWrapper::QuestionMark(s), _) => {
                StateMachineWrapper::QuestionMarkAcc(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Tilde) => {
                StateMachineWrapper::Tilde(s.into())
            }

            (StateMachineWrapper::Tilde(s), _) => StateMachineWrapper::TildeAcc(s.into()),

            // Less than
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Lt) => {
                StateMachineWrapper::Lt(s.into())
            }
            (StateMachineWrapper::Lt(s), Equivalence::Assign) => StateMachineWrapper::Lt(s),
            (StateMachineWrapper::Lt(s), Equivalence::Lt) => StateMachineWrapper::Lt(s),
            (StateMachineWrapper::Lt(s), _) => StateMachineWrapper::LtAcc(s.into()),

            // Greater than
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Gt) => {
                StateMachineWrapper::Gt(s.into())
            }
            (StateMachineWrapper::Gt(s), Equivalence::Assign) => StateMachineWrapper::Gt(s),
            (StateMachineWrapper::Gt(s), Equivalence::Gt) => StateMachineWrapper::Gt(s),
            (StateMachineWrapper::Gt(s), _) => StateMachineWrapper::GtAcc(s.into()),

            // Assign
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Assign) => {
                StateMachineWrapper::Assign(s.into())
            }
            (StateMachineWrapper::Assign(s), Equivalence::Assign) => StateMachineWrapper::Assign(s),
            (StateMachineWrapper::Assign(s), _) => StateMachineWrapper::AssignAcc(s.into()),

            // Exclamation
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Exclamation) => {
                StateMachineWrapper::Exclamation(s.into())
            }
            (StateMachineWrapper::Exclamation(s), Equivalence::Assign) => {
                StateMachineWrapper::Exclamation(s)
            }
            (StateMachineWrapper::Exclamation(s), _) => {
                StateMachineWrapper::ExclamationAcc(s.into())
            }

            // Plus
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Plus) => {
                StateMachineWrapper::Plus(s.into())
            }

            (StateMachineWrapper::Plus(s), Equivalence::Plus) => StateMachineWrapper::Plus(s),

            (StateMachineWrapper::Plus(s), Equivalence::Assign) => StateMachineWrapper::Plus(s),

            (StateMachineWrapper::Plus(s), _) => StateMachineWrapper::PlusAcc(s.into()),

            // Minus
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Minus) => {
                StateMachineWrapper::Minus(s.into())
            }
            (StateMachineWrapper::Minus(s), Equivalence::Minus) => StateMachineWrapper::Minus(s),
            (StateMachineWrapper::Minus(s), Equivalence::Gt) => StateMachineWrapper::Minus(s),
            (StateMachineWrapper::Minus(s), Equivalence::Assign) => StateMachineWrapper::Minus(s),
            (StateMachineWrapper::Minus(s), _) => StateMachineWrapper::MinusAcc(s.into()),

            // Multi
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Multi) => {
                StateMachineWrapper::Multi(s.into())
            }
            (StateMachineWrapper::Multi(s), Equivalence::Multi) => StateMachineWrapper::Multi(s),
            (StateMachineWrapper::Multi(s), Equivalence::Assign) => StateMachineWrapper::Multi(s),
            (StateMachineWrapper::Multi(s), _) => StateMachineWrapper::MultiAcc(s.into()),

            // Mod
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Mod) => {
                StateMachineWrapper::Mod(s.into())
            }
            (StateMachineWrapper::Mod(s), Equivalence::Mod) => StateMachineWrapper::Mod(s),
            (StateMachineWrapper::Mod(s), Equivalence::Assign) => StateMachineWrapper::Mod(s),
            (StateMachineWrapper::Mod(s), _) => StateMachineWrapper::ModAcc(s.into()),

            // and
            (StateMachineWrapper::InputElementDiv(s), Equivalence::SingleAnd) => {
                StateMachineWrapper::And(s.into())
            }
            (StateMachineWrapper::And(s), Equivalence::SingleAnd) => StateMachineWrapper::And(s),
            (StateMachineWrapper::And(s), Equivalence::Assign) => StateMachineWrapper::And(s),
            (StateMachineWrapper::And(s), _) => StateMachineWrapper::AndAcc(s.into()),
            // or
            (StateMachineWrapper::InputElementDiv(s), Equivalence::InclusiveOr) => {
                StateMachineWrapper::Or(s.into())
            }

            (StateMachineWrapper::Or(s), Equivalence::InclusiveOr) => StateMachineWrapper::Or(s),
            (StateMachineWrapper::Or(s), Equivalence::Assign) => StateMachineWrapper::Or(s),
            (StateMachineWrapper::Or(s), _) => StateMachineWrapper::OrAcc(s.into()),
            // ExclusiveOr
            (StateMachineWrapper::InputElementDiv(s), Equivalence::ExclusiveOr) => {
                StateMachineWrapper::ExclusiveOr(s.into())
            }
            (StateMachineWrapper::ExclusiveOr(s), Equivalence::ExclusiveOr) => {
                StateMachineWrapper::ExclusiveOr(s)
            }
            (StateMachineWrapper::ExclusiveOr(s), Equivalence::Assign) => {
                StateMachineWrapper::ExclusiveOr(s)
            }
            (StateMachineWrapper::ExclusiveOr(s), _) => {
                StateMachineWrapper::ExclusiveOrAcc(s.into())
            }

            // string
            (StateMachineWrapper::InputElementDiv(s), Equivalence::String) => {
                StateMachineWrapper::String(s.into())
            }

            (StateMachineWrapper::InputElementDiv(s), Equivalence::Char) => {
                StateMachineWrapper::Char(s.into())
            }
            // numbers
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Zero) => {
                StateMachineWrapper::SawZero(s.into())
            }

            (StateMachineWrapper::InputElementDiv(s), Equivalence::One) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Two) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Three) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Four) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Five) => {
                StateMachineWrapper::Decimal(s.into())
            }

            (StateMachineWrapper::InputElementDiv(s), Equivalence::Six) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::Seven) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::InputElementDiv(s), Equivalence::EightNine) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::B) => {
                StateMachineWrapper::Binary(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::O) => {
                StateMachineWrapper::Octal(s.into())
            }

            (StateMachineWrapper::SawZero(s), Equivalence::X) => StateMachineWrapper::Hex(s.into()),
            (StateMachineWrapper::SawZero(s), Equivalence::One) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::Two) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::Three) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::Four) => {
                StateMachineWrapper::Decimal(s.into())
            }

            (StateMachineWrapper::SawZero(s), Equivalence::Five) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::Six) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::Seven) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), Equivalence::EightNine) => {
                StateMachineWrapper::Decimal(s.into())
            }
            (StateMachineWrapper::SawZero(s), _) => StateMachineWrapper::DecimalAcc(s.into()),
            (StateMachineWrapper::Decimal(s), Equivalence::Zero) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::One) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::Two) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::Three) => {
                StateMachineWrapper::Decimal(s)
            }
            (StateMachineWrapper::Decimal(s), Equivalence::Four) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::Five) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::Six) => StateMachineWrapper::Decimal(s),
            (StateMachineWrapper::Decimal(s), Equivalence::Seven) => {
                StateMachineWrapper::Decimal(s)
            }
            (StateMachineWrapper::Decimal(s), Equivalence::EightNine) => {
                StateMachineWrapper::Decimal(s)
            }
            (StateMachineWrapper::Decimal(s), Equivalence::Dot) => {
                StateMachineWrapper::DecimalDigits(s.into())
            }
            (StateMachineWrapper::Decimal(s), Equivalence::E) => {
                StateMachineWrapper::DecimalExponent(s.into())
            }
            (StateMachineWrapper::Decimal(s), _) => StateMachineWrapper::DecimalAcc(s.into()),
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Zero) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::One) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Two) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Three) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Four) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Five) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Six) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::Seven) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::EightNine) => {
                StateMachineWrapper::DecimalDigits(s)
            }
            (StateMachineWrapper::DecimalDigits(s), Equivalence::E) => {
                StateMachineWrapper::DecimalExponent(s.into())
            }
            (StateMachineWrapper::DecimalDigits(s), _) => {
                StateMachineWrapper::DecimalDigitsAcc(s.into())
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Zero) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::One) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Two) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Three) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Four) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Five) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Six) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Seven) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::EightNine) => {
                StateMachineWrapper::DecimalExponent(s)
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Minus) => {
                StateMachineWrapper::DecimalExponentSigned(s.into())
            }
            (StateMachineWrapper::DecimalExponent(s), Equivalence::Plus) => {
                StateMachineWrapper::DecimalExponentSigned(s.into())
            }
            (StateMachineWrapper::DecimalExponent(s), _) => {
                StateMachineWrapper::DecimalExponentAcc(s.into())
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Zero) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::One) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Two) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Three) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Four) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Five) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Six) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Seven) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), Equivalence::EightNine) => {
                StateMachineWrapper::DecimalExponentSigned(s)
            }
            (StateMachineWrapper::DecimalExponentSigned(s), _) => {
                StateMachineWrapper::DecimalExponentSignedAcc(s.into())
            }
            (StateMachineWrapper::Octal(s), Equivalence::Zero) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::One) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Two) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Three) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Four) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Five) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Six) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), Equivalence::Seven) => StateMachineWrapper::Octal(s),
            (StateMachineWrapper::Octal(s), _) => StateMachineWrapper::OctalAcc(s.into()),
            (StateMachineWrapper::Hex(s), Equivalence::Zero) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::One) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Two) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Three) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Four) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Five) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Six) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::Seven) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::EightNine) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::A) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::B) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::C) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::D) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::E) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), Equivalence::F) => StateMachineWrapper::Hex(s),
            (StateMachineWrapper::Hex(s), _) => StateMachineWrapper::HexAcc(s.into()),
            (StateMachineWrapper::Binary(s), Equivalence::One) => StateMachineWrapper::Binary(s),
            (StateMachineWrapper::Binary(s), Equivalence::Zero) => StateMachineWrapper::Binary(s),
            (StateMachineWrapper::Binary(s), _) => StateMachineWrapper::BinaryAcc(s.into()),
            (_, Equivalence::HELL) => {
                StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new())
            }
            a => unreachable!("Invalid state:  {:?} ", a),
        }
    }

    #[inline]
    fn is_final(&self) -> bool {
        match self {
            StateMachineWrapper::LineTerminator(n) => n.is_final(),
            StateMachineWrapper::WhiteSpace(n) => n.is_final(),
            StateMachineWrapper::SingleLineCommentAcc(n) => n.is_final(),
            StateMachineWrapper::MultiLineCommentAcc(n) => n.is_final(),
            StateMachineWrapper::LBrace(n) => n.is_final(),
            StateMachineWrapper::LBraceAcc(n) => n.is_final(),
            StateMachineWrapper::LParen(n) => n.is_final(),
            StateMachineWrapper::RParen(n) => n.is_final(),
            StateMachineWrapper::LBracket(n) => n.is_final(),
            StateMachineWrapper::RBracket(n) => n.is_final(),
            StateMachineWrapper::LParenAcc(n) => n.is_final(),
            StateMachineWrapper::RParenAcc(n) => n.is_final(),
            StateMachineWrapper::LBracketAcc(n) => n.is_final(),
            StateMachineWrapper::RBracketAcc(n) => n.is_final(),
            StateMachineWrapper::DotPart(n) => n.is_final(),
            StateMachineWrapper::Comma(n) => n.is_final(),
            StateMachineWrapper::CommaAcc(n) => n.is_final(),
            StateMachineWrapper::Semicolon(n) => n.is_final(),
            StateMachineWrapper::SemicolonAcc(n) => n.is_final(),
            StateMachineWrapper::LtAcc(n) => n.is_final(),
            StateMachineWrapper::GtAcc(n) => n.is_final(),
            StateMachineWrapper::AssignAcc(n) => n.is_final(),
            StateMachineWrapper::ExclamationAcc(n) => n.is_final(),
            StateMachineWrapper::PlusAcc(n) => n.is_final(),
            StateMachineWrapper::MinusAcc(n) => n.is_final(),
            StateMachineWrapper::MultiAcc(n) => n.is_final(),
            StateMachineWrapper::ModAcc(n) => n.is_final(),
            StateMachineWrapper::AndAcc(n) => n.is_final(),
            StateMachineWrapper::OrAcc(n) => n.is_final(),
            StateMachineWrapper::Tilde(n) => n.is_final(),
            StateMachineWrapper::TildeAcc(n) => n.is_final(),
            StateMachineWrapper::QuestionMark(n) => n.is_final(),
            StateMachineWrapper::QuestionMarkAcc(n) => n.is_final(),
            StateMachineWrapper::ColonAcc(n) => n.is_final(),
            StateMachineWrapper::ExclusiveOrAcc(n) => n.is_final(),
            StateMachineWrapper::String(n) => n.is_final(),
            StateMachineWrapper::Char(n) => n.is_final(),
            StateMachineWrapper::BinaryAcc(n) => n.is_final(),
            StateMachineWrapper::OctalAcc(n) => n.is_final(),
            StateMachineWrapper::HexAcc(n) => n.is_final(),
            StateMachineWrapper::DecimalAcc(n) => n.is_final(),
            StateMachineWrapper::DecimalDigitsAcc(n) => n.is_final(),
            StateMachineWrapper::DecimalExponentAcc(n) => n.is_final(),
            StateMachineWrapper::DecimalExponentSignedAcc(n) => n.is_final(),
            StateMachineWrapper::Identifier(n) => n.is_final(),
            StateMachineWrapper::SlashAcc(n) => n.is_final(),
            StateMachineWrapper::RBrace(n) => n.is_final(),
            StateMachineWrapper::RBraceAcc(n) => n.is_final(),

            StateMachineWrapper::InputElementDiv(n) => n.is_final(),
            StateMachineWrapper::Slash(n) => n.is_final(),
            StateMachineWrapper::SingleLineComment(n) => n.is_final(),
            StateMachineWrapper::MultiLineComment(n) => n.is_final(),
            StateMachineWrapper::Colon(n) => n.is_final(),
            StateMachineWrapper::MultiLineCommentStar(n) => n.is_final(),
            StateMachineWrapper::Lt(n) => n.is_final(),
            StateMachineWrapper::Gt(n) => n.is_final(),
            StateMachineWrapper::Assign(n) => n.is_final(),
            StateMachineWrapper::Exclamation(n) => n.is_final(),
            StateMachineWrapper::Plus(n) => n.is_final(),
            StateMachineWrapper::Minus(n) => n.is_final(),
            StateMachineWrapper::Multi(n) => n.is_final(),
            StateMachineWrapper::Mod(n) => n.is_final(),
            StateMachineWrapper::And(n) => n.is_final(),
            StateMachineWrapper::Or(n) => n.is_final(),
            StateMachineWrapper::ExclusiveOr(n) => n.is_final(),
            StateMachineWrapper::SawZero(n) => n.is_final(),
            StateMachineWrapper::Binary(n) => n.is_final(),
            StateMachineWrapper::Octal(n) => n.is_final(),
            StateMachineWrapper::Hex(n) => n.is_final(),
            StateMachineWrapper::Decimal(n) => n.is_final(),
            StateMachineWrapper::DecimalDigits(n) => n.is_final(),
            StateMachineWrapper::DecimalExponent(n) => n.is_final(),
            StateMachineWrapper::DecimalExponentSigned(n) => n.is_final(),
        }
    }
}

#[inline]
pub fn parse(input: &str) -> Result<Vec<Token>, Error> {
    let mut st = StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new());
    let input = input.as_bytes();
    let input_len = input.len();
    let mut tokens = Vec::with_capacity(input.len());

    let mut c_src: usize = 0;
    let mut token_len: u64 = 0;
    while c_src < input_len {
        while !st.is_final() {
            let ch = unsafe { *input.get_unchecked(c_src) };
            st = st.step(EQUIVALENCE_CLASS[ch as usize]);
            c_src += 1;
            token_len += 1;
        }
        if c_src >= input_len {
            break;
        }
        let token = &input[c_src - token_len as usize..c_src - 1];
        let token = unsafe { str::from_utf8_unchecked(token) };
        let token = super::token::TOKENS
            .get(token)
            .cloned()
            .or_else(|| state_match(st, input, &mut c_src, token_len).unwrap());
        c_src -= 1;
        if let Some(tok) = token {
            tokens.push(tok);
        }

        st = StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new());
        token_len = 0;
    }
    Ok(tokens)
}

#[inline]
fn state_match(
    st: StateMachineWrapper,
    input: &[u8],
    c_src: &mut usize,
    token_len: u64,
) -> Result<Option<Token>, Error> {
    let res = match st {
        StateMachineWrapper::LineTerminator(_) => Some(Token::LineTerminator),
        // LF after comment is not considered to be part of comment
        // and should be left. We can parse it as part of single line
        // comment and replace comment with line terminator
        StateMachineWrapper::SingleLineCommentAcc(_) => Some(Token::LineTerminator),
        StateMachineWrapper::MultiLineCommentAcc(_) => None,
        StateMachineWrapper::SlashAcc(_) => {
            if input[*c_src - token_len as usize + 1] == b'=' {
                Some(Token::DivAssign)
            } else {
                Some(Token::Slash)
            }
        }
        StateMachineWrapper::String(_) => Some(string::parse_string(input, c_src)),
        StateMachineWrapper::Char(_) => Some(string::parse_char(input, c_src)),
        StateMachineWrapper::BinaryAcc(_) => Some(parse_number_radix(input, c_src, token_len, 2)?),
        StateMachineWrapper::OctalAcc(_) => Some(parse_number_radix(input, c_src, token_len, 8)?),
        StateMachineWrapper::HexAcc(_) => Some(parse_number_radix(input, c_src, token_len, 16)?),
        StateMachineWrapper::DecimalAcc(_) => Some(parse_number(input, c_src, token_len)?),
        StateMachineWrapper::DotPart(_) => Some(parse_dot(input, c_src)),
        StateMachineWrapper::DecimalDigitsAcc(_) => {
            Some(parse_number_decimal(input, c_src, token_len)?)
        }
        StateMachineWrapper::DecimalExponentSignedAcc(_) => {
            Some(parse_exponent(input, c_src, token_len)?)
        }
        StateMachineWrapper::DecimalExponentAcc(_) => {
            Some(parse_exponent(input, c_src, token_len)?)
        }
        StateMachineWrapper::Identifier(_) => Some(identifier::parse_identifier(input, c_src)),
        _ => None,
    };
    *c_src += 1;
    Ok(res)
}

#[inline]
fn parse_dot(input: &[u8], c_src: &mut usize) -> Token {
    let rest_len = input.len() - *c_src;
    if rest_len >= 2 && input[*c_src] == b'.' && input[*c_src + 1] == b'.' {
        *c_src += 2;
        return Token::ELLIPSIS;
    }

    Token::Dot
}

#[cfg(test)]
mod tests {
    use super::super::*;

    should!(
        lineterminator_all,
        "\u{000A}\u{000D}",
        vec![Token::LineTerminator, Token::LineTerminator, Token::EOF]
    );

    should!(
        single_comment,
        "// rest // of comment \n",
        vec![Token::LineTerminator, Token::EOF]
    );

    should!(multi_comment, "/** rest // of comment */", vec![Token::EOF]);

    should!(
        multi_comment_with_newline,
        "/** rest // \n of comment */",
        vec![Token::EOF]
    );

    should!(left_curly, "{", vec![Token::LBrace, Token::EOF]);

    should!(right_curly, "}", vec![Token::RBrace, Token::EOF]);

    should!(left_round, "(", vec![Token::LParen, Token::EOF]);

    should!(right_round, ")", vec![Token::RParen, Token::EOF]);

    should!(left_square, "[", vec![Token::LBracket, Token::EOF]);

    should!(right_square, "]", vec![Token::RBracket, Token::EOF]);

    should!(dot, ".", vec![Token::Dot, Token::EOF]);

    should!(twodot, "..", vec![Token::Dot, Token::Dot, Token::EOF]);

    should!(tripledot, "...", vec![Token::ELLIPSIS, Token::EOF]);

    should!(
        fourdot,
        "....",
        vec![Token::ELLIPSIS, Token::Dot, Token::EOF]
    );

    should!(lesser, "< ", vec![Token::Lt, Token::EOF]);

    should!(lesser_double, "<< ", vec![Token::LeftOp, Token::EOF]);

    should!(lesser_equal, "<= ", vec![Token::LeOp, Token::EOF]);

    should!(
        lesser_equal_double,
        "<<= ",
        vec![Token::LeftAssign, Token::EOF]
    );

    should!(bigger, "> ", vec![Token::Gt, Token::EOF]);

    should!(bigger_equal, ">= ", vec![Token::GeOp, Token::EOF]);

    should!(bigger_double, ">> ", vec![Token::RightOp, Token::EOF]);

    should!(
        bigger_double_equal,
        ">>= ",
        vec![Token::RightAssign, Token::EOF]
    );

    should!(assign, "= ", vec![Token::Assign, Token::EOF]);

    should!(ptr_op, "-> ", vec![Token::PtrOp, Token::EOF]);

    should!(assign_double, "== ", vec![Token::EqOp, Token::EOF]);

    should!(exclamation, "! ", vec![Token::Exclamation, Token::EOF]);

    should!(exclamation_assign, "!= ", vec![Token::NeOp, Token::EOF]);

    should!(plus, "+ ", vec![Token::Plus, Token::EOF]);

    should!(plus_dobule, "++ ", vec![Token::IncOp, Token::EOF]);

    should!(plus_assign, "+= ", vec![Token::AddAssign, Token::EOF]);

    should!(minus, "- ", vec![Token::Minus, Token::EOF]);

    should!(minus_double, "-- ", vec![Token::DecOp, Token::EOF]);

    should!(minus_assign, "-= ", vec![Token::SubAssign, Token::EOF]);

    should!(star, "* ", vec![Token::Multi, Token::EOF]);

    should!(star_assign, "*= ", vec![Token::MulAssign, Token::EOF]);

    should!(percent, "% ", vec![Token::Mod, Token::EOF]);

    should!(percent_assign, "%= ", vec![Token::ModAssign, Token::EOF]);

    should!(and, "& ", vec![Token::SingleAnd, Token::EOF]);

    should!(and_double, "&& ", vec![Token::AndOp, Token::EOF]);

    should!(and_assign, "&= ", vec![Token::AndAssign, Token::EOF]);

    should!(or, "| ", vec![Token::InclusiveOr, Token::EOF]);

    should!(or_double, "|| ", vec![Token::OrOp, Token::EOF]);

    should!(or_assign, "|= ", vec![Token::OrAssign, Token::EOF]);

    should!(tilde, "~ ", vec![Token::Tilde, Token::EOF]);

    should!(colon, ": ", vec![Token::Colon, Token::EOF]);

    should!(questionmark, "?", vec![Token::QuestionMark, Token::EOF]);

    should!(caret, "^ ", vec![Token::ExclusiveOr, Token::EOF]);

    should!(caret_assign, "^= ", vec![Token::XorAssign, Token::EOF]);

    should!(slash_assign, "/= ", vec![Token::DivAssign, Token::EOF]);

    should!(slash, "/ ", vec![Token::Slash, Token::EOF]);

    should!(keyowrd, "auto ", vec![Token::AUTO, Token::EOF]);

    should!(comma, ", ", vec![Token::Comma, Token::EOF]);

    // should_fail!(string_single, "'cau\n'",
    // vec![Token::StringLiteral(String::from("cau")), Token::EOF]);
}