IsMergeable() static private method

static private IsMergeable ( string charClass ) : bool
charClass string
return bool
Ejemplo n.º 1
0
        /*
         * ReduceAlternation:
         *
         * Basic optimization. Single-letter alternations can be replaced
         * by faster set specifications, and nested alternations with no
         * intervening operators can be flattened:
         *
         * a|b|c|def|g|h -> [a-c]|def|[gh]
         * apple|(?:orange|pear)|grape -> apple|orange|pear|grape
         */

        internal RegexNode ReduceAlternation()
        {
            // Combine adjacent sets/chars

            bool         wasLastSet;
            bool         lastNodeCannotMerge;
            RegexOptions optionsLast;
            RegexOptions optionsAt;
            int          i;
            int          j;
            RegexNode    at;
            RegexNode    prev;

            if (_children == null)
            {
                return(new RegexNode(RegexNode.Nothing, _options));
            }

            wasLastSet          = false;
            lastNodeCannotMerge = false;
            optionsLast         = 0;

            for (i = 0, j = 0; i < _children.Count; i++, j++)
            {
                at = _children[i];

                if (j < i)
                {
                    _children[j] = at;
                }

                for (; ;)
                {
                    if (at._type == Alternate)
                    {
                        for (int k = 0; k < at._children.Count; k++)
                        {
                            at._children[k]._next = this;
                        }

                        _children.InsertRange(i + 1, at._children);
                        j--;
                    }
                    else if (at._type == Set || at._type == One)
                    {
                        // Cannot merge sets if L or I options differ, or if either are negated.
                        optionsAt = at._options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase);


                        if (at._type == Set)
                        {
                            if (!wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge || !RegexCharClass.IsMergeable(at._str))
                            {
                                wasLastSet          = true;
                                lastNodeCannotMerge = !RegexCharClass.IsMergeable(at._str);
                                optionsLast         = optionsAt;
                                break;
                            }
                        }
                        else if (!wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge)
                        {
                            wasLastSet          = true;
                            lastNodeCannotMerge = false;
                            optionsLast         = optionsAt;
                            break;
                        }


                        // The last node was a Set or a One, we're a Set or One and our options are the same.
                        // Merge the two nodes.
                        j--;
                        prev = _children[j];

                        RegexCharClass prevCharClass;
                        if (prev._type == RegexNode.One)
                        {
                            prevCharClass = new RegexCharClass();
                            prevCharClass.AddChar(prev._ch);
                        }
                        else
                        {
                            prevCharClass = RegexCharClass.Parse(prev._str);
                        }

                        if (at._type == RegexNode.One)
                        {
                            prevCharClass.AddChar(at._ch);
                        }
                        else
                        {
                            RegexCharClass atCharClass = RegexCharClass.Parse(at._str);
                            prevCharClass.AddCharClass(atCharClass);
                        }

                        prev._type = RegexNode.Set;
                        prev._str  = prevCharClass.ToStringClass();
                    }
                    else if (at._type == RegexNode.Nothing)
                    {
                        j--;
                    }
                    else
                    {
                        wasLastSet          = false;
                        lastNodeCannotMerge = false;
                    }
                    break;
                }
            }

            if (j < i)
            {
                _children.RemoveRange(j, i - j);
            }

            return(StripEnation(RegexNode.Nothing));
        }
Ejemplo n.º 2
0
        internal RegexNode ReduceAlternation()
        {
            if (this._children == null)
            {
                return(new RegexNode(0x16, this._options));
            }
            bool         flag  = false;
            bool         flag2 = false;
            RegexOptions none  = RegexOptions.None;
            int          num   = 0;
            int          index = 0;

            while (num < this._children.Count)
            {
                RegexCharClass class2;
                RegexNode      node = this._children[num];
                if (index < num)
                {
                    this._children[index] = node;
                }
                if (node._type == 0x18)
                {
                    for (int i = 0; i < node._children.Count; i++)
                    {
                        node._children[i]._next = this;
                    }
                    this._children.InsertRange(num + 1, node._children);
                    index--;
                    goto Label_01C2;
                }
                if ((node._type != 11) && (node._type != 9))
                {
                    goto Label_01AB;
                }
                RegexOptions options2 = node._options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
                if (node._type == 11)
                {
                    if ((flag && (none == options2)) && (!flag2 && RegexCharClass.IsMergeable(node._str)))
                    {
                        goto Label_011B;
                    }
                    flag  = true;
                    flag2 = !RegexCharClass.IsMergeable(node._str);
                    none  = options2;
                    goto Label_01C2;
                }
                if ((!flag || (none != options2)) || flag2)
                {
                    flag  = true;
                    flag2 = false;
                    none  = options2;
                    goto Label_01C2;
                }
Label_011B:
                index--;
                RegexNode node2 = this._children[index];
                if (node2._type == 9)
                {
                    class2 = new RegexCharClass();
                    class2.AddChar(node2._ch);
                }
                else
                {
                    class2 = RegexCharClass.Parse(node2._str);
                }
                if (node._type == 9)
                {
                    class2.AddChar(node._ch);
                }
                else
                {
                    RegexCharClass cc = RegexCharClass.Parse(node._str);
                    class2.AddCharClass(cc);
                }
                node2._type = 11;
                node2._str  = class2.ToStringClass();
                goto Label_01C2;
Label_01AB:
                if (node._type == 0x16)
                {
                    index--;
                }
                else
                {
                    flag  = false;
                    flag2 = false;
                }
Label_01C2:
                num++;
                index++;
            }
            if (index < num)
            {
                this._children.RemoveRange(index, num - index);
            }
            return(this.StripEnation(0x16));
        }