private static void ReduceTermsForCommutativeOperator(List <object> tokens, BinaryOperator op) { Debug.Assert(tokens.IndexOf(null) == -1, "The tokens array contains a null."); int index = tokens.IndexOf(op); while (index != -1) { Debug.Assert(index != 0 && index != tokens.Count - 1, "index != 0 && index != tokens.Count - 1"); var terms = new List <IExpression>(); int endIndex = AddOperands(tokens, op, terms, index - 1); Debug.Assert(endIndex > index, "endIndex > index"); // Replace all the tokens from the start index to the end index with a CommutativeExpression. var commutative = new CommutativeExpression(op, terms); tokens[index - 1] = commutative.Simplify(); tokens.RemoveRange(index, endIndex - index + 1); if (index == tokens.Count) { break; } index = tokens.IndexOf(op, index + 1); } }
private static bool TrySplitSubExpressions(IExpression expression, ref string allWords, ref string exactPhrase, ref string anyWord, ref string withoutWords) { var commutative = expression as CommutativeExpression; if (commutative == null || commutative.Operator != BinaryOperator.And) { return(false); } // We have some ANDed sub-expressions. See if we can still split them. UnaryExpression not = null; var andedLiterals = new List <IExpression>(); LiteralTerm exact = null; CommutativeExpression oredLiterals = null; foreach (IExpression commTerm in commutative.Terms) { IExpression term = commTerm; // Is it a literal? var literal = term as LiteralTerm; if (literal != null) { if (exact == null && literal.IsExact) { exact = literal; } else { andedLiterals.Add(literal); } continue; } // Is it a NOT? var unary = term as UnaryExpression; if (unary != null) { if (not != null || unary.Operator != UnaryOperator.Not) { return(false); // More than one NOT or something other than NOT - cannot be split. } if (unary.Term is LiteralTerm || (unary.Term is CommutativeExpression && ((CommutativeExpression)unary.Term).Operator == BinaryOperator.Or)) { not = unary; continue; } return(false); } var innerAndOr = term as CommutativeExpression; if (innerAndOr != null) { if (innerAndOr.Operator != BinaryOperator.Or || !AreAllLiterals(innerAndOr.Terms)) { return(false); // A sub-expression - cannot be split. } if (oredLiterals != null) { return(false); // More than one OR - cannot be split. } oredLiterals = innerAndOr; continue; } return(false); } if (andedLiterals.Count > 0) { allWords = andedLiterals.Count == 1 ? andedLiterals[0].GetUserExpression() : JoinLiterals(andedLiterals); } if (not != null) { if (not.Term is LiteralTerm) { withoutWords = not.Term.GetUserExpression(); } else { Debug.Assert(not.Term is CommutativeExpression, "not.Term is CommutativeExpression"); withoutWords = JoinLiterals(((CommutativeExpression)not.Term).Terms); } } if (exact != null) { exactPhrase = exact.Value.Trim(LiteralTerm.Quote); } if (oredLiterals != null) { anyWord = JoinLiterals(oredLiterals.Terms); } return(true); }