private static FormatException GenerateFilterParseException(MetricFilterExpressionToken encountered, MetricFilterExpressionToken.TokenType expected) { return(new FormatException( string.Format(CultureInfo.InvariantCulture, "Failed to parse expression. Expected {0} token (encountered {1}).", expected, encountered))); }
// Parse filter clause (or parenthesized expression) corresponds to F -> ID EQ VALUE | (E) private static MetricFilterExpressionTree ParseFilterClause(MetricFilterExpressionTokenizer tokenizer) { if (tokenizer == null || tokenizer.IsEmpty) { throw GenerateFilterParseException(null, MetricFilterExpressionToken.TokenType.Identifier); } MetricFilterExpressionToken token = tokenizer.Current; switch (token.Type) { case MetricFilterExpressionToken.TokenType.Identifier: // F -> ID EQ VALUE // validate and store the parameter name FilterParameter parameter = ParseParameter(token.Value); // Consume name tokenizer.Advance(); // Verify and comsume EQ if (tokenizer.IsEmpty || tokenizer.Current.Type != MetricFilterExpressionToken.TokenType.EqOperator) { throw GenerateFilterParseException(tokenizer.Current, MetricFilterExpressionToken.TokenType.EqOperator); } tokenizer.Advance(); MetricFilterExpressionToken.TokenType expectedType = GetExpectedTokenTypeForParameter(parameter); // Verify, store, and consume value if (tokenizer.IsEmpty || tokenizer.Current.Type != expectedType) { throw GenerateFilterParseException(tokenizer.Current, expectedType); } string value = tokenizer.Current.Value; tokenizer.Advance(); return(new MetricFilterExpressionTree() { Value = new KeyValuePair <FilterParameter, string>(ParseParameter(token.Value), value) }); case MetricFilterExpressionToken.TokenType.OpenParen: // F -> (E) // Consume ( tokenizer.Advance(); // Match Expression MetricFilterExpressionTree node = ParseFilterExpression(tokenizer); // Verify and consume ) if (tokenizer.IsEmpty || tokenizer.Current.Type != MetricFilterExpressionToken.TokenType.CloseParen) { throw GenerateFilterParseException(tokenizer.Current, MetricFilterExpressionToken.TokenType.CloseParen); } tokenizer.Advance(); return(node); default: throw GenerateFilterParseException(token, MetricFilterExpressionToken.TokenType.Identifier); } }