示例#1
0
        // Build MetricFilter from expression tree by depth-first evaluation
        private static MetricFilterExpression InterpretFilterExpressionTree(MetricFilterExpressionTree tree)
        {
            if (tree == null)
            {
                return(null);
            }

            // Leaf Node: Create simple Filter
            if (tree.LeftExpression == null && tree.RightExpression == null)
            {
                MetricFilterExpression expression = new MetricFilterExpression(
                    tree.Value.Key == FilterParameter.TimeGrain ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.StartTime ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.EndTime ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.MetricName ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.DimensionName ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.DimensionValue ? tree.Value.Value : null);

                return(expression);
            }

            // Just in case (should never happen)
            if (tree.LeftExpression == null || tree.RightExpression == null)
            {
                throw new FormatException("Unexpected Parse Error.");
            }

            // Tree Node: Combine children
            return(tree.IsConjunction
                ? InterpretFilterExpressionTree(tree.LeftExpression).And(InterpretFilterExpressionTree(tree.RightExpression)) as MetricFilterExpression
                : InterpretFilterExpressionTree(tree.LeftExpression).Or(InterpretFilterExpressionTree(tree.RightExpression)) as MetricFilterExpression);
        }
示例#2
0
        // Parse Filter Term (conjunction) corresponds to T -> F AND T | F
        private static MetricFilterExpressionTree ParseFilterTerm(MetricFilterExpressionTokenizer tokenizer)
        {
            // Match Clause
            MetricFilterExpressionTree node = ParseFilterClause(tokenizer);

            // T -> F
            if (tokenizer.IsEmpty)
            {
                return(node);
            }

            if (tokenizer.Current.Type == MetricFilterExpressionToken.TokenType.AndOperator)
            {
                // Consume AND
                tokenizer.Advance();

                // T -> F AND T
                return(new MetricFilterExpressionTree()
                {
                    IsConjunction = true,
                    LeftExpression = node,
                    RightExpression = ParseFilterTerm(tokenizer)
                });
            }

            return(node);
        }
示例#3
0
        // Parse Filter Expression (disjunction) corresponds to E -> T OR E | T
        private static MetricFilterExpressionTree ParseFilterExpression(MetricFilterExpressionTokenizer tokenizer)
        {
            MetricFilterExpressionTree node = ParseFilterTerm(tokenizer);

            // E -> T
            if (tokenizer.IsEmpty)
            {
                return(node);
            }

            if (tokenizer.Current.Type == MetricFilterExpressionToken.TokenType.OrOperator)
            {
                // Consume OR
                tokenizer.Advance();

                // E -> T OR E
                return(new MetricFilterExpressionTree()
                {
                    IsConjunction = false,
                    LeftExpression = node,
                    RightExpression = ParseFilterExpression(tokenizer)
                });
            }

            return(node);
        }
示例#4
0
        /**
         * Parser implements a recursive-descent parser for the following grammar:
         *
         * E -> T OR E | T
         * T -> F AND T | F
         * F -> ID EQ VALUE | ( E )
         *
         * E = Expression (ANDs and ORs)
         * T = Term (ANDs only)
         * F = Clause
         * ID = Identifier (token)
         * EQ = EQ operator (token)
         * VALUE = value (token)
         * OR = OR operator (token)
         * AND = AND operator (token)
         * ( and ) are also terminals (tokens)
         * */

        private static MetricFilterExpressionTree ParseFilterExpressionTree(MetricFilterExpressionTokenizer tokenizer)
        {
            MetricFilterExpressionTree tree = ParseFilterExpression(tokenizer);

            if (!tokenizer.IsEmpty)
            {
                throw GenerateFilterParseException(tokenizer.Current, MetricFilterExpressionToken.TokenType.OrOperator);
            }

            return(tree);
        }
示例#5
0
        // 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);
            }
        }
        // Build MetricFilter from expression tree by depth-first evaluation
        private static MetricFilterExpression InterpretFilterExpressionTree(MetricFilterExpressionTree tree)
        {
            if (tree == null)
            {
                return null;
            }

            // Leaf Node: Create simple Filter
            if (tree.LeftExpression == null && tree.RightExpression == null)
            {
                MetricFilterExpression expression = new MetricFilterExpression(
                    tree.Value.Key == FilterParameter.TimeGrain ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.StartTime ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.EndTime ? tree.Value.Value : null,
                    tree.Value.Key == FilterParameter.Name ? tree.Value.Value : null);

                return expression;
            }

            // Just in case (should never happen)
            if (tree.LeftExpression == null || tree.RightExpression == null)
            {
                throw new FormatException("Unexpected Parse Error.");
            }

            // Tree Node: Combine children
            return tree.IsConjunction
                ? InterpretFilterExpressionTree(tree.LeftExpression)
                    .And(InterpretFilterExpressionTree(tree.RightExpression))
                : InterpretFilterExpressionTree(tree.LeftExpression)
                    .Or(InterpretFilterExpressionTree(tree.RightExpression));
        }