Exemplo n.º 1
0
 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(new char[] { '+', '-' });
         }
         else
         {
             numberstr = sr.ReadUntil(new char[] { '+', '-' });
         }
         double realpart;
         try {
             realpart = double.Parse(numberstr, CultureInfo.InvariantCulture);
         } catch (FormatException x) {
             throw new ParseException("invalid float format", x);
         }
         sr.Rewind(1);                 // rewind the +/-
         double imaginarypart = ParseImaginaryPart(sr);
         if (sr.Read() != ')')
         {
             throw new ParseException("expected ) to end a complex number");
         }
         return(new Ast.ComplexNumberNode()
         {
             Real = realpart,
             Imaginary = imaginarypart
         });
     }
     else
     {
         // imaginary
         double imag = ParseImaginaryPart(sr);
         return(new Ast.ComplexNumberNode()
         {
             Real = 0,
             Imaginary = imag
         });
     }
 }
Exemplo n.º 2
0
        private Ast.INode ParseCompound(SeekableStringReader sr)
        {
            // compound =  tuple | dict | list | set .
            sr.SkipWhitespace();
            switch (sr.Peek())
            {
            case '[':
                return(ParseList(sr));

            case '{':
            {
                int bm = sr.Bookmark();
                try {
                    return(ParseSet(sr));
                } catch (ParseException) {
                    sr.FlipBack(bm);
                    return(ParseDict(sr));
                }
            }

            case '(':
                // tricky case here, it can be a tuple but also a complex number:
                // if the last character before the closing parenthesis is a 'j', it is a complex number
            {
                int    bm            = sr.Bookmark();
                string betweenparens = sr.ReadUntil(')', '\n').TrimEnd();
                sr.FlipBack(bm);
                return(betweenparens.EndsWith("j") ? (Ast.INode)ParseComplex(sr) : ParseTuple(sr));
            }

            default:
                throw new ParseException("invalid sequencetype char");
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Parse from a string with the Python literal expression
        /// </summary>
        public Ast Parse(string expression)
        {
            Ast ast = new Ast();

            if (string.IsNullOrEmpty(expression))
            {
                return(ast);
            }

            SeekableStringReader sr = new SeekableStringReader(expression);

            if (sr.Peek() == '#')
            {
                sr.ReadUntil('\n');                  // skip comment line
            }
            try {
                ast.Root = ParseExpr(sr);
                sr.SkipWhitespace();
                if (sr.HasMore())
                {
                    throw new ParseException("garbage at end of expression");
                }
                return(ast);
            } catch (ParseException x) {
                string faultLocation = ExtractFaultLocation(sr);
                throw new ParseException(x.Message + " (at position " + sr.Bookmark() + "; '" + faultLocation + "')", x);
            }
        }
Exemplo n.º 4
0
        private Ast.NoneNode ParseNone(SeekableStringReader sr)
        {
            // None
            string n = sr.ReadUntil('e');

            if (n == "Non")
            {
                return(Ast.NoneNode.Instance);
            }
            throw new ParseException("expected None");
        }
Exemplo n.º 5
0
        double ParseImaginaryPart(SeekableStringReader sr)
        {
            //imaginary       = ['+' | '-' ] ( float | int ) 'j' .
            string numberstr = sr.ReadUntil('j');

            try {
                return(double.Parse(numberstr, CultureInfo.InvariantCulture));
            } catch (FormatException x) {
                throw new ParseException("invalid float format", x);
            }
        }
Exemplo n.º 6
0
        Ast.PrimitiveNode <bool> ParseBool(SeekableStringReader sr)
        {
            // True,False
            string b = sr.ReadUntil('e');

            if (b == "Tru")
            {
                return(new Ast.BooleanNode(true));
            }
            if (b == "Fals")
            {
                return(new Ast.BooleanNode(false));
            }
            throw new ParseException("expected bool, True or False");
        }
Exemplo n.º 7
0
        private Ast.PrimitiveNode <bool> ParseBool(SeekableStringReader sr)
        {
            // True,False
            string b = sr.ReadUntil('e');

            switch (b)
            {
            case "Tru":
                return(new Ast.BooleanNode(true));

            case "Fals":
                return(new Ast.BooleanNode(false));
            }

            throw new ParseException("expected bool, True or False");
        }
Exemplo n.º 8
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
            });
        }