4 * Copyright IBM, Corp. 2009
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
18 #include "qemu-common.h"
19 #include "json-lexer.h"
22 * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
23 * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
24 * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+))
30 enum json_lexer_state {
52 IN_NEG_NONZERO_NUMBER,
63 #define TERMINAL(state) [0 ... 0x7F] = (state)
65 static const uint8_t json_lexer[][256] = {
67 TERMINAL(JSON_STRING),
70 /* double quote string */
72 ['0' ... '9'] = IN_DQ_STRING,
73 ['a' ... 'f'] = IN_DQ_STRING,
74 ['A' ... 'F'] = IN_DQ_STRING,
77 ['0' ... '9'] = IN_DQ_UCODE3,
78 ['a' ... 'f'] = IN_DQ_UCODE3,
79 ['A' ... 'F'] = IN_DQ_UCODE3,
82 ['0' ... '9'] = IN_DQ_UCODE2,
83 ['a' ... 'f'] = IN_DQ_UCODE2,
84 ['A' ... 'F'] = IN_DQ_UCODE2,
87 ['0' ... '9'] = IN_DQ_UCODE1,
88 ['a' ... 'f'] = IN_DQ_UCODE1,
89 ['A' ... 'F'] = IN_DQ_UCODE1,
91 [IN_DQ_STRING_ESCAPE] = {
97 ['\''] = IN_DQ_STRING,
98 ['\"'] = IN_DQ_STRING,
102 [1 ... 0xFF] = IN_DQ_STRING,
103 ['\\'] = IN_DQ_STRING_ESCAPE,
104 ['"'] = IN_DONE_STRING,
107 /* single quote string */
109 ['0' ... '9'] = IN_SQ_STRING,
110 ['a' ... 'f'] = IN_SQ_STRING,
111 ['A' ... 'F'] = IN_SQ_STRING,
114 ['0' ... '9'] = IN_SQ_UCODE3,
115 ['a' ... 'f'] = IN_SQ_UCODE3,
116 ['A' ... 'F'] = IN_SQ_UCODE3,
119 ['0' ... '9'] = IN_SQ_UCODE2,
120 ['a' ... 'f'] = IN_SQ_UCODE2,
121 ['A' ... 'F'] = IN_SQ_UCODE2,
124 ['0' ... '9'] = IN_SQ_UCODE1,
125 ['a' ... 'f'] = IN_SQ_UCODE1,
126 ['A' ... 'F'] = IN_SQ_UCODE1,
128 [IN_SQ_STRING_ESCAPE] = {
129 ['b'] = IN_SQ_STRING,
130 ['f'] = IN_SQ_STRING,
131 ['n'] = IN_SQ_STRING,
132 ['r'] = IN_SQ_STRING,
133 ['t'] = IN_SQ_STRING,
134 ['\''] = IN_SQ_STRING,
135 ['\"'] = IN_SQ_STRING,
136 ['u'] = IN_SQ_UCODE0,
139 [1 ... 0xFF] = IN_SQ_STRING,
140 ['\\'] = IN_SQ_STRING_ESCAPE,
141 ['\''] = IN_DONE_STRING,
146 TERMINAL(JSON_INTEGER),
147 ['0' ... '9'] = ERROR,
153 TERMINAL(JSON_FLOAT),
154 ['0' ... '9'] = IN_DIGITS,
158 ['0' ... '9'] = IN_DIGITS,
164 ['0' ... '9'] = IN_DIGITS,
167 [IN_MANTISSA_DIGITS] = {
168 TERMINAL(JSON_FLOAT),
169 ['0' ... '9'] = IN_MANTISSA_DIGITS,
175 ['0' ... '9'] = IN_MANTISSA_DIGITS,
179 [IN_NONZERO_NUMBER] = {
180 TERMINAL(JSON_INTEGER),
181 ['0' ... '9'] = IN_NONZERO_NUMBER,
187 [IN_NEG_NONZERO_NUMBER] = {
189 ['1' ... '9'] = IN_NONZERO_NUMBER,
194 TERMINAL(JSON_KEYWORD),
195 ['a' ... 'z'] = IN_KEYWORD,
201 [' '] = IN_WHITESPACE,
202 ['\t'] = IN_WHITESPACE,
203 ['\r'] = IN_WHITESPACE,
204 ['\n'] = IN_WHITESPACE,
208 [IN_OPERATOR_DONE] = {
209 TERMINAL(JSON_OPERATOR),
214 TERMINAL(JSON_ESCAPE),
218 ['d'] = IN_ESCAPE_DONE,
222 ['d'] = IN_ESCAPE_DONE,
223 ['l'] = IN_ESCAPE_LL,
227 ['d'] = IN_ESCAPE_DONE,
228 ['i'] = IN_ESCAPE_DONE,
229 ['p'] = IN_ESCAPE_DONE,
230 ['s'] = IN_ESCAPE_DONE,
231 ['f'] = IN_ESCAPE_DONE,
237 ['"'] = IN_DQ_STRING,
238 ['\''] = IN_SQ_STRING,
240 ['1' ... '9'] = IN_NONZERO_NUMBER,
241 ['-'] = IN_NEG_NONZERO_NUMBER,
242 ['{'] = IN_OPERATOR_DONE,
243 ['}'] = IN_OPERATOR_DONE,
244 ['['] = IN_OPERATOR_DONE,
245 [']'] = IN_OPERATOR_DONE,
246 [','] = IN_OPERATOR_DONE,
247 [':'] = IN_OPERATOR_DONE,
248 ['a' ... 'z'] = IN_KEYWORD,
250 [' '] = IN_WHITESPACE,
251 ['\t'] = IN_WHITESPACE,
252 ['\r'] = IN_WHITESPACE,
253 ['\n'] = IN_WHITESPACE,
257 void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
260 lexer->state = IN_START;
261 lexer->token = qstring_new();
264 static int json_lexer_feed_char(JSONLexer *lexer, char ch)
274 lexer->state = json_lexer[lexer->state][(uint8_t)ch];
276 switch (lexer->state) {
283 lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
285 lexer->state = json_lexer[IN_START][(uint8_t)ch];
286 QDECREF(lexer->token);
287 lexer->token = qstring_new();
298 qstring_append(lexer->token, buf);
303 int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size)
307 for (i = 0; i < size; i++) {
310 err = json_lexer_feed_char(lexer, buffer[i]);
319 int json_lexer_flush(JSONLexer *lexer)
321 return json_lexer_feed_char(lexer, 0);
324 void json_lexer_destroy(JSONLexer *lexer)
326 QDECREF(lexer->token);