]>
git.proxmox.com Git - qemu.git/blob - json-lexer.c
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 /* Return whether TERMINAL is a terminal state and the transition to it
69 from OLD_STATE required lookahead. This happens whenever the table
70 below uses the TERMINAL macro. */
71 #define TERMINAL_NEEDED_LOOKAHEAD(old_state, terminal) \
72 (json_lexer[(old_state)][0] == (terminal))
74 static const uint8_t json_lexer
[][256] = {
76 TERMINAL(JSON_STRING
),
79 /* double quote string */
81 ['0' ... '9'] = IN_DQ_STRING
,
82 ['a' ... 'f'] = IN_DQ_STRING
,
83 ['A' ... 'F'] = IN_DQ_STRING
,
86 ['0' ... '9'] = IN_DQ_UCODE3
,
87 ['a' ... 'f'] = IN_DQ_UCODE3
,
88 ['A' ... 'F'] = IN_DQ_UCODE3
,
91 ['0' ... '9'] = IN_DQ_UCODE2
,
92 ['a' ... 'f'] = IN_DQ_UCODE2
,
93 ['A' ... 'F'] = IN_DQ_UCODE2
,
96 ['0' ... '9'] = IN_DQ_UCODE1
,
97 ['a' ... 'f'] = IN_DQ_UCODE1
,
98 ['A' ... 'F'] = IN_DQ_UCODE1
,
100 [IN_DQ_STRING_ESCAPE
] = {
101 ['b'] = IN_DQ_STRING
,
102 ['f'] = IN_DQ_STRING
,
103 ['n'] = IN_DQ_STRING
,
104 ['r'] = IN_DQ_STRING
,
105 ['t'] = IN_DQ_STRING
,
106 ['/'] = IN_DQ_STRING
,
107 ['\\'] = IN_DQ_STRING
,
108 ['\''] = IN_DQ_STRING
,
109 ['\"'] = IN_DQ_STRING
,
110 ['u'] = IN_DQ_UCODE0
,
113 [1 ... 0xFF] = IN_DQ_STRING
,
114 ['\\'] = IN_DQ_STRING_ESCAPE
,
115 ['"'] = IN_DONE_STRING
,
118 /* single quote string */
120 ['0' ... '9'] = IN_SQ_STRING
,
121 ['a' ... 'f'] = IN_SQ_STRING
,
122 ['A' ... 'F'] = IN_SQ_STRING
,
125 ['0' ... '9'] = IN_SQ_UCODE3
,
126 ['a' ... 'f'] = IN_SQ_UCODE3
,
127 ['A' ... 'F'] = IN_SQ_UCODE3
,
130 ['0' ... '9'] = IN_SQ_UCODE2
,
131 ['a' ... 'f'] = IN_SQ_UCODE2
,
132 ['A' ... 'F'] = IN_SQ_UCODE2
,
135 ['0' ... '9'] = IN_SQ_UCODE1
,
136 ['a' ... 'f'] = IN_SQ_UCODE1
,
137 ['A' ... 'F'] = IN_SQ_UCODE1
,
139 [IN_SQ_STRING_ESCAPE
] = {
140 ['b'] = IN_SQ_STRING
,
141 ['f'] = IN_SQ_STRING
,
142 ['n'] = IN_SQ_STRING
,
143 ['r'] = IN_SQ_STRING
,
144 ['t'] = IN_SQ_STRING
,
145 ['/'] = IN_DQ_STRING
,
146 ['\\'] = IN_DQ_STRING
,
147 ['\''] = IN_SQ_STRING
,
148 ['\"'] = IN_SQ_STRING
,
149 ['u'] = IN_SQ_UCODE0
,
152 [1 ... 0xFF] = IN_SQ_STRING
,
153 ['\\'] = IN_SQ_STRING_ESCAPE
,
154 ['\''] = IN_DONE_STRING
,
159 TERMINAL(JSON_INTEGER
),
160 ['0' ... '9'] = ERROR
,
166 TERMINAL(JSON_FLOAT
),
167 ['0' ... '9'] = IN_DIGITS
,
171 ['0' ... '9'] = IN_DIGITS
,
177 ['0' ... '9'] = IN_DIGITS
,
180 [IN_MANTISSA_DIGITS
] = {
181 TERMINAL(JSON_FLOAT
),
182 ['0' ... '9'] = IN_MANTISSA_DIGITS
,
188 ['0' ... '9'] = IN_MANTISSA_DIGITS
,
192 [IN_NONZERO_NUMBER
] = {
193 TERMINAL(JSON_INTEGER
),
194 ['0' ... '9'] = IN_NONZERO_NUMBER
,
200 [IN_NEG_NONZERO_NUMBER
] = {
202 ['1' ... '9'] = IN_NONZERO_NUMBER
,
207 TERMINAL(JSON_KEYWORD
),
208 ['a' ... 'z'] = IN_KEYWORD
,
214 [' '] = IN_WHITESPACE
,
215 ['\t'] = IN_WHITESPACE
,
216 ['\r'] = IN_WHITESPACE
,
217 ['\n'] = IN_WHITESPACE
,
221 [IN_OPERATOR_DONE
] = {
222 TERMINAL(JSON_OPERATOR
),
227 TERMINAL(JSON_ESCAPE
),
231 ['d'] = IN_ESCAPE_DONE
,
235 ['d'] = IN_ESCAPE_DONE
,
236 ['l'] = IN_ESCAPE_LL
,
240 ['d'] = IN_ESCAPE_DONE
,
244 ['4'] = IN_ESCAPE_I64
,
248 ['6'] = IN_ESCAPE_I6
,
252 ['d'] = IN_ESCAPE_DONE
,
253 ['i'] = IN_ESCAPE_DONE
,
254 ['p'] = IN_ESCAPE_DONE
,
255 ['s'] = IN_ESCAPE_DONE
,
256 ['f'] = IN_ESCAPE_DONE
,
263 ['"'] = IN_DQ_STRING
,
264 ['\''] = IN_SQ_STRING
,
266 ['1' ... '9'] = IN_NONZERO_NUMBER
,
267 ['-'] = IN_NEG_NONZERO_NUMBER
,
268 ['{'] = IN_OPERATOR_DONE
,
269 ['}'] = IN_OPERATOR_DONE
,
270 ['['] = IN_OPERATOR_DONE
,
271 [']'] = IN_OPERATOR_DONE
,
272 [','] = IN_OPERATOR_DONE
,
273 [':'] = IN_OPERATOR_DONE
,
274 ['a' ... 'z'] = IN_KEYWORD
,
276 [' '] = IN_WHITESPACE
,
277 ['\t'] = IN_WHITESPACE
,
278 ['\r'] = IN_WHITESPACE
,
279 ['\n'] = IN_WHITESPACE
,
283 void json_lexer_init(JSONLexer
*lexer
, JSONLexerEmitter func
)
286 lexer
->state
= IN_START
;
287 lexer
->token
= qstring_new();
288 lexer
->x
= lexer
->y
= 0;
291 static int json_lexer_feed_char(JSONLexer
*lexer
, char ch
)
293 int char_consumed
, new_state
;
302 new_state
= json_lexer
[lexer
->state
][(uint8_t)ch
];
303 char_consumed
= !TERMINAL_NEEDED_LOOKAHEAD(lexer
->state
, new_state
);
305 qstring_append_chr(lexer
->token
, ch
);
315 lexer
->emit(lexer
, lexer
->token
, new_state
, lexer
->x
, lexer
->y
);
317 QDECREF(lexer
->token
);
318 lexer
->token
= qstring_new();
319 new_state
= IN_START
;
326 lexer
->state
= new_state
;
327 } while (!char_consumed
);
331 int json_lexer_feed(JSONLexer
*lexer
, const char *buffer
, size_t size
)
335 for (i
= 0; i
< size
; i
++) {
338 err
= json_lexer_feed_char(lexer
, buffer
[i
]);
347 int json_lexer_flush(JSONLexer
*lexer
)
349 return lexer
->state
== IN_START
? 0 : json_lexer_feed_char(lexer
, 0);
352 void json_lexer_destroy(JSONLexer
*lexer
)
354 QDECREF(lexer
->token
);