コード例 #1
0
        /// <summary>
        /// Builds the expression tree from the output stack created by the shunting-yard algorithm
        /// </summary>
        /// <param name="sta"></param>
        /// <returns></returns>
        private LogicalExpressions.Expression GetExpressionTreeInternal(Stack <LogicalExpressions.Expression> sta)
        {
            LogicalExpressions.Expression exp = sta.Pop();
            {
                if (exp is LogicalExpressions.BinaryExpression)
                {
                    var bexp = exp as LogicalExpressions.BinaryExpression;
                    bexp.Right = GetExpressionTreeInternal(sta);
                    bexp.Left  = GetExpressionTreeInternal(sta);
                }
                else if (exp is LogicalExpressions.UnaryExpression)
                {
                    var uexp = exp as LogicalExpressions.UnaryExpression;
                    uexp.Operand = GetExpressionTreeInternal(sta);
                }
                else if (exp is LogicalExpressions.Brackets)
                {
                    // Brackets are not used in the expression tree, so eliminate them
                    var br = exp as LogicalExpressions.Brackets;
                    exp = br.Expression;
                }
            }

            return(exp);
        }
コード例 #2
0
        /// <summary>
        /// Enumerates terms of an expression tree of a search condition.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        /// <remarks>The expression tree must be in CNF</remarks>
        private static IEnumerable <LogicalExpressions.Expression> EnumerateCnfTerms(LogicalExpressions.Expression node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (node is LogicalExpressions.OperatorAnd)
            {
                // The CNF has multiple terms

                foreach (var exp in ((LogicalExpressions.OperatorAnd)node).EnumerateTerms())
                {
                    yield return(exp);
                }
            }
            else if (node is LogicalExpressions.OperatorOr ||
                     node is LogicalExpressions.OperatorNot ||
                     node is LogicalExpressions.Predicate)
            {
                // The CNF has only one term
                yield return(node);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
コード例 #3
0
ファイル: Expression.cs プロジェクト: skyquery/graywulf
 protected internal virtual SearchCondition GetParsingTree(Expression parent)
 {
     if (Precedence > 0 && parent.Precedence > Precedence)
     {
         return SearchCondition.Create(false, SearchConditionBrackets.Create(GetParsingTree()));
     }
     else
     {
         return GetParsingTree();
     }
 }
コード例 #4
0
ファイル: Expression.cs プロジェクト: skyquery/graywulf
 public virtual string ToString(Expression parent)
 {
     if (Precedence > 0 && parent.Precedence > Precedence)
     {
         return String.Format("({0})", ToString());
     }
     else
     {
         return ToString();
     }
 }
コード例 #5
0
 /// <summary>
 /// Returns a search condition predicate associated with a CNF literal
 /// </summary>
 /// <param name="term"></param>
 /// <returns></returns>
 private static Predicate GetCnfLiteralPredicate(LogicalExpressions.Expression term)
 {
     if (term is LogicalExpressions.OperatorNot)
     {
         return(((LogicalExpressions.Predicate)((LogicalExpressions.OperatorNot)term).Operand).Value);
     }
     else if (term is LogicalExpressions.Predicate)
     {
         return(((LogicalExpressions.Predicate)term).Value);
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
コード例 #6
0
ファイル: CnfConverter.cs プロジェクト: skyquery/graywulf
        protected internal override Expression VisitOperatorOr(OperatorOr node)
        {
            // Both operands must be in CNF
            var left = Visit(node.Left);
            var right = Visit(node.Right);

            // Form Cartesian product of terms
            Expression[] leftterms, rightterms;

            if (left is OperatorAnd)
            {
                leftterms = ((OperatorAnd)left).EnumerateTerms().ToArray();
            }
            else
            {
                leftterms = new Expression[] { left };
            }

            if (right is OperatorAnd)
            {
                rightterms = ((OperatorAnd)right).EnumerateTerms().ToArray();
            }
            else
            {
                rightterms = new Expression[] { right };
            }

            Expression res = null;

            for (int i = 0; i < leftterms.Length; i++)
            {
                for (int j = 0; j < rightterms.Length; j++)
                {
                    var t = new OperatorOr(leftterms[i], rightterms[j]);

                    if (res == null)
                    {
                        res = t;
                    }
                    else
                    {
                        res = new OperatorAnd(t, res);
                    }
                }
            }

            return res;
        }
コード例 #7
0
ファイル: OperatorAnd.cs プロジェクト: skyquery/graywulf
 public OperatorAnd(Expression left, Expression right)
     : base(left, right)
 {
 }
コード例 #8
0
 public Expression Visit(Expression node)
 {
     return node.Accept(this);
 }
コード例 #9
0
        /// <summary>
        /// Enumerates the terms of an expression tree that are specific to a table.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        /// <remarks>The expression must be in CNF</remarks>
        private static IEnumerable <LogicalExpressions.Expression> EnumerateCnfTermsSpecificToTable(LogicalExpressions.Expression node, TableReference table)
        {
            foreach (var term in EnumerateCnfTerms(node))
            {
                if (term is LogicalExpressions.OperatorOr)
                {
                    // A term is only specific to a table if it contains predicates
                    // only specific to the particular table
                    var specifictotable = true;
                    foreach (var exp in EnumerateCnfTermPredicates(term))
                    {
                        if (!GetCnfLiteralPredicate(exp).IsSpecificToTable(table))
                        {
                            specifictotable = false;
                            break;
                        }
                    }

                    if (specifictotable)
                    {
                        yield return(term);
                    }
                }
                else
                {
                    if (GetCnfLiteralPredicate(term).IsSpecificToTable(table))
                    {
                        yield return(term);
                    }
                }
            }
        }
コード例 #10
0
ファイル: OperatorNot.cs プロジェクト: skyquery/graywulf
 public OperatorNot(Expression operand)
     : base(operand)
 {
 }
コード例 #11
0
ファイル: BinaryExpression.cs プロジェクト: skyquery/graywulf
 public BinaryExpression(Expression left, Expression right)
 {
     this.Left = left;
     this.Right = right;
 }
コード例 #12
0
ファイル: BinaryExpression.cs プロジェクト: skyquery/graywulf
 public BinaryExpression()
 {
     this.Left = null;
     this.Right = null;
 }
コード例 #13
0
ファイル: Brackets.cs プロジェクト: skyquery/graywulf
 public override string ToString(Expression parent)
 {
     return ToString();
 }
コード例 #14
0
ファイル: Brackets.cs プロジェクト: skyquery/graywulf
 public Brackets(Expression expression)
 {
     this.Expression = expression;
 }
コード例 #15
0
ファイル: UnaryExpression.cs プロジェクト: skyquery/graywulf
 public UnaryExpression(Expression operand)
 {
     Operand = operand;
 }
コード例 #16
0
ファイル: UnaryExpression.cs プロジェクト: skyquery/graywulf
 public UnaryExpression()
 {
     Operand = null;
 }