1 /* Generated by re2c */
2 #line 1 "input_custom_mjson.re"
3 // re2c $INPUT -o $OUTPUT  --input custom
4 #include <assert.h>
5 #include <memory.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stddef.h>
9 
10 /**
11  * mjson - modified json parser
12  * syntax changes:
13  *   - no {} needed around the whole file
14  *   - "=" is allowed instead of ":"
15  *   - quotes around the key are optional
16  *   - commas after values are optional
17  *   - and c-style comments allowed
18  *
19  * intermediate storage is based on ideas from BJSON specification: http://bjson.org
20  *
21  * some code ideas are borrowed from another json parser: https://github.com/megous/sjson
22  */
23 
24 #ifndef __MJSON_H_INCLUDED__
25 #define __MJSON_H_INCLUDED__
26 
27 #include <stdint.h>
28 
29 #ifdef __cplusplus
30 extern "C"
31 {
32 #endif
33 
34 struct _mjson_entry_t;
35 
36 typedef const struct _mjson_entry_t* mjson_element_t;
37 
38 enum mjson_element_id_t
39 {
40     MJSON_ID_NULL           =  0,
41     MJSON_ID_FALSE          =  1,
42     MJSON_ID_EMPTY_STRING   =  2,
43     MJSON_ID_TRUE           =  3,
44 
45     MJSON_ID_UINT32         =  4,
46     MJSON_ID_UINT64         =  5,
47 
48     MJSON_ID_SINT32         =  6,
49     MJSON_ID_SINT64         =  7,
50 
51     MJSON_ID_FLOAT32        =  8,
52     MJSON_ID_FLOAT64        =  9,
53 
54     MJSON_ID_UTF8_KEY32     = 10,
55     MJSON_ID_UTF8_KEY64     = 11,
56 
57     MJSON_ID_UTF8_STRING32  = 12,
58     MJSON_ID_UTF8_STRING64  = 13,
59 
60     MJSON_ID_BINARY32       = 14,
61     MJSON_ID_BINARY64       = 15,
62 
63     MJSON_ID_ARRAY32        = 16,
64     MJSON_ID_ARRAY64        = 17,
65 
66     MJSON_ID_DICT32         = 18,
67     MJSON_ID_DICT64         = 19
68 };
69 
70 int mjson_parse(const char *json_data, size_t json_data_size, void* storage_buf, size_t storage_buf_size, mjson_element_t* top_element);
71 
72 mjson_element_t   mjson_get_top_element(void* storage_buf, size_t storage_buf_size);
73 
74 mjson_element_t   mjson_get_element_first(mjson_element_t array);
75 mjson_element_t   mjson_get_element_next (mjson_element_t array, mjson_element_t current_value);
76 mjson_element_t   mjson_get_element      (mjson_element_t array, int index);
77 
78 mjson_element_t   mjson_get_member_first(mjson_element_t dictionary, mjson_element_t* value);
79 mjson_element_t   mjson_get_member_next (mjson_element_t dictionary, mjson_element_t current_key, mjson_element_t* next_value);
80 mjson_element_t   mjson_get_member      (mjson_element_t dictionary, const char* name);
81 
82 int mjson_get_type(mjson_element_t element);
83 
84 const char* mjson_get_string(mjson_element_t element, const char* fallback);
85 int32_t     mjson_get_int   (mjson_element_t element, int32_t     fallback);
86 float       mjson_get_float (mjson_element_t element, float       fallback);
87 int         mjson_get_bool  (mjson_element_t element, int         fallback);
88 int         mjson_is_null   (mjson_element_t element);
89 
90 #ifdef __cplusplus
91 }
92 #endif
93 
94 #endif
95 
96 enum mjson_token_t
97 {
98     TOK_NONE,
99     TOK_IDENTIFIER,
100     TOK_NOESC_STRING,
101     TOK_STRING,
102     TOK_OCT_NUMBER,
103     TOK_HEX_NUMBER,
104     TOK_DEC_NUMBER,
105     TOK_FLOAT_NUMBER,
106     TOK_COMMA,
107     TOK_COLON,
108     TOK_EQUAL,
109     TOK_LEFT_BRACKET,
110     TOK_RIGHT_BRACKET,
111     TOK_LEFT_CURLY_BRACKET,
112     TOK_RIGHT_CURLY_BRACKET,
113     TOK_FALSE,
114     TOK_TRUE,
115     TOK_NULL,
116     TOK_WHITESPACE,
117     TOK_INVALID,
118     TOK_COUNT
119 };
120 
121 struct _mjson_parser_t
122 {
123     int token;
124     uint8_t* start;
125     uint8_t* next;
126     uint8_t* end;
127     uint8_t* bjson;
128     uint8_t* bjson_limit;
129 };
130 
131 struct _mjson_entry_t
132 {
133     uint32_t  id;
134     union
135     {
136         uint32_t val_u32;
137         int32_t  val_s32;
138         float    val_f32;
139     };
140 };
141 
142 #define RETURN_VAL_IF_FAIL(cond, val) if (!(cond)) return (val)
143 #define RETURN_IF_FAIL(cond) if (!(cond)) return
144 #define MAX_UTF8_CHAR_LEN 6
145 #define TRUE  1
146 #define FALSE 0
147 
148 typedef struct _mjson_parser_t  mjson_parser_t;
149 typedef struct _mjson_entry_t   mjson_entry_t;
150 
151 static void* parsectx_allocate_output(mjson_parser_t* ctx, ptrdiff_t size);
152 
153 static void parsectx_next_token    (mjson_parser_t* context);
154 
155 static int parse_value_list    (mjson_parser_t *context);
156 static int parse_key_value_pair(mjson_parser_t *context, int stop_token);
157 
158 static mjson_element_t next_element(mjson_element_t element);
159 
mjson_parse(const char * json_data,size_t json_data_size,void * storage_buf,size_t storage_buf_size,const mjson_entry_t ** top_element)160 int mjson_parse(const char *json_data, size_t json_data_size, void* storage_buf, size_t storage_buf_size, const mjson_entry_t** top_element)
161 {
162     uint32_t* fourcc;
163     mjson_parser_t c = {
164         TOK_NONE, 0,
165         (uint8_t*)json_data,   (uint8_t*)json_data + json_data_size,
166         (uint8_t*)storage_buf, (uint8_t*)storage_buf + storage_buf_size
167     };
168     int stop_token = TOK_NONE;
169 
170     *top_element = 0;
171 
172     fourcc = (uint32_t*)parsectx_allocate_output(&c, (ptrdiff_t)sizeof(uint32_t));
173 
174     if (!fourcc) return 0;
175 
176     *fourcc = '23JB';
177 
178     parsectx_next_token(&c);
179 
180     if (c.token == TOK_LEFT_BRACKET)
181     {
182         parsectx_next_token(&c);
183         if (!parse_value_list(&c))
184             return 0;
185     }
186     else
187     {
188         if (c.token == TOK_LEFT_CURLY_BRACKET)
189         {
190             stop_token = TOK_RIGHT_CURLY_BRACKET;
191             parsectx_next_token(&c);
192         }
193 
194         if (!parse_key_value_pair(&c, stop_token))
195             return 0;
196     }
197 
198     if (c.token != TOK_NONE)
199         return 0;
200 
201     *top_element = (mjson_entry_t*)(fourcc + 1);
202 
203     return 1;
204 }
205 
mjson_get_top_element(void * storage_buf,size_t storage_buf_size)206 mjson_element_t mjson_get_top_element(void* storage_buf, size_t storage_buf_size)
207 {
208     mjson_element_t top = (mjson_element_t)storage_buf;
209 
210     RETURN_VAL_IF_FAIL(top, NULL);
211     RETURN_VAL_IF_FAIL(top->id == MJSON_ID_DICT32 || top->id == MJSON_ID_ARRAY32, NULL);
212     RETURN_VAL_IF_FAIL(top->val_u32 <= storage_buf_size, NULL);
213 
214     return top;
215 }
216 
mjson_get_element_first(mjson_element_t array)217 mjson_element_t mjson_get_element_first(mjson_element_t array)
218 {
219     RETURN_VAL_IF_FAIL(array, NULL);
220     RETURN_VAL_IF_FAIL(array->id == MJSON_ID_ARRAY32, NULL);
221 
222     return array + 1;
223 }
224 
mjson_get_element_next(mjson_element_t array,mjson_element_t current_value)225 mjson_element_t mjson_get_element_next(mjson_element_t array, mjson_element_t current_value)
226 {
227     mjson_element_t next = NULL;
228 
229     RETURN_VAL_IF_FAIL(array, NULL);
230     RETURN_VAL_IF_FAIL(current_value, NULL);
231     RETURN_VAL_IF_FAIL(array->id == MJSON_ID_ARRAY32, NULL);
232     RETURN_VAL_IF_FAIL((uint8_t*)array + array->val_u32 > (uint8_t*)current_value, NULL);
233 
234     next = next_element(current_value);
235 
236     RETURN_VAL_IF_FAIL((uint8_t*)array + array->val_u32 > (uint8_t*)next, NULL);
237 
238     return next;
239 }
240 
mjson_get_element(mjson_element_t array,int index)241 mjson_element_t mjson_get_element(mjson_element_t array, int index)
242 {
243     mjson_element_t result;
244 
245     result = mjson_get_element_first(array);
246     while (result && index--)
247         result = mjson_get_element_next(array, result);
248 
249     return result;
250 }
251 
mjson_get_member_first(mjson_element_t dictionary,mjson_element_t * value)252 mjson_element_t mjson_get_member_first(mjson_element_t dictionary, mjson_element_t* value)
253 {
254     RETURN_VAL_IF_FAIL(dictionary, NULL);
255     RETURN_VAL_IF_FAIL(dictionary->id == MJSON_ID_DICT32, NULL);
256     RETURN_VAL_IF_FAIL((dictionary+1)->id == MJSON_ID_UTF8_KEY32, NULL);
257 
258     *value = next_element(dictionary+1);
259 
260     return dictionary + 1;
261 }
262 
mjson_get_member_next(mjson_element_t dictionary,mjson_element_t current_key,mjson_element_t * next_value)263 mjson_element_t mjson_get_member_next(mjson_element_t dictionary, mjson_element_t current_key, mjson_element_t* next_value)
264 {
265     mjson_element_t next_key = NULL;
266 
267     RETURN_VAL_IF_FAIL(dictionary, NULL);
268     RETURN_VAL_IF_FAIL(dictionary->id == MJSON_ID_DICT32, NULL);
269     RETURN_VAL_IF_FAIL(current_key, NULL);
270     RETURN_VAL_IF_FAIL((uint8_t*)dictionary + dictionary->val_u32 > (uint8_t*)current_key, NULL);
271     RETURN_VAL_IF_FAIL(current_key->id == MJSON_ID_UTF8_KEY32, NULL);
272 
273     next_key = next_element(current_key);
274     next_key = next_element(next_key);
275 
276     RETURN_VAL_IF_FAIL(next_key, NULL);
277     RETURN_VAL_IF_FAIL((uint8_t*)dictionary + dictionary->val_u32 > (uint8_t*)next_key, NULL);
278     RETURN_VAL_IF_FAIL(next_key->id == MJSON_ID_UTF8_KEY32, NULL);
279 
280     *next_value = next_element(next_key);
281 
282     return next_key;
283 }
284 
mjson_get_member(mjson_element_t dictionary,const char * name)285 mjson_element_t mjson_get_member(mjson_element_t dictionary, const char* name)
286 {
287     mjson_element_t key, result;
288 
289     key = mjson_get_member_first(dictionary, &result);
290     while (key && strncmp(name, (char*)(key+1), key->val_u32) != 0)
291         result = mjson_get_member_next(dictionary, key, &result);
292 
293     return result;
294 }
295 
mjson_get_type(mjson_element_t element)296 int mjson_get_type(mjson_element_t element)
297 {
298     RETURN_VAL_IF_FAIL(element, MJSON_ID_NULL);
299 
300     return element->id;
301 }
302 
mjson_get_string(mjson_element_t element,const char * fallback)303 const char* mjson_get_string(mjson_element_t element, const char* fallback)
304 {
305     RETURN_VAL_IF_FAIL(element, fallback);
306     RETURN_VAL_IF_FAIL(element->id == MJSON_ID_UTF8_STRING32 ||
307                        element->id == MJSON_ID_UTF8_KEY32,
308                        fallback);
309 
310     return (const char*)(element+1);
311 }
312 
mjson_get_int(mjson_element_t element,int32_t fallback)313 int32_t mjson_get_int(mjson_element_t element, int32_t fallback)
314 {
315     RETURN_VAL_IF_FAIL(element, fallback);
316     RETURN_VAL_IF_FAIL(element->id == MJSON_ID_SINT32, fallback);
317 
318     return element->val_s32;
319 }
320 
mjson_get_float(mjson_element_t element,float fallback)321 float mjson_get_float(mjson_element_t element, float fallback)
322 {
323     RETURN_VAL_IF_FAIL(element, fallback);
324     RETURN_VAL_IF_FAIL(element->id == MJSON_ID_FLOAT32, fallback);
325 
326     return element->val_f32;
327 }
328 
mjson_get_bool(mjson_element_t element,int fallback)329 int mjson_get_bool(mjson_element_t element, int fallback)
330 {
331     RETURN_VAL_IF_FAIL(element, fallback);
332     RETURN_VAL_IF_FAIL(element->id == MJSON_ID_TRUE || element->id == MJSON_ID_FALSE, fallback);
333 
334     return element->id == MJSON_ID_TRUE;
335 }
336 
mjson_is_null(mjson_element_t element)337 int mjson_is_null(mjson_element_t element)
338 {
339     RETURN_VAL_IF_FAIL(element, TRUE);
340 
341     return element->id == MJSON_ID_NULL;
342 }
343 
344 /////////////////////////////////////////////////////////////////////////////
345 // API helpers
346 /////////////////////////////////////////////////////////////////////////////
347 
element_size(mjson_element_t element)348 static size_t element_size(mjson_element_t element)
349 {
350     RETURN_VAL_IF_FAIL(element, 0);
351 
352     switch(element->id)
353     {
354         case MJSON_ID_NULL:
355         case MJSON_ID_FALSE:
356         case MJSON_ID_EMPTY_STRING:
357         case MJSON_ID_TRUE:
358             return sizeof(uint32_t);
359 
360         case MJSON_ID_UINT32:
361         case MJSON_ID_SINT32:
362         case MJSON_ID_FLOAT32:
363             return sizeof(mjson_entry_t);
364 
365         case MJSON_ID_UTF8_KEY32:
366         case MJSON_ID_UTF8_STRING32:
367             return sizeof(mjson_entry_t) + ((element->val_u32 + 1 + 3) & (~3));
368 
369         case MJSON_ID_BINARY32:
370         case MJSON_ID_ARRAY32:
371         case MJSON_ID_DICT32:
372             return sizeof(mjson_entry_t) + ((element->val_u32 + 3) & (~3));
373     };
374 
375     return 0;
376 }
377 
next_element(mjson_element_t element)378 static mjson_element_t next_element(mjson_element_t element)
379 {
380     size_t size;
381 
382     RETURN_VAL_IF_FAIL(element, 0);
383 
384     size = element_size(element);
385     assert(size>0);
386 
387     return (mjson_element_t)((uint8_t*)element + size);
388 }
389 
parsectx_reserve_output(mjson_parser_t * ctx,ptrdiff_t size)390 static void* parsectx_reserve_output(mjson_parser_t* ctx, ptrdiff_t size)
391 {
392     return (ctx->bjson_limit - ctx->bjson < size) ? 0 : ctx->bjson;
393 }
394 
parsectx_advance_output(mjson_parser_t * ctx,ptrdiff_t size)395 static void parsectx_advance_output(mjson_parser_t* ctx, ptrdiff_t size)
396 {
397     ctx->bjson += size;
398 }
399 
parsectx_allocate_output(mjson_parser_t * ctx,ptrdiff_t size)400 static void* parsectx_allocate_output(mjson_parser_t* ctx, ptrdiff_t size)
401 {
402     void* ptr;
403 
404     if (ctx->bjson_limit - ctx->bjson < size)
405         return 0;
406 
407     ptr = ctx->bjson;
408     ctx->bjson += size;
409 
410     return ptr;
411 }
412 
413 //TODO: what about 64 bit code????
parsectx_align4_output(mjson_parser_t * ctx)414 static void parsectx_align4_output(mjson_parser_t* ctx)
415 {
416     ctx->bjson = (uint8_t*)(((ptrdiff_t)ctx->bjson + 3) & (~3));
417 }
418 
unicode_cp_to_utf8(uint32_t uni_cp,uint8_t * utf8char,size_t * charlen)419 static void unicode_cp_to_utf8(uint32_t uni_cp, uint8_t* utf8char/*[6]*/, size_t* charlen)
420 {
421     uint32_t first, i;
422 
423     if (uni_cp < 0x80)
424     {
425         first   = 0;
426         *charlen = 1;
427     }
428     else if (uni_cp < 0x800)
429     {
430         first   = 0xc0;
431         *charlen = 2;
432     }
433     else if (uni_cp < 0x10000)
434     {
435         first   = 0xe0;
436         *charlen = 3;
437     }
438     else if (uni_cp < 0x200000)
439     {
440         first   = 0xf0;
441         *charlen = 4;
442     }
443     else if (uni_cp < 0x4000000)
444     {
445         first   = 0xf8;
446         *charlen = 5;
447     }
448     else
449     {
450         first   = 0xfc;
451         *charlen = 6;
452     }
453 
454     for (i = *charlen - 1; i > 0; --i)
455     {
456         utf8char[i] = (uni_cp & 0x3f) | 0x80;
457         uni_cp >>= 6;
458     }
459     utf8char[0] = uni_cp | first;
460 }
461 
462 /////////////////////////////////////////////////////////////////////////////
463 // Lexer+Parser code
464 /////////////////////////////////////////////////////////////////////////////
465 
466 #line 492 "input_custom_mjson.re"
467 
468 
parsectx_next_token(mjson_parser_t * context)469 static void parsectx_next_token(mjson_parser_t* context)
470 {
471 #define YYCTYPE        uint8_t
472 #define YYPEEK()       (c>=e?0:*c)
473 #define YYSKIP()       ++c
474 #define YYBACKUP()     m = c
475 #define YYRESTORE()    c = m
476 
477     uint8_t* c = context->next;
478     uint8_t* e = context->end;
479     uint8_t* m = NULL;
480     uint8_t* s;
481     int token = TOK_NONE;
482 
483     assert(context);
484     RETURN_IF_FAIL(context->next != NULL);
485 
486     while (TRUE)
487     {
488         s = c;
489 
490 
491 #line 492 "input_custom_mjson.c"
492         {
493             YYCTYPE yych;
494             unsigned int yyaccept = 0;
495             yych = YYPEEK();
496             switch (yych) {
497             case 0x00:    goto yy2;
498             case '\t':
499             case '\n':
500             case '\r':
501             case ' ':    goto yy6;
502             case '"':    goto yy9;
503             case '+':
504             case '-':    goto yy10;
505             case ',':    goto yy11;
506             case '.':    goto yy13;
507             case '/':    goto yy14;
508             case '0':    goto yy15;
509             case '1':
510             case '2':
511             case '3':
512             case '4':
513             case '5':
514             case '6':
515             case '7':
516             case '8':
517             case '9':    goto yy17;
518             case ':':    goto yy19;
519             case '=':    goto yy21;
520             case 'A':
521             case 'B':
522             case 'C':
523             case 'D':
524             case 'E':
525             case 'F':
526             case 'G':
527             case 'H':
528             case 'I':
529             case 'J':
530             case 'K':
531             case 'L':
532             case 'M':
533             case 'N':
534             case 'O':
535             case 'P':
536             case 'Q':
537             case 'R':
538             case 'S':
539             case 'T':
540             case 'U':
541             case 'V':
542             case 'W':
543             case 'X':
544             case 'Y':
545             case 'Z':
546             case '_':
547             case 'a':
548             case 'b':
549             case 'c':
550             case 'd':
551             case 'e':
552             case 'g':
553             case 'h':
554             case 'i':
555             case 'j':
556             case 'k':
557             case 'l':
558             case 'm':
559             case 'o':
560             case 'p':
561             case 'q':
562             case 'r':
563             case 's':
564             case 'u':
565             case 'v':
566             case 'w':
567             case 'x':
568             case 'y':
569             case 'z':    goto yy23;
570             case '[':    goto yy26;
571             case ']':    goto yy28;
572             case 'f':    goto yy30;
573             case 'n':    goto yy31;
574             case 't':    goto yy32;
575             case '{':    goto yy33;
576             case '}':    goto yy35;
577             default:    goto yy4;
578             }
579 yy2:
580             YYSKIP();
581 #line 613 "input_custom_mjson.re"
582             {
583                 context->token = TOK_NONE;
584                 return;
585             }
586 #line 587 "input_custom_mjson.c"
587 yy4:
588             YYSKIP();
589 yy5:
590 #line 623 "input_custom_mjson.re"
591             {
592                 context->token = TOK_INVALID;
593                 return;
594             }
595 #line 596 "input_custom_mjson.c"
596 yy6:
597             YYSKIP();
598             yych = YYPEEK();
599             switch (yych) {
600             case '\t':
601             case '\n':
602             case '\r':
603             case ' ':    goto yy6;
604             default:    goto yy8;
605             }
606 yy8:
607 #line 516 "input_custom_mjson.re"
608             {
609                 continue;
610             }
611 #line 612 "input_custom_mjson.c"
612 yy9:
613             yyaccept = 0;
614             YYSKIP();
615             YYBACKUP();
616             yych = YYPEEK();
617             if (yych <= 0x00) goto yy5;
618             goto yy38;
619 yy10:
620             yyaccept = 0;
621             YYSKIP();
622             YYBACKUP();
623             yych = YYPEEK();
624             switch (yych) {
625             case '.':    goto yy43;
626             case '0':    goto yy44;
627             case '1':
628             case '2':
629             case '3':
630             case '4':
631             case '5':
632             case '6':
633             case '7':
634             case '8':
635             case '9':    goto yy45;
636             default:    goto yy5;
637             }
638 yy11:
639             YYSKIP();
640 #line 558 "input_custom_mjson.re"
641             {
642                 token = TOK_COMMA;
643                 goto done;
644             }
645 #line 646 "input_custom_mjson.c"
646 yy13:
647             YYSKIP();
648             yych = YYPEEK();
649             switch (yych) {
650             case '0':
651             case '1':
652             case '2':
653             case '3':
654             case '4':
655             case '5':
656             case '6':
657             case '7':
658             case '8':
659             case '9':    goto yy47;
660             default:    goto yy5;
661             }
662 yy14:
663             yyaccept = 0;
664             YYSKIP();
665             YYBACKUP();
666             yych = YYPEEK();
667             switch (yych) {
668             case '*':    goto yy50;
669             case '/':    goto yy52;
670             default:    goto yy5;
671             }
672 yy15:
673             YYSKIP();
674             yych = YYPEEK();
675             switch (yych) {
676             case '.':
677             case '0':
678             case '1':
679             case '2':
680             case '3':
681             case '4':
682             case '5':
683             case '6':
684             case '7':
685             case '8':
686             case '9':
687             case 'A':
688             case 'B':
689             case 'C':
690             case 'D':
691             case 'E':
692             case 'F':
693             case 'G':
694             case 'H':
695             case 'I':
696             case 'J':
697             case 'K':
698             case 'L':
699             case 'M':
700             case 'N':
701             case 'O':
702             case 'P':
703             case 'Q':
704             case 'R':
705             case 'S':
706             case 'T':
707             case 'U':
708             case 'V':
709             case 'W':
710             case 'Y':
711             case 'Z':
712             case '_':
713             case 'a':
714             case 'b':
715             case 'c':
716             case 'd':
717             case 'e':
718             case 'f':
719             case 'g':
720             case 'h':
721             case 'i':
722             case 'j':
723             case 'k':
724             case 'l':
725             case 'm':
726             case 'n':
727             case 'o':
728             case 'p':
729             case 'q':
730             case 'r':
731             case 's':
732             case 't':
733             case 'u':
734             case 'v':
735             case 'w':
736             case 'y':
737             case 'z':    goto yy55;
738             case 'X':
739             case 'x':    goto yy63;
740             default:    goto yy16;
741             }
742 yy16:
743 #line 573 "input_custom_mjson.re"
744             {
745                 token = TOK_DEC_NUMBER;
746                 goto done;
747             }
748 #line 749 "input_custom_mjson.c"
749 yy17:
750             YYSKIP();
751             yych = YYPEEK();
752             switch (yych) {
753             case '.':    goto yy47;
754             case '0':
755             case '1':
756             case '2':
757             case '3':
758             case '4':
759             case '5':
760             case '6':
761             case '7':
762             case '8':
763             case '9':    goto yy17;
764             case 'A':
765             case 'B':
766             case 'C':
767             case 'D':
768             case 'F':
769             case 'G':
770             case 'H':
771             case 'I':
772             case 'J':
773             case 'K':
774             case 'L':
775             case 'M':
776             case 'N':
777             case 'O':
778             case 'P':
779             case 'Q':
780             case 'R':
781             case 'S':
782             case 'T':
783             case 'U':
784             case 'V':
785             case 'W':
786             case 'X':
787             case 'Y':
788             case 'Z':
789             case '_':
790             case 'a':
791             case 'b':
792             case 'c':
793             case 'd':
794             case 'f':
795             case 'g':
796             case 'h':
797             case 'i':
798             case 'j':
799             case 'k':
800             case 'l':
801             case 'm':
802             case 'n':
803             case 'o':
804             case 'p':
805             case 'q':
806             case 'r':
807             case 's':
808             case 't':
809             case 'u':
810             case 'v':
811             case 'w':
812             case 'x':
813             case 'y':
814             case 'z':    goto yy60;
815             case 'E':
816             case 'e':    goto yy62;
817             default:    goto yy16;
818             }
819 yy19:
820             YYSKIP();
821 #line 548 "input_custom_mjson.re"
822             {
823                 token = TOK_COLON;
824                 goto done;
825             }
826 #line 827 "input_custom_mjson.c"
827 yy21:
828             YYSKIP();
829 #line 553 "input_custom_mjson.re"
830             {
831                 token = TOK_EQUAL;
832                 goto done;
833             }
834 #line 835 "input_custom_mjson.c"
835 yy23:
836             YYSKIP();
837             yych = YYPEEK();
838 yy24:
839             switch (yych) {
840             case '0':
841             case '1':
842             case '2':
843             case '3':
844             case '4':
845             case '5':
846             case '6':
847             case '7':
848             case '8':
849             case '9':
850             case 'A':
851             case 'B':
852             case 'C':
853             case 'D':
854             case 'E':
855             case 'F':
856             case 'G':
857             case 'H':
858             case 'I':
859             case 'J':
860             case 'K':
861             case 'L':
862             case 'M':
863             case 'N':
864             case 'O':
865             case 'P':
866             case 'Q':
867             case 'R':
868             case 'S':
869             case 'T':
870             case 'U':
871             case 'V':
872             case 'W':
873             case 'X':
874             case 'Y':
875             case 'Z':
876             case '_':
877             case 'a':
878             case 'b':
879             case 'c':
880             case 'd':
881             case 'e':
882             case 'f':
883             case 'g':
884             case 'h':
885             case 'i':
886             case 'j':
887             case 'k':
888             case 'l':
889             case 'm':
890             case 'n':
891             case 'o':
892             case 'p':
893             case 'q':
894             case 'r':
895             case 's':
896             case 't':
897             case 'u':
898             case 'v':
899             case 'w':
900             case 'x':
901             case 'y':
902             case 'z':    goto yy23;
903             default:    goto yy25;
904             }
905 yy25:
906 #line 598 "input_custom_mjson.re"
907             {
908                 token = TOK_IDENTIFIER;
909                 goto done;
910             }
911 #line 912 "input_custom_mjson.c"
912 yy26:
913             YYSKIP();
914 #line 538 "input_custom_mjson.re"
915             {
916                 token = TOK_LEFT_BRACKET;
917                 goto done;
918             }
919 #line 920 "input_custom_mjson.c"
920 yy28:
921             YYSKIP();
922 #line 543 "input_custom_mjson.re"
923             {
924                 token = TOK_RIGHT_BRACKET;
925                 goto done;
926             }
927 #line 928 "input_custom_mjson.c"
928 yy30:
929             YYSKIP();
930             yych = YYPEEK();
931             switch (yych) {
932             case 'a':    goto yy64;
933             default:    goto yy24;
934             }
935 yy31:
936             YYSKIP();
937             yych = YYPEEK();
938             switch (yych) {
939             case 'u':    goto yy65;
940             default:    goto yy24;
941             }
942 yy32:
943             YYSKIP();
944             yych = YYPEEK();
945             switch (yych) {
946             case 'r':    goto yy66;
947             default:    goto yy24;
948             }
949 yy33:
950             YYSKIP();
951 #line 528 "input_custom_mjson.re"
952             {
953                 token = TOK_LEFT_CURLY_BRACKET;
954                 goto done;
955             }
956 #line 957 "input_custom_mjson.c"
957 yy35:
958             YYSKIP();
959 #line 533 "input_custom_mjson.re"
960             {
961                 token = TOK_RIGHT_CURLY_BRACKET;
962                 goto done;
963             }
964 #line 965 "input_custom_mjson.c"
965 yy37:
966             YYSKIP();
967             yych = YYPEEK();
968 yy38:
969             switch (yych) {
970             case 0x00:    goto yy39;
971             case '"':    goto yy40;
972             case '\\':    goto yy42;
973             default:    goto yy37;
974             }
975 yy39:
976             YYRESTORE();
977             switch (yyaccept) {
978             case 0:
979                 goto yy5;
980             case 1:
981                 goto yy16;
982             case 2:
983                 goto yy49;
984             case 3:
985                 goto yy59;
986             default:
987                 goto yy93;
988             }
989 yy40:
990             YYSKIP();
991 #line 603 "input_custom_mjson.re"
992             {
993                 token = TOK_NOESC_STRING;
994                 goto done;
995             }
996 #line 997 "input_custom_mjson.c"
997 yy42:
998             YYSKIP();
999             yych = YYPEEK();
1000             switch (yych) {
1001             case '"':
1002             case '/':
1003             case '\\':
1004             case 'b':
1005             case 'f':
1006             case 'n':
1007             case 'r':
1008             case 't':    goto yy67;
1009             case 'u':    goto yy69;
1010             default:    goto yy39;
1011             }
1012 yy43:
1013             YYSKIP();
1014             yych = YYPEEK();
1015             switch (yych) {
1016             case '0':
1017             case '1':
1018             case '2':
1019             case '3':
1020             case '4':
1021             case '5':
1022             case '6':
1023             case '7':
1024             case '8':
1025             case '9':    goto yy47;
1026             default:    goto yy39;
1027             }
1028 yy44:
1029             yyaccept = 1;
1030             YYSKIP();
1031             YYBACKUP();
1032             yych = YYPEEK();
1033             switch (yych) {
1034             case '.':    goto yy47;
1035             case '0':
1036             case '1':
1037             case '2':
1038             case '3':
1039             case '4':
1040             case '5':
1041             case '6':
1042             case '7':
1043             case '8':
1044             case '9':    goto yy70;
1045             case 'E':
1046             case 'e':    goto yy72;
1047             default:    goto yy16;
1048             }
1049 yy45:
1050             yyaccept = 1;
1051             YYSKIP();
1052             YYBACKUP();
1053             yych = YYPEEK();
1054             switch (yych) {
1055             case '.':    goto yy47;
1056             case '0':
1057             case '1':
1058             case '2':
1059             case '3':
1060             case '4':
1061             case '5':
1062             case '6':
1063             case '7':
1064             case '8':
1065             case '9':    goto yy45;
1066             case 'E':
1067             case 'e':    goto yy72;
1068             default:    goto yy16;
1069             }
1070 yy47:
1071             yyaccept = 2;
1072             YYSKIP();
1073             YYBACKUP();
1074             yych = YYPEEK();
1075             switch (yych) {
1076             case '0':
1077             case '1':
1078             case '2':
1079             case '3':
1080             case '4':
1081             case '5':
1082             case '6':
1083             case '7':
1084             case '8':
1085             case '9':    goto yy47;
1086             case 'E':
1087             case 'e':    goto yy72;
1088             default:    goto yy49;
1089             }
1090 yy49:
1091 #line 578 "input_custom_mjson.re"
1092             {
1093                 token = TOK_FLOAT_NUMBER;
1094                 goto done;
1095             }
1096 #line 1097 "input_custom_mjson.c"
1097 yy50:
1098             YYSKIP();
1099             yych = YYPEEK();
1100             switch (yych) {
1101             case 0x00:    goto yy39;
1102             case '*':    goto yy73;
1103             default:    goto yy50;
1104             }
1105 yy52:
1106             YYSKIP();
1107             yych = YYPEEK();
1108             switch (yych) {
1109             case 0x00:    goto yy39;
1110             case '\n':    goto yy74;
1111             default:    goto yy52;
1112             }
1113 yy54:
1114             YYSKIP();
1115             yych = YYPEEK();
1116 yy55:
1117             switch (yych) {
1118             case '.':    goto yy47;
1119             case '0':
1120             case '1':
1121             case '2':
1122             case '3':
1123             case '4':
1124             case '5':
1125             case '6':
1126             case '7':    goto yy54;
1127             case '8':
1128             case '9':    goto yy57;
1129             case 'A':
1130             case 'B':
1131             case 'C':
1132             case 'D':
1133             case 'F':
1134             case 'G':
1135             case 'H':
1136             case 'I':
1137             case 'J':
1138             case 'K':
1139             case 'L':
1140             case 'M':
1141             case 'N':
1142             case 'O':
1143             case 'P':
1144             case 'Q':
1145             case 'R':
1146             case 'S':
1147             case 'T':
1148             case 'U':
1149             case 'V':
1150             case 'W':
1151             case 'X':
1152             case 'Y':
1153             case 'Z':
1154             case '_':
1155             case 'a':
1156             case 'b':
1157             case 'c':
1158             case 'd':
1159             case 'f':
1160             case 'g':
1161             case 'h':
1162             case 'i':
1163             case 'j':
1164             case 'k':
1165             case 'l':
1166             case 'm':
1167             case 'n':
1168             case 'o':
1169             case 'p':
1170             case 'q':
1171             case 'r':
1172             case 's':
1173             case 't':
1174             case 'u':
1175             case 'v':
1176             case 'w':
1177             case 'x':
1178             case 'y':
1179             case 'z':    goto yy60;
1180             case 'E':
1181             case 'e':    goto yy62;
1182             default:    goto yy56;
1183             }
1184 yy56:
1185 #line 563 "input_custom_mjson.re"
1186             {
1187                 token = TOK_OCT_NUMBER;
1188                 goto done;
1189             }
1190 #line 1191 "input_custom_mjson.c"
1191 yy57:
1192             YYSKIP();
1193             yych = YYPEEK();
1194             switch (yych) {
1195             case '.':    goto yy47;
1196             case '0':
1197             case '1':
1198             case '2':
1199             case '3':
1200             case '4':
1201             case '5':
1202             case '6':
1203             case '7':
1204             case '8':
1205             case '9':    goto yy57;
1206             case 'A':
1207             case 'B':
1208             case 'C':
1209             case 'D':
1210             case 'F':
1211             case 'G':
1212             case 'H':
1213             case 'I':
1214             case 'J':
1215             case 'K':
1216             case 'L':
1217             case 'M':
1218             case 'N':
1219             case 'O':
1220             case 'P':
1221             case 'Q':
1222             case 'R':
1223             case 'S':
1224             case 'T':
1225             case 'U':
1226             case 'V':
1227             case 'W':
1228             case 'X':
1229             case 'Y':
1230             case 'Z':
1231             case '_':
1232             case 'a':
1233             case 'b':
1234             case 'c':
1235             case 'd':
1236             case 'f':
1237             case 'g':
1238             case 'h':
1239             case 'i':
1240             case 'j':
1241             case 'k':
1242             case 'l':
1243             case 'm':
1244             case 'n':
1245             case 'o':
1246             case 'p':
1247             case 'q':
1248             case 'r':
1249             case 's':
1250             case 't':
1251             case 'u':
1252             case 'v':
1253             case 'w':
1254             case 'x':
1255             case 'y':
1256             case 'z':    goto yy60;
1257             case 'E':
1258             case 'e':    goto yy62;
1259             default:    goto yy59;
1260             }
1261 yy59:
1262 #line 618 "input_custom_mjson.re"
1263             {
1264                 context->token = TOK_INVALID;
1265                 return;
1266             }
1267 #line 1268 "input_custom_mjson.c"
1268 yy60:
1269             YYSKIP();
1270             yych = YYPEEK();
1271 yy61:
1272             switch (yych) {
1273             case '0':
1274             case '1':
1275             case '2':
1276             case '3':
1277             case '4':
1278             case '5':
1279             case '6':
1280             case '7':
1281             case '8':
1282             case '9':
1283             case 'A':
1284             case 'B':
1285             case 'C':
1286             case 'D':
1287             case 'E':
1288             case 'F':
1289             case 'G':
1290             case 'H':
1291             case 'I':
1292             case 'J':
1293             case 'K':
1294             case 'L':
1295             case 'M':
1296             case 'N':
1297             case 'O':
1298             case 'P':
1299             case 'Q':
1300             case 'R':
1301             case 'S':
1302             case 'T':
1303             case 'U':
1304             case 'V':
1305             case 'W':
1306             case 'X':
1307             case 'Y':
1308             case 'Z':
1309             case '_':
1310             case 'a':
1311             case 'b':
1312             case 'c':
1313             case 'd':
1314             case 'e':
1315             case 'f':
1316             case 'g':
1317             case 'h':
1318             case 'i':
1319             case 'j':
1320             case 'k':
1321             case 'l':
1322             case 'm':
1323             case 'n':
1324             case 'o':
1325             case 'p':
1326             case 'q':
1327             case 'r':
1328             case 's':
1329             case 't':
1330             case 'u':
1331             case 'v':
1332             case 'w':
1333             case 'x':
1334             case 'y':
1335             case 'z':    goto yy60;
1336             default:    goto yy59;
1337             }
1338 yy62:
1339             yyaccept = 3;
1340             YYSKIP();
1341             YYBACKUP();
1342             yych = YYPEEK();
1343             switch (yych) {
1344             case '+':
1345             case '-':    goto yy76;
1346             case '0':
1347             case '1':
1348             case '2':
1349             case '3':
1350             case '4':
1351             case '5':
1352             case '6':
1353             case '7':
1354             case '8':
1355             case '9':    goto yy77;
1356             default:    goto yy61;
1357             }
1358 yy63:
1359             YYSKIP();
1360             yych = YYPEEK();
1361             switch (yych) {
1362             case '0':
1363             case '1':
1364             case '2':
1365             case '3':
1366             case '4':
1367             case '5':
1368             case '6':
1369             case '7':
1370             case '8':
1371             case '9':
1372             case 'A':
1373             case 'B':
1374             case 'C':
1375             case 'D':
1376             case 'E':
1377             case 'F':
1378             case 'G':
1379             case 'H':
1380             case 'I':
1381             case 'J':
1382             case 'K':
1383             case 'L':
1384             case 'M':
1385             case 'N':
1386             case 'O':
1387             case 'P':
1388             case 'Q':
1389             case 'R':
1390             case 'S':
1391             case 'T':
1392             case 'U':
1393             case 'V':
1394             case 'W':
1395             case 'X':
1396             case 'Y':
1397             case 'Z':
1398             case '_':
1399             case 'a':
1400             case 'b':
1401             case 'c':
1402             case 'd':
1403             case 'e':
1404             case 'f':
1405             case 'g':
1406             case 'h':
1407             case 'i':
1408             case 'j':
1409             case 'k':
1410             case 'l':
1411             case 'm':
1412             case 'n':
1413             case 'o':
1414             case 'p':
1415             case 'q':
1416             case 'r':
1417             case 's':
1418             case 't':
1419             case 'u':
1420             case 'v':
1421             case 'w':
1422             case 'x':
1423             case 'y':
1424             case 'z':    goto yy80;
1425             default:    goto yy59;
1426             }
1427 yy64:
1428             YYSKIP();
1429             yych = YYPEEK();
1430             switch (yych) {
1431             case 'l':    goto yy82;
1432             default:    goto yy24;
1433             }
1434 yy65:
1435             YYSKIP();
1436             yych = YYPEEK();
1437             switch (yych) {
1438             case 'l':    goto yy83;
1439             default:    goto yy24;
1440             }
1441 yy66:
1442             YYSKIP();
1443             yych = YYPEEK();
1444             switch (yych) {
1445             case 'u':    goto yy84;
1446             default:    goto yy24;
1447             }
1448 yy67:
1449             YYSKIP();
1450             yych = YYPEEK();
1451             switch (yych) {
1452             case 0x00:    goto yy39;
1453             case '"':    goto yy85;
1454             case '\\':    goto yy42;
1455             default:    goto yy67;
1456             }
1457 yy69:
1458             YYSKIP();
1459             yych = YYPEEK();
1460             switch (yych) {
1461             case '0':
1462             case '1':
1463             case '2':
1464             case '3':
1465             case '4':
1466             case '5':
1467             case '6':
1468             case '7':
1469             case '8':
1470             case '9':
1471             case 'A':
1472             case 'B':
1473             case 'C':
1474             case 'D':
1475             case 'E':
1476             case 'F':
1477             case 'a':
1478             case 'b':
1479             case 'c':
1480             case 'd':
1481             case 'e':
1482             case 'f':    goto yy87;
1483             default:    goto yy39;
1484             }
1485 yy70:
1486             YYSKIP();
1487             yych = YYPEEK();
1488             switch (yych) {
1489             case '.':    goto yy47;
1490             case '0':
1491             case '1':
1492             case '2':
1493             case '3':
1494             case '4':
1495             case '5':
1496             case '6':
1497             case '7':
1498             case '8':
1499             case '9':    goto yy70;
1500             case 'E':
1501             case 'e':    goto yy72;
1502             default:    goto yy39;
1503             }
1504 yy72:
1505             YYSKIP();
1506             yych = YYPEEK();
1507             switch (yych) {
1508             case '+':
1509             case '-':    goto yy76;
1510             case '0':
1511             case '1':
1512             case '2':
1513             case '3':
1514             case '4':
1515             case '5':
1516             case '6':
1517             case '7':
1518             case '8':
1519             case '9':    goto yy88;
1520             default:    goto yy39;
1521             }
1522 yy73:
1523             YYSKIP();
1524             yych = YYPEEK();
1525             switch (yych) {
1526             case 0x00:    goto yy39;
1527             case '*':    goto yy90;
1528             case '/':    goto yy92;
1529             default:    goto yy50;
1530             }
1531 yy74:
1532             YYSKIP();
1533 #line 520 "input_custom_mjson.re"
1534             {
1535                 continue;
1536             }
1537 #line 1538 "input_custom_mjson.c"
1538 yy76:
1539             YYSKIP();
1540             yych = YYPEEK();
1541             switch (yych) {
1542             case '0':
1543             case '1':
1544             case '2':
1545             case '3':
1546             case '4':
1547             case '5':
1548             case '6':
1549             case '7':
1550             case '8':
1551             case '9':    goto yy88;
1552             default:    goto yy39;
1553             }
1554 yy77:
1555             YYSKIP();
1556             yych = YYPEEK();
1557             switch (yych) {
1558             case '0':
1559             case '1':
1560             case '2':
1561             case '3':
1562             case '4':
1563             case '5':
1564             case '6':
1565             case '7':
1566             case '8':
1567             case '9':    goto yy77;
1568             case 'A':
1569             case 'B':
1570             case 'C':
1571             case 'D':
1572             case 'E':
1573             case 'F':
1574             case 'G':
1575             case 'H':
1576             case 'I':
1577             case 'J':
1578             case 'K':
1579             case 'L':
1580             case 'M':
1581             case 'N':
1582             case 'O':
1583             case 'P':
1584             case 'Q':
1585             case 'R':
1586             case 'S':
1587             case 'T':
1588             case 'U':
1589             case 'V':
1590             case 'W':
1591             case 'X':
1592             case 'Y':
1593             case 'Z':
1594             case '_':
1595             case 'a':
1596             case 'b':
1597             case 'c':
1598             case 'd':
1599             case 'e':
1600             case 'f':
1601             case 'g':
1602             case 'h':
1603             case 'i':
1604             case 'j':
1605             case 'k':
1606             case 'l':
1607             case 'm':
1608             case 'n':
1609             case 'o':
1610             case 'p':
1611             case 'q':
1612             case 'r':
1613             case 's':
1614             case 't':
1615             case 'u':
1616             case 'v':
1617             case 'w':
1618             case 'x':
1619             case 'y':
1620             case 'z':    goto yy60;
1621             default:    goto yy49;
1622             }
1623 yy79:
1624             YYSKIP();
1625             yych = YYPEEK();
1626 yy80:
1627             switch (yych) {
1628             case '0':
1629             case '1':
1630             case '2':
1631             case '3':
1632             case '4':
1633             case '5':
1634             case '6':
1635             case '7':
1636             case '8':
1637             case '9':
1638             case 'A':
1639             case 'B':
1640             case 'C':
1641             case 'D':
1642             case 'E':
1643             case 'F':
1644             case 'a':
1645             case 'b':
1646             case 'c':
1647             case 'd':
1648             case 'e':
1649             case 'f':    goto yy79;
1650             case 'G':
1651             case 'H':
1652             case 'I':
1653             case 'J':
1654             case 'K':
1655             case 'L':
1656             case 'M':
1657             case 'N':
1658             case 'O':
1659             case 'P':
1660             case 'Q':
1661             case 'R':
1662             case 'S':
1663             case 'T':
1664             case 'U':
1665             case 'V':
1666             case 'W':
1667             case 'X':
1668             case 'Y':
1669             case 'Z':
1670             case '_':
1671             case 'g':
1672             case 'h':
1673             case 'i':
1674             case 'j':
1675             case 'k':
1676             case 'l':
1677             case 'm':
1678             case 'n':
1679             case 'o':
1680             case 'p':
1681             case 'q':
1682             case 'r':
1683             case 's':
1684             case 't':
1685             case 'u':
1686             case 'v':
1687             case 'w':
1688             case 'x':
1689             case 'y':
1690             case 'z':    goto yy60;
1691             default:    goto yy81;
1692             }
1693 yy81:
1694 #line 568 "input_custom_mjson.re"
1695             {
1696                 token = TOK_HEX_NUMBER;
1697                 goto done;
1698             }
1699 #line 1700 "input_custom_mjson.c"
1700 yy82:
1701             YYSKIP();
1702             yych = YYPEEK();
1703             switch (yych) {
1704             case 's':    goto yy94;
1705             default:    goto yy24;
1706             }
1707 yy83:
1708             YYSKIP();
1709             yych = YYPEEK();
1710             switch (yych) {
1711             case 'l':    goto yy95;
1712             default:    goto yy24;
1713             }
1714 yy84:
1715             YYSKIP();
1716             yych = YYPEEK();
1717             switch (yych) {
1718             case 'e':    goto yy97;
1719             default:    goto yy24;
1720             }
1721 yy85:
1722             YYSKIP();
1723 #line 608 "input_custom_mjson.re"
1724             {
1725                 token = TOK_STRING;
1726                 goto done;
1727             }
1728 #line 1729 "input_custom_mjson.c"
1729 yy87:
1730             YYSKIP();
1731             yych = YYPEEK();
1732             switch (yych) {
1733             case '0':
1734             case '1':
1735             case '2':
1736             case '3':
1737             case '4':
1738             case '5':
1739             case '6':
1740             case '7':
1741             case '8':
1742             case '9':
1743             case 'A':
1744             case 'B':
1745             case 'C':
1746             case 'D':
1747             case 'E':
1748             case 'F':
1749             case 'a':
1750             case 'b':
1751             case 'c':
1752             case 'd':
1753             case 'e':
1754             case 'f':    goto yy99;
1755             default:    goto yy39;
1756             }
1757 yy88:
1758             YYSKIP();
1759             yych = YYPEEK();
1760             switch (yych) {
1761             case '0':
1762             case '1':
1763             case '2':
1764             case '3':
1765             case '4':
1766             case '5':
1767             case '6':
1768             case '7':
1769             case '8':
1770             case '9':    goto yy88;
1771             default:    goto yy49;
1772             }
1773 yy90:
1774             YYSKIP();
1775             yych = YYPEEK();
1776             switch (yych) {
1777             case 0x00:    goto yy39;
1778             case '*':    goto yy90;
1779             case '/':    goto yy100;
1780             default:    goto yy50;
1781             }
1782 yy92:
1783             YYSKIP();
1784 yy93:
1785 #line 524 "input_custom_mjson.re"
1786             {
1787                 continue;
1788             }
1789 #line 1790 "input_custom_mjson.c"
1790 yy94:
1791             YYSKIP();
1792             yych = YYPEEK();
1793             switch (yych) {
1794             case 'e':    goto yy101;
1795             default:    goto yy24;
1796             }
1797 yy95:
1798             YYSKIP();
1799             yych = YYPEEK();
1800             switch (yych) {
1801             case '0':
1802             case '1':
1803             case '2':
1804             case '3':
1805             case '4':
1806             case '5':
1807             case '6':
1808             case '7':
1809             case '8':
1810             case '9':
1811             case 'A':
1812             case 'B':
1813             case 'C':
1814             case 'D':
1815             case 'E':
1816             case 'F':
1817             case 'G':
1818             case 'H':
1819             case 'I':
1820             case 'J':
1821             case 'K':
1822             case 'L':
1823             case 'M':
1824             case 'N':
1825             case 'O':
1826             case 'P':
1827             case 'Q':
1828             case 'R':
1829             case 'S':
1830             case 'T':
1831             case 'U':
1832             case 'V':
1833             case 'W':
1834             case 'X':
1835             case 'Y':
1836             case 'Z':
1837             case '_':
1838             case 'a':
1839             case 'b':
1840             case 'c':
1841             case 'd':
1842             case 'e':
1843             case 'f':
1844             case 'g':
1845             case 'h':
1846             case 'i':
1847             case 'j':
1848             case 'k':
1849             case 'l':
1850             case 'm':
1851             case 'n':
1852             case 'o':
1853             case 'p':
1854             case 'q':
1855             case 'r':
1856             case 's':
1857             case 't':
1858             case 'u':
1859             case 'v':
1860             case 'w':
1861             case 'x':
1862             case 'y':
1863             case 'z':    goto yy23;
1864             default:    goto yy96;
1865             }
1866 yy96:
1867 #line 593 "input_custom_mjson.re"
1868             {
1869                 token = TOK_NULL;
1870                 goto done;
1871             }
1872 #line 1873 "input_custom_mjson.c"
1873 yy97:
1874             YYSKIP();
1875             yych = YYPEEK();
1876             switch (yych) {
1877             case '0':
1878             case '1':
1879             case '2':
1880             case '3':
1881             case '4':
1882             case '5':
1883             case '6':
1884             case '7':
1885             case '8':
1886             case '9':
1887             case 'A':
1888             case 'B':
1889             case 'C':
1890             case 'D':
1891             case 'E':
1892             case 'F':
1893             case 'G':
1894             case 'H':
1895             case 'I':
1896             case 'J':
1897             case 'K':
1898             case 'L':
1899             case 'M':
1900             case 'N':
1901             case 'O':
1902             case 'P':
1903             case 'Q':
1904             case 'R':
1905             case 'S':
1906             case 'T':
1907             case 'U':
1908             case 'V':
1909             case 'W':
1910             case 'X':
1911             case 'Y':
1912             case 'Z':
1913             case '_':
1914             case 'a':
1915             case 'b':
1916             case 'c':
1917             case 'd':
1918             case 'e':
1919             case 'f':
1920             case 'g':
1921             case 'h':
1922             case 'i':
1923             case 'j':
1924             case 'k':
1925             case 'l':
1926             case 'm':
1927             case 'n':
1928             case 'o':
1929             case 'p':
1930             case 'q':
1931             case 'r':
1932             case 's':
1933             case 't':
1934             case 'u':
1935             case 'v':
1936             case 'w':
1937             case 'x':
1938             case 'y':
1939             case 'z':    goto yy23;
1940             default:    goto yy98;
1941             }
1942 yy98:
1943 #line 583 "input_custom_mjson.re"
1944             {
1945                 token = TOK_TRUE;
1946                 goto done;
1947             }
1948 #line 1949 "input_custom_mjson.c"
1949 yy99:
1950             YYSKIP();
1951             yych = YYPEEK();
1952             switch (yych) {
1953             case '0':
1954             case '1':
1955             case '2':
1956             case '3':
1957             case '4':
1958             case '5':
1959             case '6':
1960             case '7':
1961             case '8':
1962             case '9':
1963             case 'A':
1964             case 'B':
1965             case 'C':
1966             case 'D':
1967             case 'E':
1968             case 'F':
1969             case 'a':
1970             case 'b':
1971             case 'c':
1972             case 'd':
1973             case 'e':
1974             case 'f':    goto yy103;
1975             default:    goto yy39;
1976             }
1977 yy100:
1978             yyaccept = 4;
1979             YYSKIP();
1980             YYBACKUP();
1981             yych = YYPEEK();
1982             switch (yych) {
1983             case 0x00:    goto yy93;
1984             case '*':    goto yy73;
1985             default:    goto yy50;
1986             }
1987 yy101:
1988             YYSKIP();
1989             yych = YYPEEK();
1990             switch (yych) {
1991             case '0':
1992             case '1':
1993             case '2':
1994             case '3':
1995             case '4':
1996             case '5':
1997             case '6':
1998             case '7':
1999             case '8':
2000             case '9':
2001             case 'A':
2002             case 'B':
2003             case 'C':
2004             case 'D':
2005             case 'E':
2006             case 'F':
2007             case 'G':
2008             case 'H':
2009             case 'I':
2010             case 'J':
2011             case 'K':
2012             case 'L':
2013             case 'M':
2014             case 'N':
2015             case 'O':
2016             case 'P':
2017             case 'Q':
2018             case 'R':
2019             case 'S':
2020             case 'T':
2021             case 'U':
2022             case 'V':
2023             case 'W':
2024             case 'X':
2025             case 'Y':
2026             case 'Z':
2027             case '_':
2028             case 'a':
2029             case 'b':
2030             case 'c':
2031             case 'd':
2032             case 'e':
2033             case 'f':
2034             case 'g':
2035             case 'h':
2036             case 'i':
2037             case 'j':
2038             case 'k':
2039             case 'l':
2040             case 'm':
2041             case 'n':
2042             case 'o':
2043             case 'p':
2044             case 'q':
2045             case 'r':
2046             case 's':
2047             case 't':
2048             case 'u':
2049             case 'v':
2050             case 'w':
2051             case 'x':
2052             case 'y':
2053             case 'z':    goto yy23;
2054             default:    goto yy102;
2055             }
2056 yy102:
2057 #line 588 "input_custom_mjson.re"
2058             {
2059                 token = TOK_FALSE;
2060                 goto done;
2061             }
2062 #line 2063 "input_custom_mjson.c"
2063 yy103:
2064             YYSKIP();
2065             yych = YYPEEK();
2066             switch (yych) {
2067             case '0':
2068             case '1':
2069             case '2':
2070             case '3':
2071             case '4':
2072             case '5':
2073             case '6':
2074             case '7':
2075             case '8':
2076             case '9':
2077             case 'A':
2078             case 'B':
2079             case 'C':
2080             case 'D':
2081             case 'E':
2082             case 'F':
2083             case 'a':
2084             case 'b':
2085             case 'c':
2086             case 'd':
2087             case 'e':
2088             case 'f':    goto yy67;
2089             default:    goto yy39;
2090             }
2091         }
2092 #line 627 "input_custom_mjson.re"
2093 
2094     }
2095 
2096 done:
2097     context->token = token;
2098     context->start = s;
2099     context->next  = c;
2100 
2101 #undef YYREADINPUT
2102 #undef YYCTYPE
2103 #undef YYCURSOR
2104 #undef YYMARKER
2105 }
2106 
parse_number(mjson_parser_t * context)2107 static int parse_number(mjson_parser_t *context)
2108 {
2109     int            num_parsed;
2110     uint8_t        bjson_id;
2111     const char*    format;
2112     mjson_entry_t* bdata;
2113 
2114     switch(context->token)
2115     {
2116         case TOK_OCT_NUMBER:
2117             bjson_id = MJSON_ID_SINT32;
2118             format   = "%o";
2119             break;
2120         case TOK_HEX_NUMBER:
2121             bjson_id = MJSON_ID_SINT32;
2122             format   = "%x";
2123             break;
2124         case TOK_DEC_NUMBER:
2125             bjson_id = MJSON_ID_SINT32;
2126             format   = "%d";
2127             break;
2128         case TOK_FLOAT_NUMBER:
2129             bjson_id = MJSON_ID_FLOAT32;
2130             format   = "%f";
2131             break;
2132         default:
2133             assert(!"unknown token");
2134     }
2135 
2136     bdata = (mjson_entry_t*)parsectx_allocate_output(context, (ptrdiff_t)sizeof(mjson_entry_t));
2137 
2138     if (!bdata) return 0;
2139 
2140     bdata->id = bjson_id;
2141     num_parsed = sscanf((char*)context->start, format, &bdata->val_u32);
2142     assert(num_parsed == 1);
2143 
2144     parsectx_next_token(context);
2145     return 1;
2146 }
2147 
parse_string(mjson_parser_t * context,uint32_t id)2148 static int parse_string(mjson_parser_t *context, uint32_t id)
2149 {
2150 #define YYREADINPUT(c) (c>=e?0:*c)
2151 #define YYCTYPE        uint8_t
2152 #define YYCURSOR       c
2153 #define YYMARKER       m
2154 
2155     uint8_t* c = context->start+1;
2156     uint8_t* e = context->next;
2157     uint8_t* m = NULL;
2158     uint8_t* s;
2159 
2160     mjson_entry_t* bdata;
2161     uint32_t       ch = 0;
2162     uint8_t*       str_dst;
2163     const uint8_t* str_src;
2164     ptrdiff_t      str_len;
2165     size_t         len;
2166     int            num_parsed;
2167 
2168     assert(
2169         context->token == TOK_STRING       ||
2170         context->token == TOK_NOESC_STRING ||
2171         context->token == TOK_IDENTIFIER
2172     );
2173 
2174     bdata = (mjson_entry_t*)parsectx_allocate_output(context, (ptrdiff_t)sizeof(mjson_entry_t));
2175 
2176     if (!bdata) return 0;
2177 
2178     bdata->id = id;
2179 
2180     if (context->token != TOK_STRING)
2181     {
2182         str_src = context->start;
2183         str_len = context->next - context->start;
2184 
2185         if (context->token==TOK_NOESC_STRING)
2186         {
2187             str_src += 1;
2188             str_len -= 2;
2189         }
2190 
2191         bdata->val_u32 = str_len;
2192 
2193         str_dst = (uint8_t*)parsectx_allocate_output(context, str_len + 1);
2194 
2195         if (!str_dst) return 0;
2196 
2197         memcpy(str_dst, str_src, str_len);
2198         str_dst[str_len] = 0;
2199 
2200         parsectx_align4_output(context);
2201 
2202         parsectx_next_token(context);
2203 
2204         return 1;
2205     }
2206 
2207     while (TRUE)
2208     {
2209         s = c;
2210 
2211 
2212 #line 2213 "input_custom_mjson.c"
2213         {
2214             YYCTYPE yych;
2215             yych = YYPEEK();
2216             switch (yych) {
2217             case 0x00:    goto yy106;
2218             case '"':    goto yy111;
2219             case '\\':    goto yy113;
2220             default:    goto yy108;
2221             }
2222 yy106:
2223             YYSKIP();
2224 yy107:
2225 #line 811 "input_custom_mjson.re"
2226             {
2227                 assert(!"reachable");
2228             }
2229 #line 2230 "input_custom_mjson.c"
2230 yy108:
2231             YYSKIP();
2232             yych = YYPEEK();
2233             switch (yych) {
2234             case 0x00:
2235             case '"':
2236             case '\\':    goto yy110;
2237             default:    goto yy108;
2238             }
2239 yy110:
2240 #line 746 "input_custom_mjson.re"
2241             {
2242                 str_dst = (uint8_t*)parsectx_allocate_output(context, c - s);
2243 
2244                 if (!str_dst) return 0;
2245 
2246                 memcpy(str_dst, s, c - s);
2247 
2248                 continue;
2249             }
2250 #line 2251 "input_custom_mjson.c"
2251 yy111:
2252             YYSKIP();
2253 #line 802 "input_custom_mjson.re"
2254             {
2255                 bdata->val_u32 = context->bjson - (uint8_t*)(bdata + 1);
2256                 *context->bjson++ = 0;
2257                 parsectx_align4_output(context);
2258                 parsectx_next_token(context);
2259 
2260                 return 1;
2261             }
2262 #line 2263 "input_custom_mjson.c"
2263 yy113:
2264             YYSKIP();
2265             YYBACKUP();
2266             yych = YYPEEK();
2267             switch (yych) {
2268             case '"':
2269             case '/':
2270             case '\\':
2271             case 'b':
2272             case 'f':
2273             case 'n':
2274             case 'r':
2275             case 't':    goto yy114;
2276             case 'u':    goto yy116;
2277             default:    goto yy107;
2278             }
2279 yy114:
2280             YYSKIP();
2281 #line 757 "input_custom_mjson.re"
2282             {
2283                 char decoded = s[1];
2284 
2285                 switch (s[1])
2286                 {
2287                     case 'b':
2288                         decoded = '\b';
2289                         break;
2290                     case 'n':
2291                         decoded = '\n';
2292                         break;
2293                     case 'r':
2294                         decoded = '\r';
2295                         break;
2296                     case 't':
2297                         decoded = '\t';
2298                         break;
2299                     case 'f':
2300                         decoded = '\f';
2301                         break;
2302                 }
2303 
2304                 str_dst = (uint8_t*)parsectx_allocate_output(context, 1);
2305 
2306                 if (!str_dst) return 0;
2307 
2308                 *str_dst = decoded;
2309 
2310                 continue;
2311             }
2312 #line 2313 "input_custom_mjson.c"
2313 yy116:
2314             YYSKIP();
2315             yych = YYPEEK();
2316             switch (yych) {
2317             case '0':
2318             case '1':
2319             case '2':
2320             case '3':
2321             case '4':
2322             case '5':
2323             case '6':
2324             case '7':
2325             case '8':
2326             case '9':
2327             case 'A':
2328             case 'B':
2329             case 'C':
2330             case 'D':
2331             case 'E':
2332             case 'F':
2333             case 'a':
2334             case 'b':
2335             case 'c':
2336             case 'd':
2337             case 'e':
2338             case 'f':    goto yy118;
2339             default:    goto yy117;
2340             }
2341 yy117:
2342             YYRESTORE();
2343             goto yy107;
2344 yy118:
2345             YYSKIP();
2346             yych = YYPEEK();
2347             switch (yych) {
2348             case '0':
2349             case '1':
2350             case '2':
2351             case '3':
2352             case '4':
2353             case '5':
2354             case '6':
2355             case '7':
2356             case '8':
2357             case '9':
2358             case 'A':
2359             case 'B':
2360             case 'C':
2361             case 'D':
2362             case 'E':
2363             case 'F':
2364             case 'a':
2365             case 'b':
2366             case 'c':
2367             case 'd':
2368             case 'e':
2369             case 'f':    goto yy119;
2370             default:    goto yy117;
2371             }
2372 yy119:
2373             YYSKIP();
2374             yych = YYPEEK();
2375             switch (yych) {
2376             case '0':
2377             case '1':
2378             case '2':
2379             case '3':
2380             case '4':
2381             case '5':
2382             case '6':
2383             case '7':
2384             case '8':
2385             case '9':
2386             case 'A':
2387             case 'B':
2388             case 'C':
2389             case 'D':
2390             case 'E':
2391             case 'F':
2392             case 'a':
2393             case 'b':
2394             case 'c':
2395             case 'd':
2396             case 'e':
2397             case 'f':    goto yy120;
2398             default:    goto yy117;
2399             }
2400 yy120:
2401             YYSKIP();
2402             yych = YYPEEK();
2403             switch (yych) {
2404             case '0':
2405             case '1':
2406             case '2':
2407             case '3':
2408             case '4':
2409             case '5':
2410             case '6':
2411             case '7':
2412             case '8':
2413             case '9':
2414             case 'A':
2415             case 'B':
2416             case 'C':
2417             case 'D':
2418             case 'E':
2419             case 'F':
2420             case 'a':
2421             case 'b':
2422             case 'c':
2423             case 'd':
2424             case 'e':
2425             case 'f':    goto yy121;
2426             default:    goto yy117;
2427             }
2428 yy121:
2429             YYSKIP();
2430 #line 788 "input_custom_mjson.re"
2431             {
2432                 str_dst = (uint8_t*)parsectx_reserve_output(context, 6);
2433 
2434                 if (!str_dst) return 0;
2435 
2436                 num_parsed = sscanf((char*)(s + 2), "%4x", &ch);
2437                 assert(num_parsed == 1);
2438                 unicode_cp_to_utf8(ch, str_dst, &len);
2439 
2440                 parsectx_advance_output(context, len);
2441 
2442                 continue;
2443             }
2444 #line 2445 "input_custom_mjson.c"
2445         }
2446 #line 814 "input_custom_mjson.re"
2447 
2448     }
2449 
2450 #undef YYREADINPUT
2451 #undef YYCTYPE
2452 #undef YYCURSOR
2453 #undef YYMARKER
2454 
2455     assert(!"reachable");
2456     return 0;
2457 }
2458 
parse_simple(mjson_parser_t * context)2459 static int parse_simple(mjson_parser_t *context)
2460 {
2461     uint32_t* id;
2462 
2463     assert(
2464         context->token == TOK_NULL  ||
2465         context->token == TOK_FALSE ||
2466         context->token == TOK_TRUE
2467     );
2468 
2469     id = (uint32_t*)parsectx_allocate_output(context, sizeof(uint32_t));
2470     if (!id) return 0;
2471 
2472     switch (context->token)
2473     {
2474         case TOK_NULL:
2475             *id = MJSON_ID_NULL;
2476             break;
2477         case TOK_FALSE:
2478             *id = MJSON_ID_FALSE;
2479             break;
2480         case TOK_TRUE:
2481             *id = MJSON_ID_TRUE;
2482             break;
2483     }
2484 
2485     parsectx_next_token(context);
2486     return 1;
2487 }
2488 
parse_value(mjson_parser_t * context)2489 static int parse_value(mjson_parser_t *context)
2490 {
2491     assert(context);
2492 
2493     switch (context->token)
2494     {
2495         case TOK_NULL:
2496         case TOK_FALSE:
2497         case TOK_TRUE:
2498             return parse_simple(context);
2499 
2500         case TOK_OCT_NUMBER:
2501         case TOK_HEX_NUMBER:
2502         case TOK_DEC_NUMBER:
2503         case TOK_FLOAT_NUMBER:
2504             return parse_number(context);
2505 
2506         case TOK_NOESC_STRING:
2507         case TOK_STRING:
2508             return parse_string(context, MJSON_ID_UTF8_STRING32);
2509 
2510         case TOK_LEFT_CURLY_BRACKET:
2511             parsectx_next_token(context);
2512             return parse_key_value_pair(context, TOK_RIGHT_CURLY_BRACKET);
2513 
2514         case TOK_LEFT_BRACKET:
2515             parsectx_next_token(context);
2516             return parse_value_list(context);
2517     }
2518 
2519     return 0;
2520 }
2521 
parse_value_list(mjson_parser_t * context)2522 static int parse_value_list(mjson_parser_t *context)
2523 {
2524     mjson_entry_t* array;
2525     uint8_t*       data_start;
2526     int            expect_separator;
2527 
2528     assert(context);
2529 
2530     array = (mjson_entry_t*)parsectx_allocate_output(context, sizeof(mjson_entry_t));
2531 
2532     if (!array) return 0;
2533 
2534     array->id  = MJSON_ID_ARRAY32;
2535     data_start = context->bjson;
2536 
2537     expect_separator = FALSE;
2538 
2539     while (context->token != TOK_RIGHT_BRACKET)
2540     {
2541         if (expect_separator && context->token == TOK_COMMA)
2542             parsectx_next_token(context);
2543         else
2544             expect_separator = TRUE;
2545 
2546         if (!parse_value(context))
2547             return 0;
2548     }
2549 
2550     array->val_u32 = context->bjson - data_start;
2551 
2552     assert((array->val_u32 & 3) == 0);
2553 
2554     parsectx_next_token(context);
2555 
2556     return 1;
2557 }
2558 
parse_key_value_pair(mjson_parser_t * context,int stop_token)2559 static int parse_key_value_pair(mjson_parser_t* context, int stop_token)
2560 {
2561     mjson_entry_t* dictionary;
2562     uint8_t*       data_start;
2563     int            expect_separator;
2564 
2565     assert(context);
2566 
2567     dictionary = (mjson_entry_t*)parsectx_allocate_output(context, sizeof(mjson_entry_t));
2568 
2569     if (!dictionary) return 0;
2570 
2571     dictionary->id = MJSON_ID_DICT32;
2572     data_start     = context->bjson;
2573 
2574     expect_separator = FALSE;
2575     while (context->token != stop_token)
2576     {
2577         if (expect_separator && context->token == TOK_COMMA)
2578             parsectx_next_token(context);
2579         else
2580             expect_separator = TRUE;
2581 
2582         switch (context->token)
2583         {
2584             case TOK_IDENTIFIER:
2585             case TOK_NOESC_STRING:
2586                 if (!parse_string(context, MJSON_ID_UTF8_KEY32))
2587                     return 0;
2588                 break;
2589             default:
2590                 return 0;
2591         }
2592 
2593         if (context->token != TOK_COLON && context->token != TOK_EQUAL)
2594             return 0;
2595 
2596         parsectx_next_token(context);
2597 
2598         if (!parse_value(context))
2599             return 0;
2600     }
2601 
2602     dictionary->val_u32 = context->bjson - data_start;
2603 
2604     assert((dictionary->val_u32 & 3) == 0);
2605 
2606     parsectx_next_token(context);
2607 
2608     return 1;
2609 }
2610 input_custom_mjson.re:491:26: warning: escape has no effect: '\/' [-Wuseless-escape]
2611 input_custom_mjson.re:491:50: warning: escape has no effect: '\/' [-Wuseless-escape]
2612 input_custom_mjson.re:491:77: warning: escape has no effect: '\/' [-Wuseless-escape]
2613