Пример #1
0
        /// <summary>Performs additional optimizations on an entire tree prior to being used.</summary>
        internal RegexNode FinalOptimize()
        {
            RegexNode rootNode = this;

            // If we find backtracking construct at the end of the regex, we can instead make it non-backtracking,
            // since nothing would ever backtrack into it anyway.  Doing this then makes the construct available
            // to implementations that don't support backtracking.
            if ((Options & RegexOptions.RightToLeft) == 0 && // only apply optimization when LTR to avoid needing additional code for the rarer RTL case
                (Options & RegexOptions.Compiled) != 0)      // only apply when we're compiling, as that's the only time it would make a meaningful difference
            {
                RegexNode node = rootNode;
                while (true)
                {
                    switch (node.Type)
                    {
                    case Oneloop:
                        node.Type = Oneloopatomic;
                        break;

                    case Notoneloop:
                        node.Type = Notoneloopatomic;
                        break;

                    case Setloop:
                        node.Type = Setloopatomic;
                        break;

                    case Capture:
                    case Concatenate:
                        RegexNode existingChild = node.Child(node.ChildCount() - 1);
                        switch (existingChild.Type)
                        {
                        default:
                            node = existingChild;
                            break;

                        case Alternate:
                        case Loop:
                        case Lazyloop:
                            var atomic = new RegexNode(Atomic, Options);
                            atomic.AddChild(existingChild);
                            node.ReplaceChild(node.ChildCount() - 1, atomic);
                            break;
                        }
                        continue;

                    case Atomic:
                        node = node.Child(0);
                        continue;
                    }

                    break;
                }
            }

            // Done optimizing.  Return the final tree.
            return(rootNode);
        }