#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

typedef struct 
{
    char* s;
    int len;
} token_t;

int scan_tok(char* in_txt, token_t* out_buf, int* out_tok_len)
{
    unsigned eqcls[256] = {
               0,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535282,1568535282,1568535294,1568535294,1568535282,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535282,1568535294,1568535126,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1566438142,1568535284,1566438140,1568516862,1568535166,
        1563092730,1563125496,1563125496,1563125496,1563125496,1563125496,1563125496,1563125496,
        1563125496,1563125496,1568535284,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535038,1568535038,1568535038,1568535038,1568001534,1568535038,1568535038,
        1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,
        1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,1568535038,
        1568535038,1568535038,1568535038,1568535284,1568535150,1568535284,1568535294,1568535294,
        1568535294,1560146430,1568534910,1568535038,1568535038,762695166,1568534910,1568535038,
        1568535038,1568535038,1568535038,1568535038,1266545150,1568535038,1568534910,1568535038,
        1568535038,1568535038,1560146302,1434317310,1568534910,1526591934,1568535038,1568535038,
        1568535038,1568535038,1568535038,1568535284,1568535294,1568535284,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,
        1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294,1568535294
    };
    unsigned tbl[] = {
           98304,   98304,  475265,  483457,  246281,  509213,  247458,  247718,
          248763,   98304,  483457,  246541,  246281,   98304,  246281,  246801,
          246281,   98304,  246804,  102400,   98304,  246807,  102400,   98304,
          246810,  102400,   98304,  246281,  102400,   98304,  509213,  247978,
          248497,  467073,   98304,  247978,  248497,  467073,   98304,  247458,
          509213,  102400,   98304,  248237,  102400,   98304,  248237,  248497,
          467073,   98304,  247989,  247989,  102400,   98304,  247992,  102400,
           98304,  247992,  467073,   98304,  249022,  102400,   98304,  249281,
          102400,   98304,  483457,  249541,  102400,   98304,  483457,  102400
    };
    char* p = in_txt;
    char* s = p;
    token_t* ptk = out_buf;
    int state = 491649;
    do
    {
        unsigned cls = eqcls[(unsigned char)(*p)];
        cls = (cls >> ((state >> 7) & 31)) & (state >> 16);
        state = tbl[ (state & 127) + cls ];
        p += (state >> 14) & 1;
        ptk->s = s;
        ptk->len = p-s;
        ptk += (state >> 13) & 1;
        s += (p-s) & (UINT_MAX + ((state >> 15) & 1));
    }while( (state & 127) > 0);

    *out_tok_len = ptk - out_buf;

    /* error flag */
    if ( (state>>12) & 1 )
        return 0;

    return 1;
}

int main(void)
{
    char* test1 = "\n { \"this is \\\\ \\\"test json\"  : -0.12345e-5, \"test key1\": [true, false, null, tulse\
     , 0,1,2,8,9, 13, 2345,  30004.0, 300004.2134003, \
    ]\n }";
    token_t buf[512];
    int buf_len = 0;
    int ret = 0;

    memset(buf, 0x00, sizeof(buf));

    ret = scan_tok(test1, buf, &buf_len);

    if(ret == 0)
    {
        printf("token error");
        exit(1);
    }

    for(int i=0; i < buf_len; i++)
    {
        printf("%.*s\n", buf[i].len, buf[i].s);
    }

    return 0;
}