11 #define JSON_TOKEN_INVALID -1
12 #define JSON_TOKEN_EOF 0
13 #define JSON_TOKEN_STRING 256
14 #define JSON_TOKEN_NUMBER 257
15 #define JSON_TOKEN_TRUE 258
16 #define JSON_TOKEN_FALSE 259
17 #define JSON_TOKEN_NULL 260
31 /*** error reporting ***/
33 static void json_set_error(json_error_t *error, const json_lex *lex,
41 int n = (int)(lex->input - lex->start);
42 error->line = lex->line;
43 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
44 "%s near '%.*s'", msg, n, lex->start);
48 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
49 "%s near end of file", msg);
54 /*** lexical analyzer ***/
56 static void json_scan_string(json_lex *lex)
59 const char *p = lex->input + 1;
62 lex->token = JSON_TOKEN_INVALID;
66 /* unterminated string literal */
70 if(0 <= *p && *p <= 31) {
71 /* control character */
78 for(int i = 0; i < 4; i++, p++) {
83 if(*p == '"' || *p == '\\' || *p == '/' || *p == 'b' ||
84 *p == 'f' || *p == 'n' || *p == 'r' || *p == 't')
93 /* the actual value is at most of the same length as the source
95 lex->value.string = malloc(p - lex->start);
96 if(!lex->value.string) {
97 /* this is not very nice, since TOKEN_INVALID is returned */
102 t = lex->value.string;
109 /* TODO: \uXXXX not supported yet */
110 free(lex->value.string);
111 lex->value.string = NULL;
115 case '"': case '\\': case '/':
117 case 'b': *t = '\b'; break;
118 case 'f': *t = '\f'; break;
119 case 'n': *t = '\n'; break;
120 case 'r': *t = '\r'; break;
121 case 't': *t = '\t'; break;
136 lex->token = JSON_TOKEN_STRING;
142 static void json_scan_number(json_lex *lex)
144 const char *p = lex->input;
147 lex->token = JSON_TOKEN_INVALID;
154 else /* *p != '0' */ {
169 if(*p == 'E' || *p == 'e') {
171 if(*p == '+' || *p == '-')
181 lex->token = JSON_TOKEN_NUMBER;
183 lex->value.number = strtod(lex->start, &end);
190 static int json_lex_scan(json_lex *lex)
194 if(lex->token == JSON_TOKEN_STRING) {
195 free(lex->value.string);
196 lex->value.string = NULL;
199 while(isspace(*lex->input)) {
200 if(*lex->input == '\n')
206 lex->start = lex->input;
210 lex->token = JSON_TOKEN_EOF;
212 else if(c == '{' || c == '}' || c == '[' || c == ']' ||
213 c == ':' || c == ',') {
219 json_scan_string(lex);
221 else if(isdigit(c) || c == '-')
222 json_scan_number(lex);
224 else if(isalpha(c)) {
225 /* eat up the whole identifier for clearer error messages */
228 while(isalpha(*lex->input))
230 len = lex->input - lex->start;
232 if(strncmp(lex->start, "true", len) == 0)
233 lex->token = JSON_TOKEN_TRUE;
234 else if(strncmp(lex->start, "false", len) == 0)
235 lex->token = JSON_TOKEN_FALSE;
236 else if(strncmp(lex->start, "null", len) == 0)
237 lex->token = JSON_TOKEN_NULL;
239 lex->token = JSON_TOKEN_INVALID;
243 lex->token = JSON_TOKEN_INVALID;
250 static int json_lex_init(json_lex *lex, const char *input)
253 lex->token = JSON_TOKEN_INVALID;
260 static void json_lex_close(json_lex *lex)
262 if(lex->token == JSON_TOKEN_STRING)
263 free(lex->value.string);
269 static json_t *json_parse(json_lex *lex, json_error_t *error);
271 static json_t *json_parse_object(json_lex *lex, json_error_t *error)
273 json_t *object = json_object();
278 if(lex->token == '}')
285 if(lex->token != JSON_TOKEN_STRING) {
286 json_set_error(error, lex, "string expected");
290 key = strdup(lex->value.string);
295 if(lex->token != ':') {
296 json_set_error(error, lex, "':' expected");
302 value = json_parse(lex, error);
306 if(json_object_set(object, key, value)) {
314 if(lex->token != ',')
320 if(lex->token != '}') {
321 json_set_error(error, lex, "'}' expected");
332 static json_t *json_parse_array(json_lex *lex, json_error_t *error)
334 json_t *array = json_array();
339 if(lex->token != ']') {
341 json_t *elem = json_parse(lex, error);
345 if(json_array_append(array, elem)) {
351 if(lex->token != ',')
358 if(lex->token != ']') {
359 json_set_error(error, lex, "']' expected");
370 static json_t *json_parse(json_lex *lex, json_error_t *error)
375 case JSON_TOKEN_STRING: {
376 json = json_string(lex->value.string);
380 case JSON_TOKEN_NUMBER: {
381 json = json_number(lex->value.number);
385 case JSON_TOKEN_TRUE:
389 case JSON_TOKEN_FALSE:
393 case JSON_TOKEN_NULL:
398 json = json_parse_object(lex, error);
402 json = json_parse_array(lex, error);
405 case JSON_TOKEN_INVALID:
406 json_set_error(error, lex, "invalid token");
410 json_set_error(error, lex, "unexpected token");
421 json_t *json_loads(const char *string, json_error_t *error)
424 json_t *result = NULL;
426 if(json_lex_init(&lex, string))
429 if(lex.token != '[' && lex.token != '{') {
430 json_set_error(error, &lex, "'[' or '{' expected");
434 result = json_parse(&lex, error);
438 if(lex.token != JSON_TOKEN_EOF) {
439 json_set_error(error, &lex, "end of file expected");
445 json_lex_close(&lex);