private RangeParseResult ParseRangeGroup(IEnumerator <Lexem> tokens, string context) { Type rangeType = null; while (tokens.Current.NextLexem != null && RangeTypes.Contains(tokens.Current.NextLexem.Value)) { rangeType = ParseRangeType(tokens, context: context); } if (rangeType == null) { ExpectNextToken(tokens, RangeTypes, context); } return(ParseRangeGroupContents(tokens, rangeType, context)); }
private RangeParseResult ParseRangeGroupContents(IEnumerator <Lexem> tokens, Type rangeType, string context) { List <object> minimumValues = new List <object>(); List <object> maximumValues = new List <object>(); var range = ParseRange(tokens, rangeType, context: context); minimumValues.AddRange(range.Select(r => r.Item1)); maximumValues.AddRange(range.Select(r => r.Item2)); if (tokens.Current.NextLexem != null) { RangeParseResult nextRange = null; if (tokens.Current.NextLexem.Value == "(") { nextRange = ParseRangeGroupContents(tokens, rangeType, context); } else if (RangeTypes.Contains(tokens.Current.NextLexem.Value)) { nextRange = ParseRangeGroup(tokens, context); if (!nextRange.Type.Equals(rangeType)) { throw new InvalidDataException("Non-uniform ranges are not supported. First encountered range: " + TypeToRangeDescription(rangeType) + ", next: " + TypeToRangeDescription(nextRange.Type)); } } if (nextRange != null) { minimumValues.AddRange(nextRange.MinimumValues); maximumValues.AddRange(nextRange.MaximumValues); } } return(new RangeParseResult() { Type = rangeType, MinimumValues = minimumValues, MaximumValues = maximumValues }); }
private IEnumerable <Tuple <object, object> > ParseRange(IEnumerator <Lexem> tokens, Type rangeType, string context) { if (tokens.Current.NextLexem != null && RangeTypes.Contains(tokens.Current.NextLexem.Value)) { return(Enumerable.Empty <Tuple <object, object> >()); } ExpectNextToken(tokens, "(", context: context + " range"); TypeConverter converter = TypeDescriptor.GetConverter(rangeType); List <Tuple <object, object> > result = new List <Tuple <object, object> >(); List <string> rangeTokens = new List <string>(); string token = GetNextToken(tokens, context: context + " range"); while (token != ")") // scanner guarantees that all parentheses are matched { rangeTokens.Add(token); token = GetNextToken(tokens, context: context + " range"); } if (rangeTokens.Count == 2) { result.Add(ParseRangeValues(rangeTokens[0], rangeTokens[1], converter, context: context)); } else if (rangeTokens.Count == 3) { int count = 0; Exception innerException = null; try { count = int.Parse(rangeTokens[0], CultureInfo.InvariantCulture); } catch (FormatException e) { innerException = e; } catch (OverflowException e) { innerException = e; } catch (ArgumentNullException e) { innerException = e; } if (innerException != null) { throw new InvalidDataException("Could not parse range multiplicity value: '" + rangeTokens[0] + "' when parsing " + context); } var rangeTuple = ParseRangeValues(rangeTokens[1], rangeTokens[2], converter, context: context); for (int i = 0; i < count; ++i) { result.Add(rangeTuple); } } return(result); }