Exemplo n.º 1
0
        private static bool ParseNumberLiteralDoubleFloat(string text, ref string error, NumberLiteralSuffix type,
                                                          out object numberLiteral)
        {
            numberLiteral = null;
            if (text.Contains(".") || text.Contains("e") || type == NumberLiteralSuffix.Float ||
                type == NumberLiteralSuffix.Double)
            {
                const NumberStyles decimalStyle = NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint;
                // real number
                switch (type)
                {
                case NumberLiteralSuffix.None:     // double is defualt
                case NumberLiteralSuffix.Double:
                {
                    numberLiteral = TryParse <double>(double.TryParse, text, out error, decimalStyle);
                    return(true);
                }

                case NumberLiteralSuffix.Float:
                {
                    numberLiteral = TryParse <float>(float.TryParse, text, out error, decimalStyle);
                    return(true);
                }

                case NumberLiteralSuffix.Decimal:
                {
                    numberLiteral = TryParse <decimal>(decimal.TryParse, text, out error, decimalStyle);
                    return(true);
                }

                default:
                    error = $"could not parse real number of type {type}";
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 2
0
        private static bool ParseNumberLiteralSuffix(ref string text, ref string error, char lastDigit, ref NumberLiteralSuffix type)
        {
            if (char.IsLetter(lastDigit))
            {
                // number type suffix
                if (lastDigit == 'm')
                {
                    type = NumberLiteralSuffix.Decimal;
                }
                else if (lastDigit == 'f')
                {
                    type = NumberLiteralSuffix.Float;
                }
                else if (lastDigit == 'd')
                {
                    type = NumberLiteralSuffix.Double;
                }
                else if (text.EndsWith("ul", StringComparison.Ordinal) || text.EndsWith("lu", StringComparison.Ordinal))
                {
                    type = NumberLiteralSuffix.UnsignedLong;
                }
                else if (lastDigit == 'u')
                {
                    type = NumberLiteralSuffix.Unsigned;
                }
                else if (lastDigit == 'l')
                {
                    type = NumberLiteralSuffix.Long;
                }
                else
                {
                    error = "number literal type suffix not known";
                    return(true);
                }

                if (type == NumberLiteralSuffix.UnsignedLong)
                {
                    text = text.Remove(text.Length - 2);                                           // remove 2 last chars
                }
                else
                {
                    text = text.Remove(text.Length - 1);  // remove last char
                }
            }
            return(false);
        }
Exemplo n.º 3
0
        private static object ParseNumberLiteral(string text, out string error)
        {
            text  = text.ToLower();
            error = null;
            NumberLiteralSuffix type = NumberLiteralSuffix.None;
            var lastDigit            = text[text.Length - 1];

            if (ParseNumberLiteralSuffix(ref text, ref error, lastDigit, ref type))
            {
                return(null);
            }

            object numberLiteral;

            if (ParseNumberLiteralDoubleFloat(text, ref error, type, out numberLiteral))
            {
                return(numberLiteral);
            }

            const NumberStyles integerStyle = NumberStyles.AllowLeadingSign;
            // try parse integral constant
            object result = null;

            if (type == NumberLiteralSuffix.None)
            {
                result = TryParse <int>(int.TryParse, text, integerStyle) ??
                         TryParse <uint>(uint.TryParse, text, integerStyle) ??
                         TryParse <long>(long.TryParse, text, integerStyle) ??
                         TryParse <ulong>(ulong.TryParse, text, integerStyle);
            }
            else if (type == NumberLiteralSuffix.Unsigned)
            {
                result = TryParse <uint>(uint.TryParse, text, integerStyle) ??
                         TryParse <ulong>(ulong.TryParse, text, integerStyle);
            }
            else if (type == NumberLiteralSuffix.Long)
            {
                result = TryParse <long>(long.TryParse, text, integerStyle) ??
                         TryParse <ulong>(ulong.TryParse, text, integerStyle);
            }
            else if (type == NumberLiteralSuffix.UnsignedLong)
            {
                result = TryParse <ulong>(ulong.TryParse, text, integerStyle);
            }
            if (result != null)
            {
                return(result);
            }
            // handle errors

            // if all are digits, or '0x' + hex digits => too large number
            if (text.All(char.IsDigit) ||
                (text.StartsWith("0x", StringComparison.Ordinal) && text.Skip(2).All(c => char.IsDigit(c) || (c >= 'a' && c <= 'f'))))
            {
                error = $"number number {text} is too large for integral literal, try to append 'd' to real number literal";
            }
            else
            {
                error = $"could not parse {text} as numeric literal";
            }
            return(null);
        }