public (bool, int) TryParseUnsignInt32() { int startIndex = Index; while (NotEnd() && char.IsDigit(Current())) { Index++; } if (Index > startIndex) { string numText = Text.Substring(startIndex, Index - startIndex); try { return(true, int.Parse(numText)); } catch (Exception ex) { throw ParseErrors.InvalidNumberValue(this, numText, ex); } } else { return(false, 0); } }
public char Current() { if (Index >= TotalLength) { throw ParseErrors.InvalidText(this); } return(Text[Index]); }
public LimitInfo ParseLimitInfo(string text) { if (string.IsNullOrWhiteSpace(text)) { return(null); } var context = new ParseContext(text, this.CurrentCulture); LimitInfo limitInfo = context.ParseLimitInfo(); context.SkipWhiteSpace(); if (context.NotEnd()) { throw ParseErrors.InvalidText(context); } return(limitInfo); }
public ValueInfo ParseValue(string text) { if (string.IsNullOrWhiteSpace(text)) { return(null); } var context = new ParseContext(text, this.CurrentCulture); context.SkipWhiteSpace(); var value = context.ParseValueInfo(); if (context.NotEnd()) { throw ParseErrors.InvalidText(context); } return(value); }
public static string ParseName(this ParseContext context) { context.SkipWhiteSpace(); int startIndex = context.Index; if (!IsValidNameFirstChar(context.Current())) { throw ParseErrors.InvalidFieldNameText(context); } context.Index++;// first char while (context.NotEnd() && IsValidNameChar(context.Current())) { context.Index++; } return(context.Text.Substring(startIndex, context.Index - startIndex)); }
public static void SkipWhiteSpaceAndFirstChar(this ParseContext context, char ch) { if (context.SkipWhiteSpace()) { if (context.Current() != ch) { throw ParseErrors.ExpectedCharNotFound(context, ch); } else { context.Index++; } } else { throw ParseErrors.ExpectedCharNotFound(context, ch); } }
public static FilterInfo ParseFilterInfo(this ParseContext context) { context.SkipWhiteSpace(); if (context.Current() == '(') { return(ParseCombinFilter(context)); } else { return(ParseSingleItemOne(context)); } FilterInfo ParseCombinFilter(ParseContext context) { List <FilterInfo> orItems = new List <FilterInfo>(); CombinSymbol lastOpType = CombinSymbol.OrItems; while (context.NotEnd()) { // skip start bracket context.SkipWhiteSpace(); if (context.Current() != '(') { throw ParseErrors.MissOpenBracket(context); } context.Index++; context.SkipWhiteSpace(); var inner = ParseFilterInfo(context); context.SkipWhiteSpace(); if (context.End() || context.Current() != ')') { throw ParseErrors.MissCloseBracket(context); } context.Index++; if (lastOpType == CombinSymbol.OrItems || orItems.Count == 0) { orItems.Add(inner); } else { orItems[^ 1] = orItems[^ 1].AndAlso(inner);
public static (bool, object) TryParseValue(this ParseContext context) { var originIndex = context.Index; context.SkipWhiteSpace(); if (context.End()) { context.Index = originIndex; return(false, null); } var current = context.Current(); if (current == '\"') { //string return(true, ParseStringValue(context)); } else if (char.IsLetter(current)) { //keyword eg string name = ParseName(context); if (KeyWordValues.TryGetValue(name, out var val)) { return(true, val); } else { context.Index = originIndex; return(false, null); } } else if (IsNumberStartChar(current, context)) { //number return(true, ParseNumberValue(context)); } else if (current == '[') { return(true, ParseArrayValue(context)); //array } return(false, null); string ParseStringValue(ParseContext context) { // skip start context.Index++; bool lastIsEscapeChar = false; var startIndex = context.Index; while (context.NotEnd()) { if (lastIsEscapeChar) { lastIsEscapeChar = false; context.Index++; continue; } else { var current = context.Current(); if (current == '\"') { break; } lastIsEscapeChar = IsEscapeChar(current); context.Index++; } } string origin = context.Text.Substring(startIndex, context.Index - startIndex); // skip end context.Index++; try { return(Regex.Unescape(origin)); } catch (Exception ex) { throw ParseErrors.InvalidStringValue(context, origin, ex); } } object ParseNumberValue(ParseContext context) { int startIndex = context.Index; bool hasDecimsl = context.Current() == context.NumberDecimal; bool hasDigit = char.IsDigit(context.Current()); // skip first char context.Index++; while (context.NotEnd()) { var current = context.Current(); if (char.IsDigit(current)) { hasDigit = true; context.Index++; } else if (current == context.NumberGroupSeparator) { if (hasDecimsl) { throw ParseErrors.InvalidValue(context); } context.Index++; } else if (current == context.NumberDecimal) { if (hasDecimsl) { throw ParseErrors.InvalidValue(context); } else { hasDecimsl = true; } context.Index++; } else { break; } } if (!hasDigit) { throw ParseErrors.InvalidValue(context); } var numString = context.Text.Substring(startIndex, context.Index - startIndex); try { if (hasDecimsl) { return(double.Parse(numString.Replace(context.NumberGroupSeparator.ToString(), string.Empty), NumberStyles.Any, context.CurrentCulture)); } else { return(int.Parse(numString.Replace(context.NumberGroupSeparator.ToString(), string.Empty), NumberStyles.Any, context.CurrentCulture)); } } catch (Exception ex) { throw ParseErrors.InvalidNumberValue(context, numString, ex); } } object ParseArrayValue(ParseContext context) { // skip start [ List <object> datas = new List <object>(); context.Index++; while (context.NotEnd()) { context.SkipWhiteSpace(); var current = context.Current(); if (current == ']') { context.Index++; break; } datas.Add(ParseValue(context, false)); context.SkipWhiteSpace(); if (context.Current() == ',') { context.Index++; } } return(datas.ToArray()); } object ParseKeywordValue(ParseContext context) { int startIndex = context.Index; while (context.NotEnd() && IsValidNameChar(context.Current())) { context.Index++; } string keyWord = context.Text.Substring(startIndex, context.Index - startIndex); if (KeyWordValues.TryGetValue(keyWord, out object value)) { return(value); } else { throw ParseErrors.InvalidKeywordValue(context, keyWord); } } object ParseValue(ParseContext context, bool parseArray = true) { context.SkipWhiteSpace(); var current = context.Current(); if (current == '\"') { //string return(ParseStringValue(context)); } else if (char.IsLetter(current)) { //keyword return(ParseKeywordValue(context)); } else if (IsNumberStartChar(current, context)) { //number return(ParseNumberValue(context)); } else if (parseArray && current == '[') { return(ParseArrayValue(context)); //array } else { throw ParseErrors.InvalidValue(context); } } }