Beispiel #1
0
        /// <summary>
        /// AND(Node, ZERO) -> Zero
        /// OR(Node, ZERO) -> Node
        /// NOT(ZERO) -> ALL
        /// </summary>
        /// <returns></returns>
        private static ExpressionTreeNode HandleZeroNode(ExpressionTreeNode node, ref int count)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Child1?.Operation == "ZERO" || node.Child2?.Operation == "ZERO")
            {
                var otherNode = node.Child1.Operation == "ZERO" ? node.Child2 : node.Child1;

                if (node.Operation == "AND")
                {
                    node = ExpressionTreeNode.CreateAllNode();
                }
                else if (node.Operation == "OR")
                {
                    node = otherNode;
                }
                else if (node.Operation == "NOT")
                {
                    node = ExpressionTreeNode.CreateAllNode();
                }

                count++;
            }

            return(node);
        }
Beispiel #2
0
        private ExpressionTreeNode ParseOr()
        {
            var node = ParseAnd();

            if (_tokenReader.Token != Token.Or)
            {
                return(node);
            }

            _tokenReader.NextToken();

            ExpressionTreeNode root = ExpressionTreeNode.CreateOr(node, ParseAnd());

            node = root;

            while (true)
            {
                if (_tokenReader.Token != Token.Or)
                {
                    return(root);
                }

                _tokenReader.NextToken();

                var child1 = node.Child2;

                node.Child2 = ExpressionTreeNode.CreateOr(child1, ParseAnd());

                node = node.Child2;
            }
        }
Beispiel #3
0
 public static ExpressionTreeNode CreateAnd(ExpressionTreeNode child1, ExpressionTreeNode child2)
 {
     return(new ExpressionTreeNode()
     {
         Operation = "AND", Child1 = child1, Child2 = child2
     });
 }
Beispiel #4
0
 public static ExpressionTreeNode CreateNot(ExpressionTreeNode term)
 {
     return(new ExpressionTreeNode()
     {
         Operation = "NOT", Child1 = term
     });
 }
Beispiel #5
0
        private ExpressionTreeNode ParseTerm()
        {
            if (_tokenReader.Token != Token.Term)
            {
                throw new Exception("Invalid search string format");
            }

            return(ExpressionTreeNode.CreateTerm(_tokenReader.Term));
        }
Beispiel #6
0
        private ExpressionTreeNode ParseNot()
        {
            if (_tokenReader.Token != Token.Not)
            {
                return(ParseTerm());
            }

            _tokenReader.NextToken();

            var term = ParseNot();

            return(ExpressionTreeNode.CreateNot(term));
        }
Beispiel #7
0
        private ExpressionTreeNode OptimizeTreeInternal(ExpressionTreeNode node, ref int count)
        {
            if (node == null)
            {
                return(null);
            }

            foreach (var action in _optimizeActions)
            {
                node = action(node, ref count);
            }

            node.Child1 = OptimizeTreeInternal(node.Child1, ref count);
            node.Child2 = OptimizeTreeInternal(node.Child2, ref count);

            return(node);
        }
Beispiel #8
0
        /// <summary>
        /// AND(NOT, term) -> AND(term, NOT).
        /// It helps execute note more faster.
        /// </summary>
        /// <param name="node"></param>
        private static ExpressionTreeNode ReplaceFirstNotInAndRule(ExpressionTreeNode node, ref int count)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Operation == "AND" && node.Child1.Operation == "NOT" && node.Child2.Operation != "NOT")
            {
                var child = node.Child1;
                node.Child1 = node.Child2;
                node.Child2 = child;

                count++;
            }

            return(node);
        }
Beispiel #9
0
        /// <summary>
        /// AND(NOT,NOT) -> NOT(OR)
        /// </summary>
        /// <param name="node"></param>
        private static ExpressionTreeNode TwoNotInAndRule(ExpressionTreeNode node, ref int count)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Operation == "AND" && node.Child1.Operation == "NOT" && node.Child2.Operation == "NOT")
            {
                var andChild = ExpressionTreeNode.CreateOr(node.Child1.Child1, node.Child2.Child1);

                node = ExpressionTreeNode.CreateNot(andChild);

                count++;
            }

            return(node);
        }
Beispiel #10
0
        /// <summary>
        /// OR(NOT, NOT) -> ALL - if terms are not equal
        /// OR(NOT, NOT) -> NOT(term) - if terms are equal
        /// </summary>
        /// <param name="node"></param>
        private static ExpressionTreeNode TwoNotInOrRule(ExpressionTreeNode node, ref int count)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Operation == "OR" && node.Child1.Operation == "NOT" && node.Child2.Operation == "NOT")
            {
                if (node.Child1.Child1.Term == node.Child2.Child1.Term)
                {
                    node = ExpressionTreeNode.CreateNot(node.Child1.Child1);
                }
                else
                {
                    node = ExpressionTreeNode.CreateAllNode();
                }

                count++;
            }

            return(node);
        }
Beispiel #11
0
        private ExpressionTreeNode OptimizeTree(ExpressionTreeNode node)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Operation == "ALL" || node.Operation == "ZERO")
            {
                return(node);
            }

            var count = 0;

            node = OptimizeTreeInternal(node, ref count);

            while (count != 0)
            {
                count = 0;
                node  = OptimizeTreeInternal(node, ref count);
            }

            return(node);
        }