예제 #1
0
        private Ast.INode ParseInt(SeekableStringReader sr)
        {
            // int =  ['-'] digitnonzero {digit} .
            string numberstr = sr.ReadWhile(IntegerChars);

            if (numberstr.Length == 0)
            {
                throw new ParseException("invalid int character");
            }
            try {
                try {
                    return(new Ast.IntegerNode(int.Parse(numberstr)));
                } catch (OverflowException) {
                    // try long
                    try {
                        return(new Ast.LongNode(long.Parse(numberstr)));
                    } catch (OverflowException) {
                        // try decimal, but it can still overflow because it's not arbitrary precision
                        try {
                            return(new Ast.DecimalNode(decimal.Parse(numberstr)));
                        } catch (OverflowException) {
                            throw new ParseException("number too large");
                        }
                    }
                }
            } catch (FormatException x) {
                throw new ParseException("invalid integer format", x);
            }
        }
예제 #2
0
        private Ast.PrimitiveNode <double> ParseFloat(SeekableStringReader sr)
        {
            string numberstr = sr.ReadWhile(FloatChars);

            if (numberstr.Length == 0)
            {
                throw new ParseException("invalid float character");
            }

            // little bit of a hack:
            // if the number doesn't contain a decimal point and no 'e'/'E', it is an integer instead.
            // in that case, we need to reject it as a float.
            if (numberstr.IndexOfAny(new [] { '.', 'e', 'E' }) < 0)
            {
                throw new ParseException("number is not a float (might be an integer though)");
            }

            try {
                return(new Ast.DoubleNode(ParseDouble(numberstr)));
            } catch (FormatException x) {
                throw new ParseException("invalid float format", x);
            }
        }
예제 #3
0
파일: Parser.cs 프로젝트: achernet/Serpent
        Ast.PrimitiveNode <double> ParseFloat(SeekableStringReader sr)
        {
            string numberstr = sr.ReadWhile('-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

            if (numberstr.Length == 0)
            {
                throw new ParseException("invalid float character");
            }

            // little bit of a hack:
            // if the number doesn't contain a decimal point and no 'e'/'E', it is an integer instead.
            // in that case, we need to reject it as a float.
            if (numberstr.IndexOfAny(new char[] { '.', 'e', 'E' }) < 0)
            {
                throw new ParseException("number is not a valid float");
            }

            try {
                return(new Ast.DoubleNode(double.Parse(numberstr, CultureInfo.InvariantCulture)));
            } catch (FormatException x) {
                throw new ParseException("invalid float format", x);
            }
        }
예제 #4
0
        private Ast.ComplexNumberNode ParseComplex(SeekableStringReader sr)
        {
            //complex         = complextuple | imaginary .
            //imaginary       = ['+' | '-' ] ( float | int ) 'j' .
            //complextuple    = '(' ( float | int ) imaginary ')' .
            if (sr.Peek() == '(')
            {
                // complextuple
                sr.Read();                  // (
                string numberstr;
                if (sr.Peek() == '-' || sr.Peek() == '+')
                {
                    // starts with a sign, read that first otherwise the readuntil will return immediately
                    numberstr = sr.Read(1) + sr.ReadUntil('+', '-');
                }
                else
                {
                    numberstr = sr.ReadUntil('+', '-');
                }
                sr.Rewind(1);                 // rewind the +/-

                // because we're a bit more cautious here with reading chars than in the float parser,
                // it can be that the parser now stopped directly after the 'e' in a number like "3.14e+20".
                // ("3.14e20" is fine) So, check if the last char is 'e' and if so, continue reading 0..9.
                if (numberstr.EndsWith("e", StringComparison.InvariantCultureIgnoreCase))
                {
                    // if the next symbol is + or -, accept it, then read the exponent integer
                    if (sr.Peek() == '-' || sr.Peek() == '+')
                    {
                        numberstr += sr.Read(1);
                    }
                    numberstr += sr.ReadWhile("0123456789");
                }

                sr.SkipWhitespace();
                double realpart;
                try {
                    realpart = ParseDouble(numberstr);
                } catch (FormatException x) {
                    throw new ParseException("invalid float format", x);
                }
                double imaginarypart = ParseImaginaryPart(sr);
                if (sr.Read() != ')')
                {
                    throw new ParseException("expected ) to end a complex number");
                }
                return(new Ast.ComplexNumberNode
                {
                    Real = realpart,
                    Imaginary = imaginarypart
                });
            }

            // imaginary
            double imag = ParseImaginaryPart(sr);

            return(new Ast.ComplexNumberNode
            {
                Real = 0,
                Imaginary = imag
            });
        }