json lib

Dependents:   grove_stream_jpa_sd2 grove_stream_jpa_sd2 grove_stream_jpa_sd2-2 grove_stream_jpa_sd2-3 ... more

Committer:
mercurywaters
Date:
Thu Jun 02 06:08:24 2016 +0000
Revision:
3:fab591fca1e7
Parent:
0:7f4a18b3fd82
Child:
5:dd98cf00ed9b
Added the documentation of JSON class

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mercurywaters 0:7f4a18b3fd82 1 #include "jsmn.h"
mercurywaters 0:7f4a18b3fd82 2
mercurywaters 0:7f4a18b3fd82 3 /**
mercurywaters 0:7f4a18b3fd82 4 * Allocates a fresh unused token from the token pull.
mercurywaters 0:7f4a18b3fd82 5 */
mercurywaters 3:fab591fca1e7 6 static jsmntok_t *jsmn_alloc_token ( jsmn_parser *parser, jsmntok_t *tokens, size_t num_tokens )
mercurywaters 0:7f4a18b3fd82 7 {
mercurywaters 0:7f4a18b3fd82 8 jsmntok_t *tok;
mercurywaters 3:fab591fca1e7 9 if ( parser->toknext >= num_tokens )
mercurywaters 3:fab591fca1e7 10 {
mercurywaters 3:fab591fca1e7 11 return NULL ;
mercurywaters 0:7f4a18b3fd82 12 }
mercurywaters 3:fab591fca1e7 13 tok = &tokens [ parser->toknext++ ];
mercurywaters 0:7f4a18b3fd82 14 tok->start = tok->end = -1;
mercurywaters 0:7f4a18b3fd82 15 tok->childCount = 0;
mercurywaters 0:7f4a18b3fd82 16 tok->parent = -1;
mercurywaters 0:7f4a18b3fd82 17 return tok;
mercurywaters 0:7f4a18b3fd82 18 }
mercurywaters 0:7f4a18b3fd82 19
mercurywaters 0:7f4a18b3fd82 20 /**
mercurywaters 0:7f4a18b3fd82 21 * Fills token type and boundaries.
mercurywaters 0:7f4a18b3fd82 22 */
mercurywaters 3:fab591fca1e7 23 static void jsmn_fill_token ( jsmntok_t *token, jsmntype_t type, int start, int end )
mercurywaters 0:7f4a18b3fd82 24 {
mercurywaters 0:7f4a18b3fd82 25 token->type = type;
mercurywaters 0:7f4a18b3fd82 26 token->start = start;
mercurywaters 0:7f4a18b3fd82 27 token->end = end;
mercurywaters 0:7f4a18b3fd82 28 token->childCount = 0;
mercurywaters 0:7f4a18b3fd82 29 }
mercurywaters 0:7f4a18b3fd82 30
mercurywaters 0:7f4a18b3fd82 31 /**
mercurywaters 0:7f4a18b3fd82 32 * Fills next available token with JSON primitive.
mercurywaters 0:7f4a18b3fd82 33 */
mercurywaters 3:fab591fca1e7 34 static int jsmn_parse_primitive ( jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens )
mercurywaters 0:7f4a18b3fd82 35 {
mercurywaters 0:7f4a18b3fd82 36 jsmntok_t *token;
mercurywaters 0:7f4a18b3fd82 37 int start;
mercurywaters 3:fab591fca1e7 38
mercurywaters 0:7f4a18b3fd82 39 start = parser->pos;
mercurywaters 3:fab591fca1e7 40
mercurywaters 3:fab591fca1e7 41 for ( ; parser->pos < len && js [ parser->pos ] != '\0'; parser->pos++ )
mercurywaters 3:fab591fca1e7 42 {
mercurywaters 3:fab591fca1e7 43 switch ( js [ parser->pos ] )
mercurywaters 3:fab591fca1e7 44 {
mercurywaters 3:fab591fca1e7 45 case '\t':
mercurywaters 3:fab591fca1e7 46 case '\r':
mercurywaters 3:fab591fca1e7 47 case '\n':
mercurywaters 3:fab591fca1e7 48 case ' ':
mercurywaters 3:fab591fca1e7 49 case ',':
mercurywaters 3:fab591fca1e7 50 case ']':
mercurywaters 3:fab591fca1e7 51 case '}':
mercurywaters 0:7f4a18b3fd82 52 goto found;
mercurywaters 0:7f4a18b3fd82 53 }
mercurywaters 3:fab591fca1e7 54 if ( js [ parser->pos ] < 32 || js [ parser->pos ] >= 127 )
mercurywaters 3:fab591fca1e7 55 {
mercurywaters 0:7f4a18b3fd82 56 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 57 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 58 }
mercurywaters 0:7f4a18b3fd82 59 }
mercurywaters 0:7f4a18b3fd82 60 /* primitive must be followed by a comma/object/array */
mercurywaters 0:7f4a18b3fd82 61 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 62 return JSMN_ERROR_PART;
mercurywaters 3:fab591fca1e7 63
mercurywaters 3:fab591fca1e7 64 found: if ( tokens == NULL )
mercurywaters 3:fab591fca1e7 65 {
mercurywaters 0:7f4a18b3fd82 66 parser->pos--;
mercurywaters 0:7f4a18b3fd82 67 return 0;
mercurywaters 0:7f4a18b3fd82 68 }
mercurywaters 3:fab591fca1e7 69 token = jsmn_alloc_token ( parser, tokens, num_tokens );
mercurywaters 3:fab591fca1e7 70 if ( token == NULL )
mercurywaters 3:fab591fca1e7 71 {
mercurywaters 0:7f4a18b3fd82 72 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 73 return JSMN_ERROR_NOMEM;
mercurywaters 0:7f4a18b3fd82 74 }
mercurywaters 3:fab591fca1e7 75 jsmn_fill_token ( token, JSMN_PRIMITIVE, start, parser->pos );
mercurywaters 0:7f4a18b3fd82 76 token->parent = parser->toksuper;
mercurywaters 0:7f4a18b3fd82 77 parser->pos--;
mercurywaters 0:7f4a18b3fd82 78 return 0;
mercurywaters 0:7f4a18b3fd82 79 }
mercurywaters 0:7f4a18b3fd82 80
mercurywaters 0:7f4a18b3fd82 81 /**
mercurywaters 0:7f4a18b3fd82 82 * Fills next token with JSON string.
mercurywaters 0:7f4a18b3fd82 83 */
mercurywaters 3:fab591fca1e7 84 static int jsmn_parse_string ( jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, size_t num_tokens, unsigned char isKey )
mercurywaters 0:7f4a18b3fd82 85 {
mercurywaters 0:7f4a18b3fd82 86 jsmntok_t *token;
mercurywaters 3:fab591fca1e7 87
mercurywaters 0:7f4a18b3fd82 88 int start = parser->pos;
mercurywaters 3:fab591fca1e7 89
mercurywaters 0:7f4a18b3fd82 90 parser->pos++;
mercurywaters 3:fab591fca1e7 91
mercurywaters 0:7f4a18b3fd82 92 /* Skip starting quote */
mercurywaters 3:fab591fca1e7 93 for ( ; parser->pos < len && js [ parser->pos ] != '\0'; parser->pos++ )
mercurywaters 3:fab591fca1e7 94 {
mercurywaters 3:fab591fca1e7 95 char c = js [ parser->pos ];
mercurywaters 3:fab591fca1e7 96
mercurywaters 0:7f4a18b3fd82 97 /* Quote: end of string */
mercurywaters 3:fab591fca1e7 98 if ( c == '\"' )
mercurywaters 3:fab591fca1e7 99 {
mercurywaters 3:fab591fca1e7 100 if ( tokens == NULL )
mercurywaters 3:fab591fca1e7 101 {
mercurywaters 0:7f4a18b3fd82 102 return 0;
mercurywaters 0:7f4a18b3fd82 103 }
mercurywaters 3:fab591fca1e7 104 token = jsmn_alloc_token ( parser, tokens, num_tokens );
mercurywaters 3:fab591fca1e7 105 if ( token == NULL )
mercurywaters 3:fab591fca1e7 106 {
mercurywaters 0:7f4a18b3fd82 107 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 108 return JSMN_ERROR_NOMEM;
mercurywaters 0:7f4a18b3fd82 109 }
mercurywaters 3:fab591fca1e7 110 if ( isKey == 1 )
mercurywaters 3:fab591fca1e7 111 {
mercurywaters 3:fab591fca1e7 112 jsmn_fill_token ( token, JSMN_KEY, start + 1, parser->pos );
mercurywaters 0:7f4a18b3fd82 113 }
mercurywaters 3:fab591fca1e7 114 else
mercurywaters 3:fab591fca1e7 115 {
mercurywaters 3:fab591fca1e7 116 jsmn_fill_token ( token, JSMN_STRING, start + 1, parser->pos );
mercurywaters 0:7f4a18b3fd82 117 }
mercurywaters 0:7f4a18b3fd82 118 token->parent = parser->toksuper;
mercurywaters 0:7f4a18b3fd82 119 return 0;
mercurywaters 0:7f4a18b3fd82 120 }
mercurywaters 3:fab591fca1e7 121
mercurywaters 0:7f4a18b3fd82 122 /* Backslash: Quoted symbol expected */
mercurywaters 3:fab591fca1e7 123 if ( c == '\\' && parser->pos + 1 < len )
mercurywaters 3:fab591fca1e7 124 {
mercurywaters 0:7f4a18b3fd82 125 int i;
mercurywaters 0:7f4a18b3fd82 126 parser->pos++;
mercurywaters 3:fab591fca1e7 127 switch ( js [ parser->pos ] )
mercurywaters 3:fab591fca1e7 128 {
mercurywaters 3:fab591fca1e7 129 /* Allowed escaped symbols */
mercurywaters 0:7f4a18b3fd82 130 case '\"':
mercurywaters 3:fab591fca1e7 131 case '/':
mercurywaters 3:fab591fca1e7 132 case '\\':
mercurywaters 3:fab591fca1e7 133 case 'b':
mercurywaters 3:fab591fca1e7 134 case 'f':
mercurywaters 3:fab591fca1e7 135 case 'r':
mercurywaters 3:fab591fca1e7 136 case 'n':
mercurywaters 3:fab591fca1e7 137 case 't':
mercurywaters 0:7f4a18b3fd82 138 break;
mercurywaters 0:7f4a18b3fd82 139 /* Allows escaped symbol \uXXXX */
mercurywaters 0:7f4a18b3fd82 140 case 'u':
mercurywaters 0:7f4a18b3fd82 141 parser->pos++;
mercurywaters 3:fab591fca1e7 142 for ( i = 0; i < 4 && parser->pos < len && js [ parser->pos ] != '\0'; i++ )
mercurywaters 3:fab591fca1e7 143 {
mercurywaters 0:7f4a18b3fd82 144 /* If it isn't a hex character we have an error */
mercurywaters 3:fab591fca1e7 145 if ( ! ( ( js [ parser->pos ] >= 48 && js [ parser->pos ] <= 57 ) || /* 0-9 */
mercurywaters 3:fab591fca1e7 146 ( js [ parser->pos ] >= 65 && js [ parser->pos ] <= 70 )
mercurywaters 3:fab591fca1e7 147 || /* A-F */
mercurywaters 3:fab591fca1e7 148 ( js [ parser->pos ] >= 97 && js [ parser->pos ] <= 102 ) ) )
mercurywaters 3:fab591fca1e7 149 { /* a-f */
mercurywaters 0:7f4a18b3fd82 150 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 151 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 152 }
mercurywaters 0:7f4a18b3fd82 153 parser->pos++;
mercurywaters 0:7f4a18b3fd82 154 }
mercurywaters 0:7f4a18b3fd82 155 parser->pos--;
mercurywaters 0:7f4a18b3fd82 156 break;
mercurywaters 0:7f4a18b3fd82 157 /* Unexpected symbol */
mercurywaters 0:7f4a18b3fd82 158 default:
mercurywaters 0:7f4a18b3fd82 159 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 160 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 161 }
mercurywaters 0:7f4a18b3fd82 162 }
mercurywaters 0:7f4a18b3fd82 163 }
mercurywaters 0:7f4a18b3fd82 164 parser->pos = start;
mercurywaters 0:7f4a18b3fd82 165 return JSMN_ERROR_PART;
mercurywaters 0:7f4a18b3fd82 166 }
mercurywaters 0:7f4a18b3fd82 167
mercurywaters 0:7f4a18b3fd82 168 /**
mercurywaters 0:7f4a18b3fd82 169 * Parse JSON string and fill tokens.
mercurywaters 0:7f4a18b3fd82 170 */
mercurywaters 3:fab591fca1e7 171 int jsmn_parse ( jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, unsigned int num_tokens )
mercurywaters 0:7f4a18b3fd82 172 {
mercurywaters 0:7f4a18b3fd82 173 int r;
mercurywaters 0:7f4a18b3fd82 174 int i;
mercurywaters 0:7f4a18b3fd82 175 jsmntok_t *token;
mercurywaters 0:7f4a18b3fd82 176 int count = parser->toknext;
mercurywaters 3:fab591fca1e7 177
mercurywaters 0:7f4a18b3fd82 178 unsigned char isKey = 1;
mercurywaters 3:fab591fca1e7 179
mercurywaters 3:fab591fca1e7 180 for ( ; parser->pos < len && js [ parser->pos ] != '\0'; parser->pos++ )
mercurywaters 3:fab591fca1e7 181 {
mercurywaters 0:7f4a18b3fd82 182 char c;
mercurywaters 0:7f4a18b3fd82 183 jsmntype_t type;
mercurywaters 3:fab591fca1e7 184
mercurywaters 3:fab591fca1e7 185 c = js [ parser->pos ];
mercurywaters 3:fab591fca1e7 186 switch ( c )
mercurywaters 3:fab591fca1e7 187 {
mercurywaters 0:7f4a18b3fd82 188 case '{':
mercurywaters 0:7f4a18b3fd82 189 case '[':
mercurywaters 0:7f4a18b3fd82 190 count++;
mercurywaters 3:fab591fca1e7 191 if ( tokens == NULL )
mercurywaters 3:fab591fca1e7 192 {
mercurywaters 0:7f4a18b3fd82 193 break;
mercurywaters 0:7f4a18b3fd82 194 }
mercurywaters 3:fab591fca1e7 195 token = jsmn_alloc_token ( parser, tokens, num_tokens );
mercurywaters 3:fab591fca1e7 196 if ( token == NULL )
mercurywaters 0:7f4a18b3fd82 197 return JSMN_ERROR_NOMEM;
mercurywaters 3:fab591fca1e7 198 if ( parser->toksuper != -1 )
mercurywaters 3:fab591fca1e7 199 {
mercurywaters 3:fab591fca1e7 200 tokens [ parser->toksuper ].childCount++;
mercurywaters 0:7f4a18b3fd82 201 token->parent = parser->toksuper;
mercurywaters 0:7f4a18b3fd82 202 }
mercurywaters 3:fab591fca1e7 203 token->type = ( c == '{' ? JSMN_OBJECT : JSMN_ARRAY );
mercurywaters 0:7f4a18b3fd82 204 token->start = parser->pos;
mercurywaters 0:7f4a18b3fd82 205 parser->toksuper = parser->toknext - 1;
mercurywaters 3:fab591fca1e7 206 if ( token->type == JSMN_OBJECT )
mercurywaters 3:fab591fca1e7 207 {
mercurywaters 0:7f4a18b3fd82 208 isKey = 1;
mercurywaters 0:7f4a18b3fd82 209 }
mercurywaters 0:7f4a18b3fd82 210 break;
mercurywaters 0:7f4a18b3fd82 211 case '}':
mercurywaters 0:7f4a18b3fd82 212 case ']':
mercurywaters 3:fab591fca1e7 213 if ( tokens == NULL )
mercurywaters 0:7f4a18b3fd82 214 break;
mercurywaters 3:fab591fca1e7 215 type = ( c == '}' ? JSMN_OBJECT : JSMN_ARRAY );
mercurywaters 3:fab591fca1e7 216 if ( parser->toknext < 1 )
mercurywaters 3:fab591fca1e7 217 {
mercurywaters 0:7f4a18b3fd82 218 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 219 }
mercurywaters 3:fab591fca1e7 220 token = &tokens [ parser->toknext - 1 ];
mercurywaters 3:fab591fca1e7 221 for ( ;; )
mercurywaters 3:fab591fca1e7 222 {
mercurywaters 3:fab591fca1e7 223 if ( token->start != -1 && token->end == -1 )
mercurywaters 3:fab591fca1e7 224 {
mercurywaters 3:fab591fca1e7 225 if ( token->type != type )
mercurywaters 3:fab591fca1e7 226 {
mercurywaters 0:7f4a18b3fd82 227 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 228 }
mercurywaters 0:7f4a18b3fd82 229 token->end = parser->pos + 1;
mercurywaters 0:7f4a18b3fd82 230 parser->toksuper = token->parent;
mercurywaters 0:7f4a18b3fd82 231 break;
mercurywaters 0:7f4a18b3fd82 232 }
mercurywaters 3:fab591fca1e7 233 if ( token->parent == -1 )
mercurywaters 3:fab591fca1e7 234 {
mercurywaters 0:7f4a18b3fd82 235 break;
mercurywaters 0:7f4a18b3fd82 236 }
mercurywaters 3:fab591fca1e7 237 token = &tokens [ token->parent ];
mercurywaters 0:7f4a18b3fd82 238 }
mercurywaters 0:7f4a18b3fd82 239 break;
mercurywaters 0:7f4a18b3fd82 240 case '\"':
mercurywaters 3:fab591fca1e7 241 r = jsmn_parse_string ( parser, js, len, tokens, num_tokens, isKey );
mercurywaters 3:fab591fca1e7 242 if ( r < 0 )
mercurywaters 3:fab591fca1e7 243 return r;
mercurywaters 0:7f4a18b3fd82 244 count++;
mercurywaters 3:fab591fca1e7 245 if ( parser->toksuper != -1 && tokens != NULL )
mercurywaters 3:fab591fca1e7 246 tokens [ parser->toksuper ].childCount++;
mercurywaters 0:7f4a18b3fd82 247 break;
mercurywaters 3:fab591fca1e7 248 case '\t':
mercurywaters 3:fab591fca1e7 249 case '\r':
mercurywaters 3:fab591fca1e7 250 case '\n':
mercurywaters 0:7f4a18b3fd82 251 case ' ':
mercurywaters 0:7f4a18b3fd82 252 break;
mercurywaters 0:7f4a18b3fd82 253 case ':':
mercurywaters 0:7f4a18b3fd82 254 isKey = 0;
mercurywaters 0:7f4a18b3fd82 255 parser->toksuper = parser->toknext - 1;
mercurywaters 0:7f4a18b3fd82 256 break;
mercurywaters 0:7f4a18b3fd82 257 case ',':
mercurywaters 3:fab591fca1e7 258 if ( tokens != NULL && parser->toksuper != -1 && tokens [ parser->toksuper ].type != JSMN_ARRAY && tokens [ parser->toksuper ].type != JSMN_OBJECT )
mercurywaters 3:fab591fca1e7 259 {
mercurywaters 3:fab591fca1e7 260 parser->toksuper = tokens [ parser->toksuper ].parent;
mercurywaters 0:7f4a18b3fd82 261 }
mercurywaters 0:7f4a18b3fd82 262 isKey = 1;
mercurywaters 0:7f4a18b3fd82 263 break;
mercurywaters 0:7f4a18b3fd82 264 /* In strict mode primitives are: numbers and booleans */
mercurywaters 0:7f4a18b3fd82 265 case '-':
mercurywaters 0:7f4a18b3fd82 266 case '0':
mercurywaters 3:fab591fca1e7 267 case '1':
mercurywaters 0:7f4a18b3fd82 268 case '2':
mercurywaters 3:fab591fca1e7 269 case '3':
mercurywaters 0:7f4a18b3fd82 270 case '4':
mercurywaters 0:7f4a18b3fd82 271 case '5':
mercurywaters 0:7f4a18b3fd82 272 case '6':
mercurywaters 3:fab591fca1e7 273 case '7':
mercurywaters 0:7f4a18b3fd82 274 case '8':
mercurywaters 0:7f4a18b3fd82 275 case '9':
mercurywaters 0:7f4a18b3fd82 276 case 't':
mercurywaters 0:7f4a18b3fd82 277 case 'f':
mercurywaters 3:fab591fca1e7 278 case 'n':
mercurywaters 0:7f4a18b3fd82 279 /* And they must not be keys of the object */
mercurywaters 3:fab591fca1e7 280 if ( tokens != NULL && parser->toksuper != -1 )
mercurywaters 3:fab591fca1e7 281 {
mercurywaters 3:fab591fca1e7 282 jsmntok_t *t = &tokens [ parser->toksuper ];
mercurywaters 3:fab591fca1e7 283 if ( t->type == JSMN_OBJECT || ( t->type == JSMN_STRING && t->childCount != 0 ) )
mercurywaters 3:fab591fca1e7 284 {
mercurywaters 0:7f4a18b3fd82 285 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 286 }
mercurywaters 0:7f4a18b3fd82 287 }
mercurywaters 3:fab591fca1e7 288 r = jsmn_parse_primitive ( parser, js, len, tokens, num_tokens );
mercurywaters 3:fab591fca1e7 289 if ( r < 0 )
mercurywaters 3:fab591fca1e7 290 return r;
mercurywaters 0:7f4a18b3fd82 291 count++;
mercurywaters 3:fab591fca1e7 292 if ( parser->toksuper != -1 && tokens != NULL )
mercurywaters 3:fab591fca1e7 293 tokens [ parser->toksuper ].childCount++;
mercurywaters 0:7f4a18b3fd82 294 break;
mercurywaters 3:fab591fca1e7 295
mercurywaters 0:7f4a18b3fd82 296 /* Unexpected char in strict mode */
mercurywaters 0:7f4a18b3fd82 297 default:
mercurywaters 0:7f4a18b3fd82 298 return JSMN_ERROR_INVAL;
mercurywaters 0:7f4a18b3fd82 299 }
mercurywaters 0:7f4a18b3fd82 300 }
mercurywaters 3:fab591fca1e7 301
mercurywaters 3:fab591fca1e7 302 if ( tokens != NULL )
mercurywaters 3:fab591fca1e7 303 {
mercurywaters 3:fab591fca1e7 304 for ( i = parser->toknext - 1; i >= 0; i-- )
mercurywaters 3:fab591fca1e7 305 {
mercurywaters 0:7f4a18b3fd82 306 /* Unmatched opened object or array */
mercurywaters 3:fab591fca1e7 307 if ( tokens [ i ].start != -1 && tokens [ i ].end == -1 )
mercurywaters 3:fab591fca1e7 308 {
mercurywaters 0:7f4a18b3fd82 309 return JSMN_ERROR_PART;
mercurywaters 0:7f4a18b3fd82 310 }
mercurywaters 0:7f4a18b3fd82 311 }
mercurywaters 0:7f4a18b3fd82 312 }
mercurywaters 3:fab591fca1e7 313
mercurywaters 0:7f4a18b3fd82 314 return count;
mercurywaters 0:7f4a18b3fd82 315 }
mercurywaters 0:7f4a18b3fd82 316
mercurywaters 0:7f4a18b3fd82 317 /**
mercurywaters 0:7f4a18b3fd82 318 * Creates a new parser based over a given buffer with an array of tokens
mercurywaters 0:7f4a18b3fd82 319 * available.
mercurywaters 0:7f4a18b3fd82 320 */
mercurywaters 3:fab591fca1e7 321 void jsmn_init ( jsmn_parser *parser )
mercurywaters 0:7f4a18b3fd82 322 {
mercurywaters 0:7f4a18b3fd82 323 parser->pos = 0;
mercurywaters 0:7f4a18b3fd82 324 parser->toknext = 0;
mercurywaters 0:7f4a18b3fd82 325 parser->toksuper = -1;
mercurywaters 0:7f4a18b3fd82 326 }
mercurywaters 3:fab591fca1e7 327