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
// < !! WARNING !! >
//
// the order of variants in `enum Token` and `enum CharacterType` **must** be kept in sync with the state transition
// table `TRANSITIONS` - we directly cast `Token` and `CharacterType` variants into `usizes` to index into the
// transition table to find the next state transition.
use crate::Error;
#[repr(usize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CharacterType {
Space, // space
Whitespace, // other whitespace
BraceOpen, // {
BraceClose, // }
BracketOpen, // [
BracketClose, // ]
Colon, // :
Comma, // ,
Quote, // "
Backslash, // \
Slash, // /
Plus, // +
Minus, // -
Dot, // .
Zero, // 0
Digit, // 123456789
LowA, // a
LowB, // b
LowC, // c
LowD, // d
LowE, // e
LowF, // f
LowL, // l
LowN, // n
LowR, // r
LowS, // s
LowT, // t
LowU, // u
Abcdf, // ABCDF
E, // E
Other, // all other characters
Error, // error-type. will never be returned / passed outside this module.
}
#[repr(usize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Token {
Begin, // <begin>
Ok, // <ok>
Object, // object
Key, // key
Colon, // colon
Value, // value
Array, // array
String, // string
Escape, // escape
U1, // u1
U2, // u2
U3, // u3
U4, // u4
Minus, // minus
Zero, // zero
Integer, // integer
Fraction1, // fraction 1
Fraction2, // fraction 2
Exponent1, // exponent 1
Exponent2, // exponent 2
Exponent3, // exponent 3
TrueTr, // tr
TrueTru, // tru
TrueTrue, // true
FalseFa, // fa
FalseFal, // fal
FalseFals, // fals
FalseFalse, // false
NullNu, // nu
NullNul, // nul
NullNull, // null
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComplexToken {
BraceEmptyClose, // } - empty brace
BraceClose, // }
BracketClose, // ]
BraceOpen, // {
BracketOpen, // [
Quote, // "
Comma, // ,
Kolon, // :
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Transition {
Simple(Token),
Complex(ComplexToken),
Error, // error-type. will never be returned / passed outside this module.
}
#[rustfmt::skip]
const TRANSITIONS: [[Transition; 31]; 31] = {
use self::{
ComplexToken::{
BraceClose, BraceEmptyClose, BraceOpen, BracketClose, BracketOpen, Comma, Kolon, Quote,
},
Token::{
Array, Begin, Colon, Escape, Exponent1, Exponent2, Exponent3, FalseFa, FalseFal,
FalseFals, FalseFalse, Fraction1, Fraction2, Integer, Key, Minus, NullNu, NullNul,
NullNull, Object, Ok, String, TrueTr, TrueTru, TrueTrue, Value, Zero, U1, U2, U3, U4,
},
Transition::{Complex, Error, Simple},
};
[
// <space> <other-white-space> { } [ ] : , " \ / + - . 0 <123456789> a b c d e f l n r s t u <ABCDF> E <...>
/* continue */ [ Simple(Begin), Simple(Begin), Complex(BraceOpen), Error, Complex(BracketOpen), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* ok */ [ Simple(Ok), Simple(Ok), Error, Complex(BraceClose), Error, Complex(BracketClose), Error, Complex(Comma), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* object */ [ Simple(Object), Simple(Object), Error, Complex(BraceEmptyClose), Error, Error, Error, Error, Simple(String), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* key */ [ Simple(Key), Simple(Key), Error, Error, Error, Error, Error, Error, Simple(String), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* colon */ [ Simple(Colon), Simple(Colon), Error, Error, Error, Error, Complex(Kolon), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* value */ [ Simple(Value), Simple(Value), Complex(BraceOpen), Error, Complex(BracketOpen), Error, Error, Error, Simple(String), Error, Error, Error, Simple(Minus), Error, Simple(Zero), Simple(Integer), Error, Error, Error, Error, Error, Simple(FalseFa), Error, Simple(NullNu), Error, Error, Simple(TrueTr), Error, Error, Error, Error],
/* array */ [ Simple(Array), Simple(Array), Complex(BraceOpen), Error, Complex(BracketOpen), Complex(BracketClose), Error, Error, Simple(String), Error, Error, Error, Simple(Minus), Error, Simple(Zero), Simple(Integer), Error, Error, Error, Error, Error, Simple(FalseFa), Error, Simple(NullNu), Error, Error, Simple(TrueTr), Error, Error, Error, Error],
/* string */ [ Simple(String), Error, Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Complex(Quote), Simple(Escape), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String)],
/* escape */ [ Error, Error, Error, Error, Error, Error, Error, Error, Simple(String), Simple(String), Simple(String), Error, Error, Error, Error, Error, Error, Simple(String), Error, Error, Error, Simple(String), Error, Simple(String), Simple(String), Error, Simple(String), Simple(U1), Error, Error, Error],
/* u1 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(U2), Simple(U2), Simple(U2), Simple(U2), Simple(U2), Simple(U2), Simple(U2), Simple(U2), Error, Error, Error, Error, Error, Error, Simple(U2), Simple(U2), Error],
/* u2 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(U3), Simple(U3), Simple(U3), Simple(U3), Simple(U3), Simple(U3), Simple(U3), Simple(U3), Error, Error, Error, Error, Error, Error, Simple(U3), Simple(U3), Error],
/* u3 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(U4), Simple(U4), Simple(U4), Simple(U4), Simple(U4), Simple(U4), Simple(U4), Simple(U4), Error, Error, Error, Error, Error, Error, Simple(U4), Simple(U4), Error],
/* u4 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Simple(String), Error, Error, Error, Error, Error, Error, Simple(String), Simple(String), Error],
/* minus */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Zero), Simple(Integer), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* zero */ [ Simple(Ok), Simple(Ok), Error, Complex(BraceClose), Error, Complex(BracketClose), Error, Complex(Comma), Error, Error, Error, Error, Error, Simple(Fraction1), Error, Error, Error, Error, Error, Error, Simple(Exponent1), Error, Error, Error, Error, Error, Error, Error, Error, Simple(Exponent1), Error],
/* integer */ [ Simple(Ok), Simple(Ok), Error, Complex(BraceClose), Error, Complex(BracketClose), Error, Complex(Comma), Error, Error, Error, Error, Error, Simple(Fraction1), Simple(Integer), Simple(Integer), Error, Error, Error, Error, Simple(Exponent1), Error, Error, Error, Error, Error, Error, Error, Error, Simple(Exponent1), Error],
/* fraction 1 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Fraction2), Simple(Fraction2), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* fraction 2 */ [ Simple(Ok), Simple(Ok), Error, Complex(BraceClose), Error, Complex(BracketClose), Error, Complex(Comma), Error, Error, Error, Error, Error, Error, Simple(Fraction2), Simple(Fraction2), Error, Error, Error, Error, Simple(Exponent1), Error, Error, Error, Error, Error, Error, Error, Error, Simple(Exponent1), Error],
/* exponent 1 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Exponent2), Simple(Exponent2), Error, Simple(Exponent3), Simple(Exponent3), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* exponent 2 */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Exponent3), Simple(Exponent3), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* exponent 3 */ [ Simple(Ok), Simple(Ok), Error, Complex(BraceClose), Error, Complex(BracketClose), Error, Complex(Comma), Error, Error, Error, Error, Error, Error, Simple(Exponent3), Simple(Exponent3), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* true_tr */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(TrueTru), Error, Error, Error, Error, Error, Error],
/* true_tru */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(TrueTrue), Error, Error, Error],
/* true_true */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Ok), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* false_fa */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(FalseFal), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* false_fal */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(FalseFals), Error, Error, Error, Error, Error, Error, Error, Error],
/* false_fals */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(FalseFalse), Error, Error, Error, Error, Error],
/* false_false */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Ok), Error, Error, Error, Error, Error, Error, Error, Error, Error, Error],
/* null_nu */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(NullNul), Error, Error, Error],
/* null_nul */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(NullNull), Error, Error, Error, Error, Error, Error, Error, Error],
/* null_null */ [ Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Simple(Ok), Error, Error, Error, Error, Error, Error, Error, Error],
]
};
#[rustfmt::skip]
const CATEGORIES: [CharacterType; 128] = {
use self::CharacterType::{
Abcdf, Backslash, BraceClose, BraceOpen, BracketClose, BracketOpen, Colon, Comma, Digit,
Dot, Error, LowA, LowB, LowC, LowD, LowE, LowF, LowL, LowN, LowR, LowS, LowT, LowU, Minus,
Other, Plus, Quote, Slash, Space, Whitespace, Zero, E,
};
[
Error, Error, Error, Error, Error, Error, Error, Error,
Error, Whitespace, Whitespace, Error, Error, Whitespace, Error, Error,
Error, Error, Error, Error, Error, Error, Error, Error,
Error, Error, Error, Error, Error, Error, Error, Error,
Space, Other, Quote, Other, Other, Other, Other, Other,
Other, Other, Other, Plus, Comma, Minus, Dot, Slash,
Zero, Digit, Digit, Digit, Digit, Digit, Digit, Digit,
Digit, Digit, Colon, Other, Other, Other, Other, Other,
Other, Abcdf, Abcdf, Abcdf, Abcdf, E, Abcdf, Other,
Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, BracketOpen, Backslash, BracketClose, Other, Other,
Other, LowA, LowB, LowC, LowD, LowE, LowF, Other,
Other, Other, Other, Other, LowL, Other, LowN, Other,
Other, Other, LowR, LowS, LowT, LowU, Other, Other,
Other, Other, Other, BraceOpen, Other, BraceClose, Other, Other,
]
};
pub fn character_type(character: u8) -> Result<CharacterType, Error> {
debug_assert!(character < 128);
match CATEGORIES[character as usize] {
CharacterType::Error => Err(Error::Invalid),
character_type => Ok(character_type),
}
}
pub fn transition(from: Token, ty: CharacterType) -> Result<Transition, Error> {
debug_assert!(ty != CharacterType::Error);
match TRANSITIONS[from as usize][ty as usize] {
Transition::Error => Err(Error::Invalid),
transition => Ok(transition),
}
}