root / json-lexer.c @ a1f0cce2
History | View | Annotate | Download (7.8 kB)
1 | 5ab8558d | Anthony Liguori | /*
|
---|---|---|---|
2 | 5ab8558d | Anthony Liguori | * JSON lexer
|
3 | 5ab8558d | Anthony Liguori | *
|
4 | 5ab8558d | Anthony Liguori | * Copyright IBM, Corp. 2009
|
5 | 5ab8558d | Anthony Liguori | *
|
6 | 5ab8558d | Anthony Liguori | * Authors:
|
7 | 5ab8558d | Anthony Liguori | * Anthony Liguori <aliguori@us.ibm.com>
|
8 | 5ab8558d | Anthony Liguori | *
|
9 | 5ab8558d | Anthony Liguori | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
10 | 5ab8558d | Anthony Liguori | * See the COPYING.LIB file in the top-level directory.
|
11 | 5ab8558d | Anthony Liguori | *
|
12 | 5ab8558d | Anthony Liguori | */
|
13 | 5ab8558d | Anthony Liguori | |
14 | 5ab8558d | Anthony Liguori | #include "qstring.h" |
15 | 5ab8558d | Anthony Liguori | #include "qlist.h" |
16 | 5ab8558d | Anthony Liguori | #include "qdict.h" |
17 | 5ab8558d | Anthony Liguori | #include "qint.h" |
18 | 5ab8558d | Anthony Liguori | #include "qemu-common.h" |
19 | 5ab8558d | Anthony Liguori | #include "json-lexer.h" |
20 | 5ab8558d | Anthony Liguori | |
21 | 5ab8558d | Anthony Liguori | /*
|
22 | 5ab8558d | Anthony Liguori | * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
|
23 | 5ab8558d | Anthony Liguori | * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
|
24 | 5ab8558d | Anthony Liguori | * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+))
|
25 | 5ab8558d | Anthony Liguori | * [{}\[\],:]
|
26 | 5ab8558d | Anthony Liguori | * [a-z]+
|
27 | 5ab8558d | Anthony Liguori | *
|
28 | 5ab8558d | Anthony Liguori | */
|
29 | 5ab8558d | Anthony Liguori | |
30 | 5ab8558d | Anthony Liguori | enum json_lexer_state {
|
31 | 33d05394 | Blue Swirl | IN_ERROR = 0,
|
32 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE3, |
33 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE2, |
34 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE1, |
35 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE0, |
36 | 5ab8558d | Anthony Liguori | IN_DQ_STRING_ESCAPE, |
37 | 5ab8558d | Anthony Liguori | IN_DQ_STRING, |
38 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE3, |
39 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE2, |
40 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE1, |
41 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE0, |
42 | 5ab8558d | Anthony Liguori | IN_SQ_STRING_ESCAPE, |
43 | 5ab8558d | Anthony Liguori | IN_SQ_STRING, |
44 | 5ab8558d | Anthony Liguori | IN_ZERO, |
45 | 5ab8558d | Anthony Liguori | IN_DIGITS, |
46 | 5ab8558d | Anthony Liguori | IN_DIGIT, |
47 | 5ab8558d | Anthony Liguori | IN_EXP_E, |
48 | 5ab8558d | Anthony Liguori | IN_MANTISSA, |
49 | 5ab8558d | Anthony Liguori | IN_MANTISSA_DIGITS, |
50 | 5ab8558d | Anthony Liguori | IN_NONZERO_NUMBER, |
51 | 5ab8558d | Anthony Liguori | IN_NEG_NONZERO_NUMBER, |
52 | 5ab8558d | Anthony Liguori | IN_KEYWORD, |
53 | 5ab8558d | Anthony Liguori | IN_ESCAPE, |
54 | 5ab8558d | Anthony Liguori | IN_ESCAPE_L, |
55 | 5ab8558d | Anthony Liguori | IN_ESCAPE_LL, |
56 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I, |
57 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I6, |
58 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I64, |
59 | 5ab8558d | Anthony Liguori | IN_WHITESPACE, |
60 | 5ab8558d | Anthony Liguori | IN_START, |
61 | 5ab8558d | Anthony Liguori | }; |
62 | 5ab8558d | Anthony Liguori | |
63 | 5ab8558d | Anthony Liguori | #define TERMINAL(state) [0 ... 0x7F] = (state) |
64 | 5ab8558d | Anthony Liguori | |
65 | f7c05274 | Paolo Bonzini | /* Return whether TERMINAL is a terminal state and the transition to it
|
66 | f7c05274 | Paolo Bonzini | from OLD_STATE required lookahead. This happens whenever the table
|
67 | f7c05274 | Paolo Bonzini | below uses the TERMINAL macro. */
|
68 | f7c05274 | Paolo Bonzini | #define TERMINAL_NEEDED_LOOKAHEAD(old_state, terminal) \
|
69 | f7c05274 | Paolo Bonzini | (json_lexer[(old_state)][0] == (terminal))
|
70 | f7c05274 | Paolo Bonzini | |
71 | 5ab8558d | Anthony Liguori | static const uint8_t json_lexer[][256] = { |
72 | 5ab8558d | Anthony Liguori | /* double quote string */
|
73 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE3] = { |
74 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_STRING, |
75 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_STRING, |
76 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_STRING, |
77 | 5ab8558d | Anthony Liguori | }, |
78 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE2] = { |
79 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE3, |
80 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE3, |
81 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE3, |
82 | 5ab8558d | Anthony Liguori | }, |
83 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE1] = { |
84 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE2, |
85 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE2, |
86 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE2, |
87 | 5ab8558d | Anthony Liguori | }, |
88 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE0] = { |
89 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE1, |
90 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE1, |
91 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE1, |
92 | 5ab8558d | Anthony Liguori | }, |
93 | 5ab8558d | Anthony Liguori | [IN_DQ_STRING_ESCAPE] = { |
94 | 5ab8558d | Anthony Liguori | ['b'] = IN_DQ_STRING,
|
95 | 5ab8558d | Anthony Liguori | ['f'] = IN_DQ_STRING,
|
96 | 5ab8558d | Anthony Liguori | ['n'] = IN_DQ_STRING,
|
97 | 5ab8558d | Anthony Liguori | ['r'] = IN_DQ_STRING,
|
98 | 5ab8558d | Anthony Liguori | ['t'] = IN_DQ_STRING,
|
99 | 1041ba7a | Luiz Capitulino | ['/'] = IN_DQ_STRING,
|
100 | 1041ba7a | Luiz Capitulino | ['\\'] = IN_DQ_STRING,
|
101 | 5ab8558d | Anthony Liguori | ['\''] = IN_DQ_STRING,
|
102 | 5ab8558d | Anthony Liguori | ['\"'] = IN_DQ_STRING,
|
103 | 5ab8558d | Anthony Liguori | ['u'] = IN_DQ_UCODE0,
|
104 | 5ab8558d | Anthony Liguori | }, |
105 | 5ab8558d | Anthony Liguori | [IN_DQ_STRING] = { |
106 | 5ab8558d | Anthony Liguori | [1 ... 0xFF] = IN_DQ_STRING, |
107 | 5ab8558d | Anthony Liguori | ['\\'] = IN_DQ_STRING_ESCAPE,
|
108 | 28e91a68 | Paolo Bonzini | ['"'] = JSON_STRING,
|
109 | 5ab8558d | Anthony Liguori | }, |
110 | 5ab8558d | Anthony Liguori | |
111 | 5ab8558d | Anthony Liguori | /* single quote string */
|
112 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE3] = { |
113 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_STRING, |
114 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_STRING, |
115 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_STRING, |
116 | 5ab8558d | Anthony Liguori | }, |
117 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE2] = { |
118 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE3, |
119 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE3, |
120 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE3, |
121 | 5ab8558d | Anthony Liguori | }, |
122 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE1] = { |
123 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE2, |
124 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE2, |
125 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE2, |
126 | 5ab8558d | Anthony Liguori | }, |
127 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE0] = { |
128 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE1, |
129 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE1, |
130 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE1, |
131 | 5ab8558d | Anthony Liguori | }, |
132 | 5ab8558d | Anthony Liguori | [IN_SQ_STRING_ESCAPE] = { |
133 | 5ab8558d | Anthony Liguori | ['b'] = IN_SQ_STRING,
|
134 | 5ab8558d | Anthony Liguori | ['f'] = IN_SQ_STRING,
|
135 | 5ab8558d | Anthony Liguori | ['n'] = IN_SQ_STRING,
|
136 | 5ab8558d | Anthony Liguori | ['r'] = IN_SQ_STRING,
|
137 | 5ab8558d | Anthony Liguori | ['t'] = IN_SQ_STRING,
|
138 | 1041ba7a | Luiz Capitulino | ['/'] = IN_DQ_STRING,
|
139 | 1041ba7a | Luiz Capitulino | ['\\'] = IN_DQ_STRING,
|
140 | 5ab8558d | Anthony Liguori | ['\''] = IN_SQ_STRING,
|
141 | 5ab8558d | Anthony Liguori | ['\"'] = IN_SQ_STRING,
|
142 | 5ab8558d | Anthony Liguori | ['u'] = IN_SQ_UCODE0,
|
143 | 5ab8558d | Anthony Liguori | }, |
144 | 5ab8558d | Anthony Liguori | [IN_SQ_STRING] = { |
145 | 5ab8558d | Anthony Liguori | [1 ... 0xFF] = IN_SQ_STRING, |
146 | 5ab8558d | Anthony Liguori | ['\\'] = IN_SQ_STRING_ESCAPE,
|
147 | 28e91a68 | Paolo Bonzini | ['\''] = JSON_STRING,
|
148 | 5ab8558d | Anthony Liguori | }, |
149 | 5ab8558d | Anthony Liguori | |
150 | 5ab8558d | Anthony Liguori | /* Zero */
|
151 | 5ab8558d | Anthony Liguori | [IN_ZERO] = { |
152 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_INTEGER), |
153 | 33d05394 | Blue Swirl | ['0' ... '9'] = IN_ERROR, |
154 | 5ab8558d | Anthony Liguori | ['.'] = IN_MANTISSA,
|
155 | 5ab8558d | Anthony Liguori | }, |
156 | 5ab8558d | Anthony Liguori | |
157 | 5ab8558d | Anthony Liguori | /* Float */
|
158 | 5ab8558d | Anthony Liguori | [IN_DIGITS] = { |
159 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_FLOAT), |
160 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
161 | 5ab8558d | Anthony Liguori | }, |
162 | 5ab8558d | Anthony Liguori | |
163 | 5ab8558d | Anthony Liguori | [IN_DIGIT] = { |
164 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
165 | 5ab8558d | Anthony Liguori | }, |
166 | 5ab8558d | Anthony Liguori | |
167 | 5ab8558d | Anthony Liguori | [IN_EXP_E] = { |
168 | 5ab8558d | Anthony Liguori | ['-'] = IN_DIGIT,
|
169 | 5ab8558d | Anthony Liguori | ['+'] = IN_DIGIT,
|
170 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
171 | 5ab8558d | Anthony Liguori | }, |
172 | 5ab8558d | Anthony Liguori | |
173 | 5ab8558d | Anthony Liguori | [IN_MANTISSA_DIGITS] = { |
174 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_FLOAT), |
175 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_MANTISSA_DIGITS, |
176 | 5ab8558d | Anthony Liguori | ['e'] = IN_EXP_E,
|
177 | 5ab8558d | Anthony Liguori | ['E'] = IN_EXP_E,
|
178 | 5ab8558d | Anthony Liguori | }, |
179 | 5ab8558d | Anthony Liguori | |
180 | 5ab8558d | Anthony Liguori | [IN_MANTISSA] = { |
181 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_MANTISSA_DIGITS, |
182 | 5ab8558d | Anthony Liguori | }, |
183 | 5ab8558d | Anthony Liguori | |
184 | 5ab8558d | Anthony Liguori | /* Number */
|
185 | 5ab8558d | Anthony Liguori | [IN_NONZERO_NUMBER] = { |
186 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_INTEGER), |
187 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_NONZERO_NUMBER, |
188 | 5ab8558d | Anthony Liguori | ['e'] = IN_EXP_E,
|
189 | 5ab8558d | Anthony Liguori | ['E'] = IN_EXP_E,
|
190 | 5ab8558d | Anthony Liguori | ['.'] = IN_MANTISSA,
|
191 | 5ab8558d | Anthony Liguori | }, |
192 | 5ab8558d | Anthony Liguori | |
193 | 5ab8558d | Anthony Liguori | [IN_NEG_NONZERO_NUMBER] = { |
194 | 5ab8558d | Anthony Liguori | ['0'] = IN_ZERO,
|
195 | 5ab8558d | Anthony Liguori | ['1' ... '9'] = IN_NONZERO_NUMBER, |
196 | 5ab8558d | Anthony Liguori | }, |
197 | 5ab8558d | Anthony Liguori | |
198 | 5ab8558d | Anthony Liguori | /* keywords */
|
199 | 5ab8558d | Anthony Liguori | [IN_KEYWORD] = { |
200 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_KEYWORD), |
201 | 5ab8558d | Anthony Liguori | ['a' ... 'z'] = IN_KEYWORD, |
202 | 5ab8558d | Anthony Liguori | }, |
203 | 5ab8558d | Anthony Liguori | |
204 | 5ab8558d | Anthony Liguori | /* whitespace */
|
205 | 5ab8558d | Anthony Liguori | [IN_WHITESPACE] = { |
206 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_SKIP), |
207 | 5ab8558d | Anthony Liguori | [' '] = IN_WHITESPACE,
|
208 | 5ab8558d | Anthony Liguori | ['\t'] = IN_WHITESPACE,
|
209 | 5ab8558d | Anthony Liguori | ['\r'] = IN_WHITESPACE,
|
210 | 5ab8558d | Anthony Liguori | ['\n'] = IN_WHITESPACE,
|
211 | 5ab8558d | Anthony Liguori | }, |
212 | 5ab8558d | Anthony Liguori | |
213 | 5ab8558d | Anthony Liguori | /* escape */
|
214 | 5ab8558d | Anthony Liguori | [IN_ESCAPE_LL] = { |
215 | 28e91a68 | Paolo Bonzini | ['d'] = JSON_ESCAPE,
|
216 | 5ab8558d | Anthony Liguori | }, |
217 | 5ab8558d | Anthony Liguori | |
218 | 5ab8558d | Anthony Liguori | [IN_ESCAPE_L] = { |
219 | 28e91a68 | Paolo Bonzini | ['d'] = JSON_ESCAPE,
|
220 | 5ab8558d | Anthony Liguori | ['l'] = IN_ESCAPE_LL,
|
221 | 5ab8558d | Anthony Liguori | }, |
222 | 5ab8558d | Anthony Liguori | |
223 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I64] = { |
224 | 28e91a68 | Paolo Bonzini | ['d'] = JSON_ESCAPE,
|
225 | 2c0d4b36 | Roy Tam | }, |
226 | 2c0d4b36 | Roy Tam | |
227 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I6] = { |
228 | 2c0d4b36 | Roy Tam | ['4'] = IN_ESCAPE_I64,
|
229 | 2c0d4b36 | Roy Tam | }, |
230 | 2c0d4b36 | Roy Tam | |
231 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I] = { |
232 | 2c0d4b36 | Roy Tam | ['6'] = IN_ESCAPE_I6,
|
233 | 2c0d4b36 | Roy Tam | }, |
234 | 2c0d4b36 | Roy Tam | |
235 | 5ab8558d | Anthony Liguori | [IN_ESCAPE] = { |
236 | 28e91a68 | Paolo Bonzini | ['d'] = JSON_ESCAPE,
|
237 | 28e91a68 | Paolo Bonzini | ['i'] = JSON_ESCAPE,
|
238 | 28e91a68 | Paolo Bonzini | ['p'] = JSON_ESCAPE,
|
239 | 28e91a68 | Paolo Bonzini | ['s'] = JSON_ESCAPE,
|
240 | 28e91a68 | Paolo Bonzini | ['f'] = JSON_ESCAPE,
|
241 | 5ab8558d | Anthony Liguori | ['l'] = IN_ESCAPE_L,
|
242 | 2c0d4b36 | Roy Tam | ['I'] = IN_ESCAPE_I,
|
243 | 5ab8558d | Anthony Liguori | }, |
244 | 5ab8558d | Anthony Liguori | |
245 | 5ab8558d | Anthony Liguori | /* top level rule */
|
246 | 5ab8558d | Anthony Liguori | [IN_START] = { |
247 | 5ab8558d | Anthony Liguori | ['"'] = IN_DQ_STRING,
|
248 | 5ab8558d | Anthony Liguori | ['\''] = IN_SQ_STRING,
|
249 | 5ab8558d | Anthony Liguori | ['0'] = IN_ZERO,
|
250 | 5ab8558d | Anthony Liguori | ['1' ... '9'] = IN_NONZERO_NUMBER, |
251 | 5ab8558d | Anthony Liguori | ['-'] = IN_NEG_NONZERO_NUMBER,
|
252 | 28e91a68 | Paolo Bonzini | ['{'] = JSON_OPERATOR,
|
253 | 28e91a68 | Paolo Bonzini | ['}'] = JSON_OPERATOR,
|
254 | 28e91a68 | Paolo Bonzini | ['['] = JSON_OPERATOR,
|
255 | 28e91a68 | Paolo Bonzini | [']'] = JSON_OPERATOR,
|
256 | 28e91a68 | Paolo Bonzini | [','] = JSON_OPERATOR,
|
257 | 28e91a68 | Paolo Bonzini | [':'] = JSON_OPERATOR,
|
258 | 5ab8558d | Anthony Liguori | ['a' ... 'z'] = IN_KEYWORD, |
259 | 5ab8558d | Anthony Liguori | ['%'] = IN_ESCAPE,
|
260 | 5ab8558d | Anthony Liguori | [' '] = IN_WHITESPACE,
|
261 | 5ab8558d | Anthony Liguori | ['\t'] = IN_WHITESPACE,
|
262 | 5ab8558d | Anthony Liguori | ['\r'] = IN_WHITESPACE,
|
263 | 5ab8558d | Anthony Liguori | ['\n'] = IN_WHITESPACE,
|
264 | 5ab8558d | Anthony Liguori | }, |
265 | 5ab8558d | Anthony Liguori | }; |
266 | 5ab8558d | Anthony Liguori | |
267 | 5ab8558d | Anthony Liguori | void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
|
268 | 5ab8558d | Anthony Liguori | { |
269 | 5ab8558d | Anthony Liguori | lexer->emit = func; |
270 | 5ab8558d | Anthony Liguori | lexer->state = IN_START; |
271 | 5ab8558d | Anthony Liguori | lexer->token = qstring_new(); |
272 | 03308f6c | Luiz Capitulino | lexer->x = lexer->y = 0;
|
273 | 5ab8558d | Anthony Liguori | } |
274 | 5ab8558d | Anthony Liguori | |
275 | 5ab8558d | Anthony Liguori | static int json_lexer_feed_char(JSONLexer *lexer, char ch) |
276 | 5ab8558d | Anthony Liguori | { |
277 | f7c05274 | Paolo Bonzini | int char_consumed, new_state;
|
278 | f7c05274 | Paolo Bonzini | |
279 | 5ab8558d | Anthony Liguori | lexer->x++; |
280 | 5ab8558d | Anthony Liguori | if (ch == '\n') { |
281 | 5ab8558d | Anthony Liguori | lexer->x = 0;
|
282 | 5ab8558d | Anthony Liguori | lexer->y++; |
283 | 5ab8558d | Anthony Liguori | } |
284 | 5ab8558d | Anthony Liguori | |
285 | f7c05274 | Paolo Bonzini | do {
|
286 | f7c05274 | Paolo Bonzini | new_state = json_lexer[lexer->state][(uint8_t)ch]; |
287 | f7c05274 | Paolo Bonzini | char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state); |
288 | f7c05274 | Paolo Bonzini | if (char_consumed) {
|
289 | f7c05274 | Paolo Bonzini | qstring_append_chr(lexer->token, ch); |
290 | f7c05274 | Paolo Bonzini | } |
291 | 5ab8558d | Anthony Liguori | |
292 | f7c05274 | Paolo Bonzini | switch (new_state) {
|
293 | f7c05274 | Paolo Bonzini | case JSON_OPERATOR:
|
294 | f7c05274 | Paolo Bonzini | case JSON_ESCAPE:
|
295 | f7c05274 | Paolo Bonzini | case JSON_INTEGER:
|
296 | f7c05274 | Paolo Bonzini | case JSON_FLOAT:
|
297 | f7c05274 | Paolo Bonzini | case JSON_KEYWORD:
|
298 | f7c05274 | Paolo Bonzini | case JSON_STRING:
|
299 | f7c05274 | Paolo Bonzini | lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y); |
300 | f7c05274 | Paolo Bonzini | case JSON_SKIP:
|
301 | f7c05274 | Paolo Bonzini | QDECREF(lexer->token); |
302 | f7c05274 | Paolo Bonzini | lexer->token = qstring_new(); |
303 | f7c05274 | Paolo Bonzini | new_state = IN_START; |
304 | f7c05274 | Paolo Bonzini | break;
|
305 | 33d05394 | Blue Swirl | case IN_ERROR:
|
306 | f7c05274 | Paolo Bonzini | return -EINVAL;
|
307 | f7c05274 | Paolo Bonzini | default:
|
308 | f7c05274 | Paolo Bonzini | break;
|
309 | f7c05274 | Paolo Bonzini | } |
310 | f7c05274 | Paolo Bonzini | lexer->state = new_state; |
311 | f7c05274 | Paolo Bonzini | } while (!char_consumed);
|
312 | 5ab8558d | Anthony Liguori | return 0; |
313 | 5ab8558d | Anthony Liguori | } |
314 | 5ab8558d | Anthony Liguori | |
315 | 5ab8558d | Anthony Liguori | int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) |
316 | 5ab8558d | Anthony Liguori | { |
317 | 5ab8558d | Anthony Liguori | size_t i; |
318 | 5ab8558d | Anthony Liguori | |
319 | 5ab8558d | Anthony Liguori | for (i = 0; i < size; i++) { |
320 | 5ab8558d | Anthony Liguori | int err;
|
321 | 5ab8558d | Anthony Liguori | |
322 | 5ab8558d | Anthony Liguori | err = json_lexer_feed_char(lexer, buffer[i]); |
323 | 5ab8558d | Anthony Liguori | if (err < 0) { |
324 | 5ab8558d | Anthony Liguori | return err;
|
325 | 5ab8558d | Anthony Liguori | } |
326 | 5ab8558d | Anthony Liguori | } |
327 | 5ab8558d | Anthony Liguori | |
328 | 5ab8558d | Anthony Liguori | return 0; |
329 | 5ab8558d | Anthony Liguori | } |
330 | 5ab8558d | Anthony Liguori | |
331 | 5ab8558d | Anthony Liguori | int json_lexer_flush(JSONLexer *lexer)
|
332 | 5ab8558d | Anthony Liguori | { |
333 | f7c05274 | Paolo Bonzini | return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0); |
334 | 5ab8558d | Anthony Liguori | } |
335 | 5ab8558d | Anthony Liguori | |
336 | 5ab8558d | Anthony Liguori | void json_lexer_destroy(JSONLexer *lexer)
|
337 | 5ab8558d | Anthony Liguori | { |
338 | 5ab8558d | Anthony Liguori | QDECREF(lexer->token); |
339 | 5ab8558d | Anthony Liguori | } |