예제 #1
0
        /*
         * number = [ minus ] int [ frac ] [ exp ]
         * decimal-point = %x2E       ; .
         * digit1-9 = %x31-39         ; 1-9
         * e = %x65 / %x45            ; e E
         * exp = e [ minus / plus ] 1*DIGIT
         * frac = decimal-point 1*DIGIT
         * int = zero / ( digit1-9 *DIGIT )
         * minus = %x2D               ; -
         * plus = %x2B                ; +
         * zero = %x30                ; 0
         */

        private object ParseNumber(ITypeBuilderRegistry registry, ITypeBuilder builder)
        {
            var startLine = Line;
            var startColumn = Column;
            var sb = new StringBuilder();
            if (Peek() == '-')
            {
                sb.Append(Next());
            }
            var hasInteger = false;
            while (char.IsDigit((char) Peek()))
            {
                sb.Append(Next());
                hasInteger = true;
            }
            if (!hasInteger)
            {
                throw CreateExpectedNumberException(startLine, startColumn);
            }

            if (Peek() != '.')
            {
                long intValue;
                if (!long.TryParse(sb.ToString(), out intValue))
                {
                    throw CreateExpectedNumberException(startLine, startColumn);
                }
                return builder.CreateNumber(registry, intValue);
            }

            sb.Append(Next());
            var hasFrac = false;
            while (char.IsDigit((char) Peek()))
            {
                sb.Append(Next());
                hasFrac = true;
            }
            if (!hasFrac)
            {
                throw CreateExpectedNumberException(startLine, startColumn);
            }

            if ("eE".IndexOf((char) Peek()) >= 0)
            {
                sb.Append(Next());

                if ("+-".IndexOf((char) Peek()) >= 0)
                {
                    sb.Append(Next());
                }
                var hasExp = false;
                while (char.IsDigit((char) Peek()))
                {
                    sb.Append(Next());
                    hasExp = true;
                }
                if (!hasExp)
                {
                    throw CreateExpectedNumberException(startLine, startColumn);
                }
            }
            double doubleValue;

            if (!double.TryParse(sb.ToString(),
                                 NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint |
                                 NumberStyles.AllowExponent,
                                 JsonFormats.DoubleFormat, out doubleValue))
            {
                throw CreateExpectedNumberException(startLine, startColumn);
            }
            return builder.CreateNumber(registry, doubleValue);
        }