]>
git.proxmox.com Git - qemu.git/blob - json-lexer.c
1d9b81fef4c015cbac985c8e3b50693e05810cdf
4 * Copyright IBM, Corp. 2009
7 * Anthony Liguori <aliguori@us.ibm.com>
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
,
66 #define TERMINAL(state) [0 ... 0x7F] = (state)
68 static const uint8_t json_lexer
[][256] = {
70 TERMINAL(JSON_STRING
),
73 /* double quote string */
75 ['0' ... '9'] = IN_DQ_STRING
,
76 ['a' ... 'f'] = IN_DQ_STRING
,
77 ['A' ... 'F'] = IN_DQ_STRING
,
80 ['0' ... '9'] = IN_DQ_UCODE3
,
81 ['a' ... 'f'] = IN_DQ_UCODE3
,
82 ['A' ... 'F'] = IN_DQ_UCODE3
,
85 ['0' ... '9'] = IN_DQ_UCODE2
,
86 ['a' ... 'f'] = IN_DQ_UCODE2
,
87 ['A' ... 'F'] = IN_DQ_UCODE2
,
90 ['0' ... '9'] = IN_DQ_UCODE1
,
91 ['a' ... 'f'] = IN_DQ_UCODE1
,
92 ['A' ... 'F'] = IN_DQ_UCODE1
,
94 [IN_DQ_STRING_ESCAPE
] = {
100 ['/'] = IN_DQ_STRING
,
101 ['\\'] = IN_DQ_STRING
,
102 ['\''] = IN_DQ_STRING
,
103 ['\"'] = IN_DQ_STRING
,
104 ['u'] = IN_DQ_UCODE0
,
107 [1 ... 0xFF] = IN_DQ_STRING
,
108 ['\\'] = IN_DQ_STRING_ESCAPE
,
109 ['"'] = IN_DONE_STRING
,
112 /* single quote string */
114 ['0' ... '9'] = IN_SQ_STRING
,
115 ['a' ... 'f'] = IN_SQ_STRING
,
116 ['A' ... 'F'] = IN_SQ_STRING
,
119 ['0' ... '9'] = IN_SQ_UCODE3
,
120 ['a' ... 'f'] = IN_SQ_UCODE3
,
121 ['A' ... 'F'] = IN_SQ_UCODE3
,
124 ['0' ... '9'] = IN_SQ_UCODE2
,
125 ['a' ... 'f'] = IN_SQ_UCODE2
,
126 ['A' ... 'F'] = IN_SQ_UCODE2
,
129 ['0' ... '9'] = IN_SQ_UCODE1
,
130 ['a' ... 'f'] = IN_SQ_UCODE1
,
131 ['A' ... 'F'] = IN_SQ_UCODE1
,
133 [IN_SQ_STRING_ESCAPE
] = {
134 ['b'] = IN_SQ_STRING
,
135 ['f'] = IN_SQ_STRING
,
136 ['n'] = IN_SQ_STRING
,
137 ['r'] = IN_SQ_STRING
,
138 ['t'] = IN_SQ_STRING
,
139 ['/'] = IN_DQ_STRING
,
140 ['\\'] = IN_DQ_STRING
,
141 ['\''] = IN_SQ_STRING
,
142 ['\"'] = IN_SQ_STRING
,
143 ['u'] = IN_SQ_UCODE0
,
146 [1 ... 0xFF] = IN_SQ_STRING
,
147 ['\\'] = IN_SQ_STRING_ESCAPE
,
148 ['\''] = IN_DONE_STRING
,
153 TERMINAL(JSON_INTEGER
),
154 ['0' ... '9'] = ERROR
,
160 TERMINAL(JSON_FLOAT
),
161 ['0' ... '9'] = IN_DIGITS
,
165 ['0' ... '9'] = IN_DIGITS
,
171 ['0' ... '9'] = IN_DIGITS
,
174 [IN_MANTISSA_DIGITS
] = {
175 TERMINAL(JSON_FLOAT
),
176 ['0' ... '9'] = IN_MANTISSA_DIGITS
,
182 ['0' ... '9'] = IN_MANTISSA_DIGITS
,
186 [IN_NONZERO_NUMBER
] = {
187 TERMINAL(JSON_INTEGER
),
188 ['0' ... '9'] = IN_NONZERO_NUMBER
,
194 [IN_NEG_NONZERO_NUMBER
] = {
196 ['1' ... '9'] = IN_NONZERO_NUMBER
,
201 TERMINAL(JSON_KEYWORD
),
202 ['a' ... 'z'] = IN_KEYWORD
,
208 [' '] = IN_WHITESPACE
,
209 ['\t'] = IN_WHITESPACE
,
210 ['\r'] = IN_WHITESPACE
,
211 ['\n'] = IN_WHITESPACE
,
215 [IN_OPERATOR_DONE
] = {
216 TERMINAL(JSON_OPERATOR
),
221 TERMINAL(JSON_ESCAPE
),
225 ['d'] = IN_ESCAPE_DONE
,
229 ['d'] = IN_ESCAPE_DONE
,
230 ['l'] = IN_ESCAPE_LL
,
234 ['d'] = IN_ESCAPE_DONE
,
238 ['4'] = IN_ESCAPE_I64
,
242 ['6'] = IN_ESCAPE_I6
,
246 ['d'] = IN_ESCAPE_DONE
,
247 ['i'] = IN_ESCAPE_DONE
,
248 ['p'] = IN_ESCAPE_DONE
,
249 ['s'] = IN_ESCAPE_DONE
,
250 ['f'] = IN_ESCAPE_DONE
,
257 ['"'] = IN_DQ_STRING
,
258 ['\''] = IN_SQ_STRING
,
260 ['1' ... '9'] = IN_NONZERO_NUMBER
,
261 ['-'] = IN_NEG_NONZERO_NUMBER
,
262 ['{'] = IN_OPERATOR_DONE
,
263 ['}'] = IN_OPERATOR_DONE
,
264 ['['] = IN_OPERATOR_DONE
,
265 [']'] = IN_OPERATOR_DONE
,
266 [','] = IN_OPERATOR_DONE
,
267 [':'] = IN_OPERATOR_DONE
,
268 ['a' ... 'z'] = IN_KEYWORD
,
270 [' '] = IN_WHITESPACE
,
271 ['\t'] = IN_WHITESPACE
,
272 ['\r'] = IN_WHITESPACE
,
273 ['\n'] = IN_WHITESPACE
,
277 void json_lexer_init(JSONLexer
*lexer
, JSONLexerEmitter func
)
280 lexer
->state
= IN_START
;
281 lexer
->token
= qstring_new();
282 lexer
->x
= lexer
->y
= 0;
285 static int json_lexer_feed_char(JSONLexer
*lexer
, char ch
)
293 lexer
->state
= json_lexer
[lexer
->state
][(uint8_t)ch
];
295 switch (lexer
->state
) {
302 lexer
->emit(lexer
, lexer
->token
, lexer
->state
, lexer
->x
, lexer
->y
);
304 lexer
->state
= json_lexer
[IN_START
][(uint8_t)ch
];
305 QDECREF(lexer
->token
);
306 lexer
->token
= qstring_new();
314 qstring_append_chr(lexer
->token
, ch
);
319 int json_lexer_feed(JSONLexer
*lexer
, const char *buffer
, size_t size
)
323 for (i
= 0; i
< size
; i
++) {
326 err
= json_lexer_feed_char(lexer
, buffer
[i
]);
335 int json_lexer_flush(JSONLexer
*lexer
)
337 return json_lexer_feed_char(lexer
, 0);
340 void json_lexer_destroy(JSONLexer
*lexer
)
342 QDECREF(lexer
->token
);