/// Parse stream until the end of the expression, evaluate it, and return result of the evaluation converted to type T
        public T Eval <T>(ParsingReader sr)
        {
            var p = Parser.Parse(sr);

            if (p == null)
            {
                return(Utils.To <T>(null));
            }
            return(Eval <T>(p));
        }
 /// Evaluate string and return the result of the evaluation, casted to the type T
 public T Eval <T>(string st)
 {
     using (var sr = new ParsingReader(new StringReader(st)))
     {
         var o = Eval <T>(sr);
         sr.SkipWhiteSpaceAndComments();
         sr.ReadAndThrowIfNot(-1);
         return(o);
     }
 }
示例#3
0
 /// True if str is a number
 public static bool IsNumber(string str)
 {
     if (str == null)
     {
         throw new ArgumentNullException("str");
     }
     using (var sr = new ParsingReader(str))
     {
         if (sr.ReadNumber() == null)
         {
             return(false);
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             return(false);
         }
     }
     return(true);
 }
示例#4
0
 /// Returns null if str is not a number, or its value otherwise
 public static ValueType TryParseNumber(string stringToParse)
 {
     if (stringToParse == null)
     {
         return(null);
     }
     using (var sr = new ParsingReader(stringToParse))
     {
         sr.SkipWhiteSpaceAndComments();
         ValueType o = sr.ReadNumber();
         if (o == null)
         {
             return(null);
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             return(null);
         }
         return(o);
     }
 }
示例#5
0
 /// Parse string to a number. 10 and hex numbers (like 0x222) are allowed. Suffixes like 20.3f are also allowed.
 public static ValueType ParseNumber(string str)
 {
     if (str == null)
     {
         throw new ArgumentNullException("str");
     }
     using (var sr = new ParsingReader(str))
     {
         sr.SkipWhiteSpaceAndComments();
         ValueType o = sr.ReadNumber();
         if (o == null)
         {
             throw new ParsingException("Invalid numeric expression at " + sr.ReadLine());
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             throw new ParsingException("Invalid numeric expression, unexpected characters at " + sr.ReadLine());
         }
         return(o);
     }
 }
示例#6
0
        /// <summary>
        /// Parse stream and return the expression tree
        /// </summary>
        /// <param name="r">Stream</param>
        /// <returns>Parsed expression or null if no expression is found on stream</returns>
        public IOperation Parse(ParsingReader r)
        {
            List <IOperation> data = new List <IOperation>();

            while (!r.IsEOF)
            {
                TokenQueue tokenQueue = new TokenQueue(this, r);
                var        ex         = parseSingleStatement(tokenQueue, -1);
                if (ex == null)
                {
                    break;
                }
                if (data.Count > 0)
                {
                    data.Add(new Operations.OperationPop());
                }
                data.Add(ex);
                r.SkipWhiteSpaceAndComments();
                if (r.Peek() != ';')
                {
                    break;
                }
                do
                {
                    r.Read();
                    r.SkipWhiteSpaceAndComments();
                } while (r.Peek() == ';');
            }
            if (data.Count == 0)
            {
                return(null);
            }
            if (data.Count == 1)
            {
                return(data[0]);
            }
            return(new Operations.OperationExpression(data.ToArray()));
        }
示例#7
0
        private static object convertString(string text, Type pt)
        {
            if (pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (String.IsNullOrEmpty(text))
                {
                    return(null);
                }
                return(convertString(text, pt.GetGenericArguments()[0]));
            }
            if (String.IsNullOrEmpty(text))
            {
                if (pt.IsPrimitive || pt.IsEnum || pt == typeof(decimal))
                {
                    text = "0";
                }
            }


            if (pt == typeof(bool))
            {
                int t;
                if (Int32.TryParse(text, out t))
                {
                    return(t != 0);
                }
                return(Boolean.Parse(text));
            }
            if (pt == typeof(byte) ||
                pt == typeof(sbyte) ||
                pt == typeof(short) ||
                pt == typeof(ushort) ||
                pt == typeof(int) ||
                pt == typeof(uint) ||
                pt == typeof(long) ||
                pt == typeof(ulong) ||
                pt == typeof(decimal) ||
                pt == typeof(float) ||
                pt == typeof(double))
            {
                object o = ParsingReader.TryParseNumber(text);
                if (o == null)
                {
                    throw new InvalidCastException("Cannot cast '" + text + "' to " + pt.FullName);
                }
                return(Convert.ChangeType(o, pt));
            }
            if (pt == typeof(char?))
            {
                if (string.IsNullOrEmpty(text))
                {
                    return(null);
                }
                return(text[0]);
            }
            if (pt == typeof(char))
            {
                return(text[0]);
            }
            if (pt == typeof(DateTime))
            {
                return(DateTime.Parse(text));
            }
            if (pt == typeof(Guid))
            {
                return(new Guid(text));
            }
            if (pt == typeof(string))
            {
                return(text);
            }
            if (pt.IsEnum)
            {
                bool hasFlags  = CustomAttributeHelper.Has <FlagsAttribute>(pt);
                bool hasDigits = !string.IsNullOrEmpty(text) && text.IndexOfAny("0123456789".ToCharArray()) != -1;
                bool isempty   = string.IsNullOrEmpty(text);
                if (isempty || hasFlags || hasDigits)
                {
                    long val        = 0;
                    var  names      = Enum.GetNames(pt);
                    var  dictionary = new Dictionary <string, long>(StringComparer.OrdinalIgnoreCase);
                    var  values     = Enum.GetValues(pt);
                    for (int i = 0; i < names.Length; ++i)
                    {
                        long vv = (long)Convert.ChangeType(values.GetValue(i), typeof(long));
                        dictionary[names[i]] = vv;
                        if (isempty && vv == 0)
                        {
                            return(Enum.ToObject(pt, vv));
                        }
                    }
                    if (isempty)
                    {
                        throw new InvalidCastException(String.Format("Unexpected empty enum value"));
                    }

                    int step = 0;
                    foreach (string str in text.Split(s_enumDelimiters))
                    {
                        if (String.IsNullOrEmpty(str))
                        {
                            continue;
                        }
                        step++;
                        if (!hasFlags && step > 1)
                        {
                            throw new InvalidCastException(String.Format("Unexpected enum value {0}", str));
                        }
                        long v;
                        if (char.IsDigit(str[0]))
                        {
                            val |= ParsingReader.ParseNumber <long>(str);
                        }
                        else if (dictionary.TryGetValue(str, out v))
                        {
                            val |= v;
                        }
                        else
                        {
                            throw new InvalidCastException(String.Format("Unexpected enum value {0}", str));
                        }
                    }
                    return(Enum.ToObject(pt, val));
                }
                return(Enum.Parse(pt, text, true));
            }

            throw new InvalidCastException(String.Format("'{0}' cannot be converted to {1}", text, pt.ToString()));
        }
 /// Parse stream until the end of the expression, evaluate it, and return result of the evaluation
 public object Eval(ParsingReader sr)
 {
     return(Eval <object>(sr));
 }
示例#9
0
 public TokenQueue(Parser p, ParsingReader r)
 {
     _reader = r;
     _parser = p;
 }
示例#10
0
        /// Parse multi-expression, like ${a|b|=2+3}
        public IOperation ParseMulti(ParsingReader reader)
        {
            Operations.OperationVariableAccess va = new Operations.OperationVariableAccess();
            StringBuilder sb    = new StringBuilder();
            bool          orMet = true;
            int           n;

            while ((n = reader.Peek()) != -1)
            {
                var q = (char)n;
                if (q == '}' || q == ')' || q == ']')
                {
                    break;
                }
                switch (q)
                {
                case '|':
                    reader.Read();
                    va.AddName(sb.ToString());
                    sb.Length = 0;
                    orMet     = true;
                    break;

                case '\'':
                case '\"':
                case '`':
                    orMet = false;
                    if (sb.Length != 0)
                    {
                        reader.ThrowParsingException("Quote must be a first character");
                    }
                    va.AddValue(reader.ReadQuote());
                    reader.SkipWhiteSpaceAndComments();
                    if (reader.Peek() != '}' && reader.Peek() != '|')
                    {
                        reader.ThrowParsingException("Unexpected character '" + (char)reader.Peek() + "'");
                    }
                    sb.Length = 0;
                    break;

                case '=':
                    orMet = false;
                    reader.Read();
                    var v = Parse(reader);
                    if (v != null)
                    {
                        va.AddExpression(v);
                    }
                    else
                    {
                        va.AddValue(null);
                    }
                    break;

                default:
                    orMet = false;
                    sb.Append(q);
                    reader.Read();
                    break;
                }
            }
            if (sb.Length > 0 || orMet)
            {
                va.AddName(sb.ToString());
            }
            return(va);
        }