/// <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); }
/// <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(); } }
protected internal virtual SearchCondition GetParsingTree(Expression parent) { if (Precedence > 0 && parent.Precedence > Precedence) { return SearchCondition.Create(false, SearchConditionBrackets.Create(GetParsingTree())); } else { return GetParsingTree(); } }
public virtual string ToString(Expression parent) { if (Precedence > 0 && parent.Precedence > Precedence) { return String.Format("({0})", ToString()); } else { return ToString(); } }
/// <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(); } }
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; }
public OperatorAnd(Expression left, Expression right) : base(left, right) { }
public Expression Visit(Expression node) { return node.Accept(this); }
/// <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); } } } }
public OperatorNot(Expression operand) : base(operand) { }
public BinaryExpression(Expression left, Expression right) { this.Left = left; this.Right = right; }
public BinaryExpression() { this.Left = null; this.Right = null; }
public override string ToString(Expression parent) { return ToString(); }
public Brackets(Expression expression) { this.Expression = expression; }
public UnaryExpression(Expression operand) { Operand = operand; }
public UnaryExpression() { Operand = null; }