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); } }
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); } }
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); } }
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 }); }