355 { try {
356
357 size_t i = 0, n = token.length();
358 if( n == 0 )
359 FC_THROW_EXCEPTION( parse_error_exception,
"expected: non-empty token, got: empty token" );
360 switch( token[0] )
361 {
362 case '+':
363 if( strict )
365 i++;
366 break;
367 case '-':
368 i++;
369 break;
370 default:
371 break;
372 }
373 char c = token[i++];
374 switch( c )
375 {
376 case '0':
377 if( i >= n )
379 switch( token[i] )
380 {
381 case 'b':
382 case 'B':
383 if( strict )
384 FC_THROW_EXCEPTION( parse_error_exception,
"binary numeric literals not supported in strict mode" );
385 i++;
386 if( i >= n )
388 return maybeParseInt<strict, 2>( token, i+1 );
389 case 'o':
390 case 'O':
391 if( strict )
392 FC_THROW_EXCEPTION( parse_error_exception,
"octal numeric literals not supported in strict mode" );
393 return maybeParseInt<strict, 8>( token, i+1 );
394 case 'x':
395 case 'X':
396 if( strict )
397 FC_THROW_EXCEPTION( parse_error_exception,
"hex numeric literals not supported in strict mode" );
398 return maybeParseInt<strict, 16>( token, i+1 );
399 case '.':
400 case 'e':
401 case 'E':
402 break;
403 default:
404
405 if( strict )
406 FC_THROW_EXCEPTION( parse_error_exception,
"expected '.'|'e'|'E' parsing number, got '${c}'",
407 ( "c", c ) );
408 }
409 break;
410 case '1': case '2': case '3': case '4':
411 case '5': case '6': case '7': case '8': case '9':
412 break;
413 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
414 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
415 case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
416 case 'y': case 'z':
417 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
418 case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
419 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
420 case 'Y': case 'Z':
421 case '_': case '-': case '.': case '+': case '/':
422 if( strict )
423 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' parsing number", (
"c", c ) );
425 default:
426 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c ) );
427 }
429
430 bool dot_ok = true;
431
432
433 while(true)
434 {
435 if( i >= n )
436 return parseInt<10>( token, start );
437 char c = token[i++];
438
439 switch( c )
440 {
441 case '0': case '1': case '2': case '3': case '4':
442 case '5': case '6': case '7': case '8': case '9':
443 break;
444 case '.':
446 if( dot_ok )
447 {
448 dot_ok = false;
449 if( i == n )
450 {
451 if( strict )
452 FC_THROW_EXCEPTION( parse_error_exception,
"number cannot end with '.' in strict mode" );
454 }
455
456
457 c = token[i+1];
458
459 switch( c )
460 {
461 case '0': case '1': case '2': case '3': case '4':
462 case '5': case '6': case '7': case '8': case '9':
463 break;
464 case 'e':
465 case 'E':
466 if( strict )
468 break;
469 case 'a': case 'b': case 'c': case 'd': case 'f': case 'g': case 'h':
470 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
471 case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
472 case 'y': case 'z':
473 case 'A': case 'B': case 'C': case 'D': case 'F': case 'G': case 'H':
474 case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
475 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
476 case 'Y': case 'Z':
477 case '_': case '-': case '.': case '+': case '/':
478 if( strict )
481 default:
482 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c )(
"i",
int(c)) );
483 }
484 }
485 else
486 {
487 if( strict )
490 }
491 break;
492 case 'e':
493 case 'E':
494 if( i == n )
495 {
496 if( strict )
497 FC_THROW_EXCEPTION( parse_error_exception,
"expected exponent after 'e'|'E' parsing number" );
499 }
500 c = token[i++];
501 switch( c )
502 {
503 case '+': case '-':
504 if( i == n )
505 {
506 if( strict )
509 }
510 break;
511 case '0': case '1': case '2': case '3': case '4':
512 case '5': case '6': case '7': case '8': case '9':
513 break;
514 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
515 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
516 case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
517 case 'y': case 'z':
518 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
519 case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
520 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
521 case 'Y': case 'Z':
522 case '_': case '.': case '/':
523 if( strict )
524 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
526 default:
527 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c ) );
528 }
529 while( true )
530 {
531 if( i == n )
532 break;
533 c = token[i++];
534 switch( c )
535 {
536 case '0': case '1': case '2': case '3': case '4':
537 case '5': case '6': case '7': case '8': case '9':
538 break;
539 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
540 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
541 case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
542 case 'y': case 'z':
543 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
544 case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
545 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
546 case 'Y': case 'Z':
547 case '_': case '-': case '.': case '+': case '/':
548 if( strict )
549 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
551 }
552 }
554 case 'a': case 'b': case 'c': case 'd': case 'f': case 'g': case 'h':
555 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
556 case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
557 case 'y': case 'z':
558 case 'A': case 'B': case 'C': case 'D': case 'F': case 'G': case 'H':
559 case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
560 case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
561 case 'Y': case 'Z':
562 case '_': case '-': case '+': case '/':
563 if( strict )
564 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' parsing number", (
"c", c ) );
566 default:
567 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
568 }
569 }
double to_double(const fc::string &)