Esempio n. 1
0
        public override Expression Optimize()
        {
            bool somethingChanged;

            Expression previous;

            IList <Expression> oldList = ConcatHelper.Iterate(Expressions.Select(e => e.Optimize())).ToList();
            IList <Expression> newList;

            do
            {
                somethingChanged = false;
                newList          = new List <Expression>();

                previous = null;

                foreach (Expression expression in oldList)
                {
                    if (expression == Empty.Instance)
                    {
                        somethingChanged = true;
                        continue;
                    }

                    if (previous == null)
                    {
                        previous = expression;
                        continue;
                    }

                    Iteration iteration1 = previous.As <Iteration>();
                    Iteration iteration2 = expression.As <Iteration>();

                    if (iteration1 != null || iteration2 != null)
                    {
                        if (iteration1 != null && iteration2 != null && iteration1.Expression == iteration2.Expression)
                        {
                            if (iteration1.IsPositive && iteration2.IsPositive)
                            {
                                newList.Add(iteration1.Expression);
                            }

                            previous         = new Iteration(iteration1.Expression, iteration1.IsPositive || iteration2.IsPositive);
                            somethingChanged = true;
                            continue;
                        }

                        Iteration  iteration;
                        Expression newExpression;

                        if (iteration1 != null)
                        {
                            iteration     = iteration1;
                            newExpression = expression;
                        }
                        else
                        {
                            iteration     = iteration2;
                            newExpression = previous;
                        }

                        if (iteration.Expression == newExpression && !iteration.IsPositive)
                        {
                            previous         = new Iteration(newExpression, true);
                            somethingChanged = true;
                            continue;
                        }
                    }

                    ConstIteration constIteration1 = previous.As <ConstIteration>();
                    ConstIteration constIteration2 = expression.As <ConstIteration>();

                    if (constIteration1 != null || constIteration2 != null)
                    {
                        if (constIteration1 != null && constIteration2 != null && constIteration1.Expression == constIteration2.Expression)
                        {
                            previous         = new ConstIteration(constIteration1.Expression, constIteration1.IterationCount + constIteration2.IterationCount);
                            somethingChanged = true;
                            continue;
                        }

                        ConstIteration constIteration;
                        Expression     newExpression;

                        if (constIteration1 != null)
                        {
                            constIteration = constIteration1;
                            newExpression  = expression;
                        }
                        else
                        {
                            constIteration = constIteration2;
                            newExpression  = previous;
                        }

                        if (constIteration.Expression == newExpression)
                        {
                            previous         = new ConstIteration(newExpression, constIteration.IterationCount + 1);
                            somethingChanged = true;
                            continue;
                        }
                    }

                    if (constIteration1 != null && iteration2 != null && constIteration1.Expression == iteration2.Expression)
                    {
                        if (constIteration1.IterationCount > 2)
                        {
                            newList.Add(new ConstIteration(constIteration1.Expression, constIteration1.IterationCount - 1));
                        }
                        else
                        {
                            newList.Add(constIteration1.Expression);
                        }

                        previous         = new Iteration(iteration2.Expression, true);
                        somethingChanged = true;
                        continue;
                    }

                    if (iteration1 != null && constIteration2 != null && iteration1.Expression == constIteration2.Expression)
                    {
                        newList.Add(new Iteration(iteration1.Expression, true));

                        if (constIteration2.IterationCount > 2)
                        {
                            previous = new ConstIteration(constIteration2.Expression, constIteration2.IterationCount - 1);
                        }
                        else
                        {
                            previous = constIteration2.Expression;
                        }

                        somethingChanged = true;
                        continue;
                    }

                    newList.Add(previous);
                    previous = expression;
                }

                if (previous != null)
                {
                    newList.Add(previous);
                }

                oldList = newList;

                somethingChanged |= TryToCompress(oldList);
            } while (somethingChanged);

            return(ConcatHelper.MakeExpression(newList));
        }
Esempio n. 2
0
        private static bool TryToCompress(IList <Expression> list)
        {
            bool changed;
            bool somethingChanged = false;

            do
            {
                changed = false;

                for (int i = 0; i < list.Count; i++)
                {
                    Iteration iteration = list[i].As <Iteration>();

                    if (iteration == null || iteration.IsPositive)
                    {
                        continue;
                    }

                    Concat concat = iteration.Expression.As <Concat>();

                    IList <Expression> list1;

                    if (concat != null)
                    {
                        list1 = concat.Expressions.ToList();
                    }
                    else
                    {
                        list1 = iteration.Expression.AsSequence().ToList();
                    }

                    int j = 0;

                    IList <Expression> list2 = null;

                    for (j = 0; j <= list1.Count; j++)
                    {
                        if (j > i || list1.Count - j > list.Count - i - 1)
                        {
                            continue;
                        }

                        list2 = new List <Expression>();

                        int k;

                        for (k = 0; k < j; k++)
                        {
                            list2.Add(list[i - j + k]);
                        }

                        for (k = 0; k < list1.Count - j; k++)
                        {
                            list2.Add(list[i + 1 + k]);
                        }

                        bool allEquals = true;

                        for (int l = 0; l < list1.Count; l++)
                        {
                            if (list1[l] != list2[(l + j) % list2.Count])
                            {
                                allEquals = false;
                                break;
                            }
                        }

                        if (allEquals)
                        {
                            break;
                        }
                    }

                    if (j <= list1.Count)
                    {
                        Expression newExpression = new Iteration(ConcatHelper.MakeExpression(list2), true);

                        for (int l = list1.Count - j; l > 0; l--)
                        {
                            list.RemoveAt(i + l);
                        }

                        for (int l = 0; l <= j; l++)
                        {
                            list.RemoveAt(i - l);
                        }

                        i -= j + 1;

                        list.Insert(i + 1, newExpression);

                        changed          = true;
                        somethingChanged = true;
                    }
                }
            } while (changed);

            return(somethingChanged);
        }
Esempio n. 3
0
        private static Expression ExtractFromBrackets(Expression expressionA, Expression expressionB)
        {
            IReadOnlyList <Expression> concatA = expressionA.As <Concat>()?.Expressions;

            if (concatA == null)
            {
                concatA = expressionA.AsSequence().ToList().AsReadOnly();
            }

            IReadOnlyList <Expression> concatB = expressionB.As <Concat>()?.Expressions;

            if (concatB == null)
            {
                concatB = expressionB.AsSequence().ToList().AsReadOnly();
            }

            int left  = 0;
            int right = 0;

            int count = Math.Min(concatA.Count, concatB.Count);

            while (left < count && concatA[left] == concatB[left])
            {
                left++;
            }

            while (right < count - left && concatA[concatA.Count - 1 - right] == concatB[concatB.Count - 1 - right])
            {
                right++;
            }

            if (left == 0 && right == 0)
            {
                return(null);
            }

            IList <Expression>          newConcat   = new List <Expression>();
            IList <Expression>          leftConcat  = new List <Expression>();
            IList <IList <Expression> > middleUnion = new List <IList <Expression> >();
            IList <Expression>          rightConcat = new List <Expression>();

            for (int i = 0; i < left; i++)
            {
                leftConcat.Add(concatA[i]);
            }

            for (int i = 0; i < right; i++)
            {
                rightConcat.Add(concatB[concatB.Count - 1 - i]);
            }

            rightConcat = rightConcat.AsReadOnly().FastReverse().ToList();

            IList <Expression> middleConcat = new List <Expression>();

            for (int i = left; i < concatA.Count - right; i++)
            {
                middleConcat.Add(concatA[i]);
            }

            middleUnion.Add(middleConcat);

            middleConcat = new List <Expression>();

            for (int i = left; i < concatB.Count - right; i++)
            {
                middleConcat.Add(concatB[i]);
            }

            middleUnion.Add(middleConcat);

            newConcat.AddRange(leftConcat);
            newConcat.Add(
                UnionHelper.MakeExpression(
                    middleUnion.Select(
                        c => ConcatHelper.MakeExpression(c.Where(e => e != Empty.Instance).ToList())
                        ).ToList()
                    )
                );
            newConcat.AddRange(rightConcat);

            return(ConcatHelper.MakeExpression(newConcat).Optimize());
        }