private void Range(ExpressionType expType, RangeNode range, ValueValidator validator) { validator(expType, range.Start); if (range.End != null) { validator(expType, range.End); if (range.IsHalfOpen && ValuesAreEqual(expType, range.Start, range.End)) throw new SchyntaxParseException("Start and end values of a half-open range cannot be equal.", Input, range.Start.Index); } if (expType == ExpressionType.Dates && range.End != null) { // special validation to make the date range is sane var start = (DateValueNode)range.Start; var end = (DateValueNode)range.End; if (start.Year != null || end.Year != null) { if (start.Year == null || end.Year == null) throw new SchyntaxParseException("Cannot mix full and partial dates in a date range.", Input, start.Index); if (!IsStartBeforeEnd(start, end)) throw new SchyntaxParseException("End date of range is before the start date.", Input, start.Index); } } }
private RangeNode ParseRange(ExpressionType expressionType) { var range = new RangeNode(); range.Start = expressionType == ExpressionType.Dates ? (ValueNode)ParseDate() : ParseIntegerValue(expressionType); var isRange = false; if (IsNext(TokenType.RangeInclusive)) { isRange = true; } else if (IsNext(TokenType.RangeHalfOpen)) { isRange = true; range.IsHalfOpen = true; } if (isRange) { range.AddToken(Advance()); range.End = expressionType == ExpressionType.Dates ? (ValueNode)ParseDate() : ParseIntegerValue(expressionType); } return range; }