/// 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); } }
/// 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); }
/// 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); } }
/// 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); } }
/// <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())); }
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)); }
public TokenQueue(Parser p, ParsingReader r) { _reader = r; _parser = p; }
/// 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); }