Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
        }