protected static IList<ValueRange> DecodeRanges(object enumerator) { Symbol temp = null; var ranges = new List<ValueRange>(); bool size = false; while (temp != Symbol.CloseParentheses) { Symbol value1 = enumerator.Next(); Symbol value2 = null; if (value1 == Symbol.Size) { size = true; enumerator.Next().Expect(Symbol.OpenParentheses); continue; } temp = enumerator.Next(); if (temp == Symbol.DoubleDot) { value2 = enumerator.Next(); temp = enumerator.Next(); } var range = new ValueRange(value1, value2); if (size) { value1.Assert(range.Start >= 0, "invalid sub-typing; size must be greater than 0"); } value1.Assert(!Contains(range.Start, ranges), "invalid sub-typing"); if (value2 != null) { value2.Assert(!Contains(range.End, ranges), "invalid sub-typing"); } foreach (ValueRange other in ranges) { value1.Assert(!range.Contains(other.Start), "invalid sub-typing"); if (other.End != null) { value1.Assert(!range.Contains((int)other.End), "invalid sub-typing"); } } ranges.Add(range); } if (size) { enumerator.Next().Expect(Symbol.CloseParentheses); } return ranges; }
public static ValueRanges DecodeRanges(ISymbolEnumerator symbols) { ValueRanges result = new ValueRanges(); Symbol startSymbol = symbols.NextNonEOLSymbol(); Symbol current = startSymbol; current.Expect(Symbol.OpenParentheses); while (current != Symbol.CloseParentheses) { Symbol value1Symbol = symbols.NextNonEOLSymbol(); if ((value1Symbol == Symbol.Size) && !result.IsSizeDeclaration) { result.IsSizeDeclaration = true; symbols.NextNonEOLSymbol().Expect(Symbol.OpenParentheses); continue; } // check for valid number Int64? value1 = DecodeNumber(value1Symbol); if (!value1.HasValue) { value1Symbol.Assert(false, "Invalid range declaration!"); } // process next symbol ValueRange range; current = symbols.NextNonEOLSymbol(); if (current == Symbol.DoubleDot) { // its a continous range Symbol value2Symbol = symbols.NextNonEOLSymbol(); Int64? value2 = DecodeNumber(value2Symbol); value2Symbol.Assert(value2.HasValue && (value2.Value >= value1.Value), "Invalid range declaration!"); if (value2.Value == value1.Value) { range = new ValueRange(value1.Value, null); } else { range = new ValueRange(value1.Value, value2.Value); } current = symbols.NextNonEOLSymbol(); } else { // its a single number range = new ValueRange(value1.Value, null); } // validate range if (result.IsSizeDeclaration) { value1Symbol.Assert(range.Start >= 0, "Invalid range declaration! Size must be greater than 0"); } result.Add(range); // check next symbol current.Expect(Symbol.Pipe, Symbol.CloseParentheses); } if (result.IsSizeDeclaration) { current = symbols.NextNonEOLSymbol(); current.Expect(Symbol.CloseParentheses); } // validate ranges in between for (int i=0; i<result.Count; i++) { for (int k=i+1; k<result.Count; k++) { startSymbol.Assert(!result[i].IntersectsWith(result[k]), "Invalid range declaration! Overlapping of ranges!"); } } return result; }