UseOptionR() private method

private UseOptionR ( ) : bool
return bool
Beispiel #1
0
        /// <summary>
        /// The main RegexCode generator. It does a depth-first walk
        /// through the tree and calls EmitFragment to emits code before
        /// and after each child of an interior node, and at each leaf.
        /// </summary>
        private void EmitFragment(int nodetype, RegexNode node, int curIndex)
        {
            int bits = 0;

            if (nodetype <= RegexNode.Ref)
            {
                if (node.UseOptionR())
                {
                    bits |= RegexCode.Rtl;
                }
                if ((node.Options & RegexOptions.IgnoreCase) != 0)
                {
                    bits |= RegexCode.Ci;
                }
            }

            switch (nodetype)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Concatenate | AfterChild:
            case RegexNode.Empty:
                break;

            case RegexNode.Alternate | BeforeChild:
                if (curIndex < node.Children !.Count - 1)
                {
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                }
                break;

            case RegexNode.Alternate | AfterChild:
            {
                if (curIndex < node.Children !.Count - 1)
                {
                    int LBPos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(LBPos, _emitted.Length);
                }
Beispiel #2
0
        /*
         * The main RegexCode generator. It does a depth-first walk
         * through the tree and calls EmitFragment to emits code before
         * and after each child of an interior node, and at each leaf.
         */
        internal void EmitFragment(int nodetype, RegexNode node, int CurIndex)
        {
            int bits = 0;

            if (nodetype <= RegexNode.Ref)
            {
                if (node.UseOptionR())
                {
                    bits |= RegexCode.Rtl;
                }
                if ((node._options & RegexOptions.IgnoreCase) != 0)
                {
                    bits |= RegexCode.Ci;
                }
            }

            switch (nodetype)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Concatenate | AfterChild:
            case RegexNode.Empty:
                break;

            case RegexNode.Alternate | BeforeChild:
                if (CurIndex < node._children.Count - 1)
                {
                    PushInt(CurPos());
                    Emit(RegexCode.Lazybranch, 0);
                }
                break;

            case RegexNode.Alternate | AfterChild: {
                if (CurIndex < node._children.Count - 1)
                {
                    int LBPos = PopInt();
                    PushInt(CurPos());
                    Emit(RegexCode.Goto, 0);
                    PatchJump(LBPos, CurPos());
                }
                else
                {
                    int I;
                    for (I = 0; I < CurIndex; I++)
                    {
                        PatchJump(PopInt(), CurPos());
                    }
                }
                break;
            }

            case RegexNode.Testref | BeforeChild:
                switch (CurIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    PushInt(CurPos());
                    Emit(RegexCode.Lazybranch, 0);
                    Emit(RegexCode.Testref, MapCapnum(node._m));
                    Emit(RegexCode.Forejump);
                    break;
                }
                break;

            case RegexNode.Testref | AfterChild:
                switch (CurIndex)
                {
                case 0: {
                    int Branchpos = PopInt();
                    PushInt(CurPos());
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, CurPos());
                    Emit(RegexCode.Forejump);
                    if (node._children.Count > 1)
                    {
                        break;
                    }
                    // else fallthrough
                    goto case 1;
                }

                case 1:
                    PatchJump(PopInt(), CurPos());
                    break;
                }
                break;

            case RegexNode.Testgroup | BeforeChild:
                switch (CurIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    Emit(RegexCode.Setmark);
                    PushInt(CurPos());
                    Emit(RegexCode.Lazybranch, 0);
                    break;
                }
                break;

            case RegexNode.Testgroup | AfterChild:
                switch (CurIndex)
                {
                case 0:
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);
                    break;

                case 1:
                    int Branchpos = PopInt();
                    PushInt(CurPos());
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, CurPos());
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);

                    if (node._children.Count > 2)
                    {
                        break;
                    }
                    // else fallthrough
                    goto case 2;

                case 2:
                    PatchJump(PopInt(), CurPos());
                    break;
                }
                break;

            case RegexNode.Loop | BeforeChild:
            case RegexNode.Lazyloop | BeforeChild:

                if (node._n < infinite || node._m > 1)
                {
                    Emit(node._m == 0 ? RegexCode.Nullcount : RegexCode.Setcount, node._m == 0 ? 0 : 1 - node._m);
                }
                else
                {
                    Emit(node._m == 0 ? RegexCode.Nullmark : RegexCode.Setmark);
                }

                if (node._m == 0)
                {
                    PushInt(CurPos());
                    Emit(RegexCode.Goto, 0);
                }
                PushInt(CurPos());
                break;

            case RegexNode.Loop | AfterChild:
            case RegexNode.Lazyloop | AfterChild: {
                int StartJumpPos = CurPos();
                int Lazy         = (nodetype - (RegexNode.Loop | AfterChild));

                if (node._n < infinite || node._m > 1)
                {
                    Emit(RegexCode.Branchcount + Lazy, PopInt(), node._n == infinite ? infinite : node._n - node._m);
                }
                else
                {
                    Emit(RegexCode.Branchmark + Lazy, PopInt());
                }

                if (node._m == 0)
                {
                    PatchJump(PopInt(), StartJumpPos);
                }
            }
            break;

            case RegexNode.Group | BeforeChild:
            case RegexNode.Group | AfterChild:
                break;

            case RegexNode.Capture | BeforeChild:
                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Capture | AfterChild:
                Emit(RegexCode.Capturemark, MapCapnum(node._m), MapCapnum(node._n));
                break;

            case RegexNode.Require | BeforeChild:
                // NOTE: the following line causes lookahead/lookbehind to be
                // NON-BACKTRACKING. It can be commented out with (*)
                Emit(RegexCode.Setjump);


                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Require | AfterChild:
                Emit(RegexCode.Getmark);

                // NOTE: the following line causes lookahead/lookbehind to be
                // NON-BACKTRACKING. It can be commented out with (*)
                Emit(RegexCode.Forejump);

                break;

            case RegexNode.Prevent | BeforeChild:
                Emit(RegexCode.Setjump);
                PushInt(CurPos());
                Emit(RegexCode.Lazybranch, 0);
                break;

            case RegexNode.Prevent | AfterChild:
                Emit(RegexCode.Backjump);
                PatchJump(PopInt(), CurPos());
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.Greedy | BeforeChild:
                Emit(RegexCode.Setjump);
                break;

            case RegexNode.Greedy | AfterChild:
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.One:
            case RegexNode.Notone:
                Emit(node._type | bits, (int)node._ch);
                break;

            case RegexNode.Notoneloop:
            case RegexNode.Notonelazy:
            case RegexNode.Oneloop:
            case RegexNode.Onelazy:
                if (node._m > 0)
                {
                    Emit(((node._type == RegexNode.Oneloop || node._type == RegexNode.Onelazy) ?
                          RegexCode.Onerep : RegexCode.Notonerep) | bits, (int)node._ch, node._m);
                }
                if (node._n > node._m)
                {
                    Emit(node._type | bits, (int)node._ch, node._n == infinite ?
                         infinite : node._n - node._m);
                }
                break;

            case RegexNode.Setloop:
            case RegexNode.Setlazy:
                if (node._m > 0)
                {
                    Emit(RegexCode.Setrep | bits, StringCode(node._str), StringCode(node._str2), node._m);
                }
                if (node._n > node._m)
                {
                    Emit(node._type | bits, StringCode(node._str), StringCode(node._str2),
                         (node._n == infinite) ? infinite : node._n - node._m);
                }
                break;

            case RegexNode.Multi:
                Emit(node._type | bits, StringCode(node._str));
                break;

            case RegexNode.Set:
                Emit(node._type | bits, StringCode(node._str), StringCode(node._str2));
                break;

            case RegexNode.Ref:
                Emit(node._type | bits, MapCapnum(node._m));
                break;

            case RegexNode.Nothing:
            case RegexNode.Bol:
            case RegexNode.Eol:
            case RegexNode.Boundary:
            case RegexNode.Nonboundary:
#if ECMA
            case RegexNode.ECMABoundary:
            case RegexNode.NonECMABoundary:
#endif
            case RegexNode.Beginning:
            case RegexNode.Start:
            case RegexNode.EndZ:
            case RegexNode.End:
                Emit(node._type);
                break;

            default:
                throw MakeException(SR.GetString(SR.UnexpectedOpcode, nodetype.ToString()));
            }
        }
Beispiel #3
0
        /// <summary>
        /// The main RegexCode generator. It does a depth-first walk
        /// through the tree and calls EmitFragment to emits code before
        /// and after each child of an interior node, and at each leaf.
        /// </summary>
        private void EmitFragment(int nodetype, RegexNode node, int curIndex)
        {
            int bits = 0;

            if (nodetype <= RegexNode.Ref)
            {
                if (node.UseOptionR())
                {
                    bits |= RegexCode.Rtl;
                }
                if ((node.Options & RegexOptions.IgnoreCase) != 0)
                {
                    bits |= RegexCode.Ci;
                }
            }

            switch (nodetype)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Concatenate | AfterChild:
            case RegexNode.Empty:
                break;

            case RegexNode.Alternate | BeforeChild:
                if (curIndex < node.Children.Count - 1)
                {
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                }
                break;

            case RegexNode.Alternate | AfterChild:
            {
                if (curIndex < node.Children.Count - 1)
                {
                    int LBPos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(LBPos, _emitted.Length);
                }
                else
                {
                    int I;
                    for (I = 0; I < curIndex; I++)
                    {
                        PatchJump(_intStack.Pop(), _emitted.Length);
                    }
                }
                break;
            }

            case RegexNode.Testref | BeforeChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                    Emit(RegexCode.Testref, MapCapnum(node.M));
                    Emit(RegexCode.Forejump);
                    break;
                }
                break;

            case RegexNode.Testref | AfterChild:
                switch (curIndex)
                {
                case 0:
                {
                    int Branchpos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, _emitted.Length);
                    Emit(RegexCode.Forejump);
                    if (node.Children.Count > 1)
                    {
                        break;
                    }
                    // else fallthrough
                    goto case 1;
                }

                case 1:
                    PatchJump(_intStack.Pop(), _emitted.Length);
                    break;
                }
                break;

            case RegexNode.Testgroup | BeforeChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    Emit(RegexCode.Setmark);
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                    break;
                }
                break;

            case RegexNode.Testgroup | AfterChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);
                    break;

                case 1:
                    int Branchpos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, _emitted.Length);
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);

                    if (node.Children.Count > 2)
                    {
                        break;
                    }
                    // else fallthrough
                    goto case 2;

                case 2:
                    PatchJump(_intStack.Pop(), _emitted.Length);
                    break;
                }
                break;

            case RegexNode.Loop | BeforeChild:
            case RegexNode.Lazyloop | BeforeChild:

                if (node.N < int.MaxValue || node.M > 1)
                {
                    Emit(node.M == 0 ? RegexCode.Nullcount : RegexCode.Setcount, node.M == 0 ? 0 : 1 - node.M);
                }
                else
                {
                    Emit(node.M == 0 ? RegexCode.Nullmark : RegexCode.Setmark);
                }

                if (node.M == 0)
                {
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                }
                _intStack.Append(_emitted.Length);
                break;

            case RegexNode.Loop | AfterChild:
            case RegexNode.Lazyloop | AfterChild:
            {
                int StartJumpPos = _emitted.Length;
                int Lazy         = (nodetype - (RegexNode.Loop | AfterChild));

                if (node.N < int.MaxValue || node.M > 1)
                {
                    Emit(RegexCode.Branchcount + Lazy, _intStack.Pop(), node.N == int.MaxValue ? int.MaxValue : node.N - node.M);
                }
                else
                {
                    Emit(RegexCode.Branchmark + Lazy, _intStack.Pop());
                }

                if (node.M == 0)
                {
                    PatchJump(_intStack.Pop(), StartJumpPos);
                }
            }
            break;

            case RegexNode.Group | BeforeChild:
            case RegexNode.Group | AfterChild:
                break;

            case RegexNode.Capture | BeforeChild:
                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Capture | AfterChild:
                Emit(RegexCode.Capturemark, MapCapnum(node.M), MapCapnum(node.N));
                break;

            case RegexNode.Require | BeforeChild:
                // NOTE: the following line causes lookahead/lookbehind to be
                // NON-BACKTRACKING. It can be commented out with (*)
                Emit(RegexCode.Setjump);


                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Require | AfterChild:
                Emit(RegexCode.Getmark);

                // NOTE: the following line causes lookahead/lookbehind to be
                // NON-BACKTRACKING. It can be commented out with (*)
                Emit(RegexCode.Forejump);

                break;

            case RegexNode.Prevent | BeforeChild:
                Emit(RegexCode.Setjump);
                _intStack.Append(_emitted.Length);
                Emit(RegexCode.Lazybranch, 0);
                break;

            case RegexNode.Prevent | AfterChild:
                Emit(RegexCode.Backjump);
                PatchJump(_intStack.Pop(), _emitted.Length);
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.Greedy | BeforeChild:
                Emit(RegexCode.Setjump);
                break;

            case RegexNode.Greedy | AfterChild:
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.One:
            case RegexNode.Notone:
                Emit(node.NType | bits, node.Ch);
                break;

            case RegexNode.Notoneloop:
            case RegexNode.Notonelazy:
            case RegexNode.Oneloop:
            case RegexNode.Onelazy:
                if (node.M > 0)
                {
                    Emit(((node.NType == RegexNode.Oneloop || node.NType == RegexNode.Onelazy) ?
                          RegexCode.Onerep : RegexCode.Notonerep) | bits, node.Ch, node.M);
                }
                if (node.N > node.M)
                {
                    Emit(node.NType | bits, node.Ch, node.N == int.MaxValue ?
                         int.MaxValue : node.N - node.M);
                }
                break;

            case RegexNode.Setloop:
            case RegexNode.Setlazy:
                if (node.M > 0)
                {
                    Emit(RegexCode.Setrep | bits, StringCode(node.Str), node.M);
                }
                if (node.N > node.M)
                {
                    Emit(node.NType | bits, StringCode(node.Str),
                         (node.N == int.MaxValue) ? int.MaxValue : node.N - node.M);
                }
                break;

            case RegexNode.Multi:
                Emit(node.NType | bits, StringCode(node.Str));
                break;

            case RegexNode.Set:
                Emit(node.NType | bits, StringCode(node.Str));
                break;

            case RegexNode.Ref:
                Emit(node.NType | bits, MapCapnum(node.M));
                break;

            case RegexNode.Nothing:
            case RegexNode.Bol:
            case RegexNode.Eol:
            case RegexNode.Boundary:
            case RegexNode.Nonboundary:
            case RegexNode.ECMABoundary:
            case RegexNode.NonECMABoundary:
            case RegexNode.Beginning:
            case RegexNode.Start:
            case RegexNode.EndZ:
            case RegexNode.End:
                Emit(node.NType);
                break;

            default:
                throw new ArgumentException(SR.Format(SR.UnexpectedOpcode, nodetype.ToString(CultureInfo.CurrentCulture)));
            }
        }
Beispiel #4
0
        /// <summary>
        /// The main RegexCode generator. It does a depth-first walk
        /// through the tree and calls EmitFragment to emits code before
        /// and after each child of an interior node, and at each leaf.
        /// </summary>
        private void EmitFragment(int nodetype, RegexNode node, int curIndex)
        {
            int bits = 0;

            if (nodetype <= RegexNode.Ref)
            {
                if (node.UseOptionR())
                    bits |= RegexCode.Rtl;
                if ((node._options & RegexOptions.IgnoreCase) != 0)
                    bits |= RegexCode.Ci;
            }

            switch (nodetype)
            {
                case RegexNode.Concatenate | BeforeChild:
                case RegexNode.Concatenate | AfterChild:
                case RegexNode.Empty:
                    break;

                case RegexNode.Alternate | BeforeChild:
                    if (curIndex < node._children.Count - 1)
                    {
                        PushInt(CurPos());
                        Emit(RegexCode.Lazybranch, 0);
                    }
                    break;

                case RegexNode.Alternate | AfterChild:
                    {
                        if (curIndex < node._children.Count - 1)
                        {
                            int LBPos = PopInt();
                            PushInt(CurPos());
                            Emit(RegexCode.Goto, 0);
                            PatchJump(LBPos, CurPos());
                        }
                        else
                        {
                            int I;
                            for (I = 0; I < curIndex; I++)
                            {
                                PatchJump(PopInt(), CurPos());
                            }
                        }
                        break;
                    }

                case RegexNode.Testref | BeforeChild:
                    switch (curIndex)
                    {
                        case 0:
                            Emit(RegexCode.Setjump);
                            PushInt(CurPos());
                            Emit(RegexCode.Lazybranch, 0);
                            Emit(RegexCode.Testref, MapCapnum(node._m));
                            Emit(RegexCode.Forejump);
                            break;
                    }
                    break;

                case RegexNode.Testref | AfterChild:
                    switch (curIndex)
                    {
                        case 0:
                            {
                                int Branchpos = PopInt();
                                PushInt(CurPos());
                                Emit(RegexCode.Goto, 0);
                                PatchJump(Branchpos, CurPos());
                                Emit(RegexCode.Forejump);
                                if (node._children.Count > 1)
                                    break;
                                // else fallthrough
                                goto case 1;
                            }
                        case 1:
                            PatchJump(PopInt(), CurPos());
                            break;
                    }
                    break;

                case RegexNode.Testgroup | BeforeChild:
                    switch (curIndex)
                    {
                        case 0:
                            Emit(RegexCode.Setjump);
                            Emit(RegexCode.Setmark);
                            PushInt(CurPos());
                            Emit(RegexCode.Lazybranch, 0);
                            break;
                    }
                    break;

                case RegexNode.Testgroup | AfterChild:
                    switch (curIndex)
                    {
                        case 0:
                            Emit(RegexCode.Getmark);
                            Emit(RegexCode.Forejump);
                            break;
                        case 1:
                            int Branchpos = PopInt();
                            PushInt(CurPos());
                            Emit(RegexCode.Goto, 0);
                            PatchJump(Branchpos, CurPos());
                            Emit(RegexCode.Getmark);
                            Emit(RegexCode.Forejump);

                            if (node._children.Count > 2)
                                break;
                            // else fallthrough
                            goto case 2;
                        case 2:
                            PatchJump(PopInt(), CurPos());
                            break;
                    }
                    break;

                case RegexNode.Loop | BeforeChild:
                case RegexNode.Lazyloop | BeforeChild:

                    if (node._n < Int32.MaxValue || node._m > 1)
                        Emit(node._m == 0 ? RegexCode.Nullcount : RegexCode.Setcount, node._m == 0 ? 0 : 1 - node._m);
                    else
                        Emit(node._m == 0 ? RegexCode.Nullmark : RegexCode.Setmark);

                    if (node._m == 0)
                    {
                        PushInt(CurPos());
                        Emit(RegexCode.Goto, 0);
                    }
                    PushInt(CurPos());
                    break;

                case RegexNode.Loop | AfterChild:
                case RegexNode.Lazyloop | AfterChild:
                    {
                        int StartJumpPos = CurPos();
                        int Lazy = (nodetype - (RegexNode.Loop | AfterChild));

                        if (node._n < Int32.MaxValue || node._m > 1)
                            Emit(RegexCode.Branchcount + Lazy, PopInt(), node._n == Int32.MaxValue ? Int32.MaxValue : node._n - node._m);
                        else
                            Emit(RegexCode.Branchmark + Lazy, PopInt());

                        if (node._m == 0)
                            PatchJump(PopInt(), StartJumpPos);
                    }
                    break;

                case RegexNode.Group | BeforeChild:
                case RegexNode.Group | AfterChild:
                    break;

                case RegexNode.Capture | BeforeChild:
                    Emit(RegexCode.Setmark);
                    break;

                case RegexNode.Capture | AfterChild:
                    Emit(RegexCode.Capturemark, MapCapnum(node._m), MapCapnum(node._n));
                    break;

                case RegexNode.Require | BeforeChild:
                    // NOTE: the following line causes lookahead/lookbehind to be
                    // NON-BACKTRACKING. It can be commented out with (*)
                    Emit(RegexCode.Setjump);


                    Emit(RegexCode.Setmark);
                    break;

                case RegexNode.Require | AfterChild:
                    Emit(RegexCode.Getmark);

                    // NOTE: the following line causes lookahead/lookbehind to be
                    // NON-BACKTRACKING. It can be commented out with (*)
                    Emit(RegexCode.Forejump);

                    break;

                case RegexNode.Prevent | BeforeChild:
                    Emit(RegexCode.Setjump);
                    PushInt(CurPos());
                    Emit(RegexCode.Lazybranch, 0);
                    break;

                case RegexNode.Prevent | AfterChild:
                    Emit(RegexCode.Backjump);
                    PatchJump(PopInt(), CurPos());
                    Emit(RegexCode.Forejump);
                    break;

                case RegexNode.Greedy | BeforeChild:
                    Emit(RegexCode.Setjump);
                    break;

                case RegexNode.Greedy | AfterChild:
                    Emit(RegexCode.Forejump);
                    break;

                case RegexNode.One:
                case RegexNode.Notone:
                    Emit(node._type | bits, (int)node._ch);
                    break;

                case RegexNode.Notoneloop:
                case RegexNode.Notonelazy:
                case RegexNode.Oneloop:
                case RegexNode.Onelazy:
                    if (node._m > 0)
                        Emit(((node._type == RegexNode.Oneloop || node._type == RegexNode.Onelazy) ?
                              RegexCode.Onerep : RegexCode.Notonerep) | bits, (int)node._ch, node._m);
                    if (node._n > node._m)
                        Emit(node._type | bits, (int)node._ch, node._n == Int32.MaxValue ?
                             Int32.MaxValue : node._n - node._m);
                    break;

                case RegexNode.Setloop:
                case RegexNode.Setlazy:
                    if (node._m > 0)
                        Emit(RegexCode.Setrep | bits, StringCode(node._str), node._m);
                    if (node._n > node._m)
                        Emit(node._type | bits, StringCode(node._str),
                             (node._n == Int32.MaxValue) ? Int32.MaxValue : node._n - node._m);
                    break;

                case RegexNode.Multi:
                    Emit(node._type | bits, StringCode(node._str));
                    break;

                case RegexNode.Set:
                    Emit(node._type | bits, StringCode(node._str));
                    break;

                case RegexNode.Ref:
                    Emit(node._type | bits, MapCapnum(node._m));
                    break;

                case RegexNode.Nothing:
                case RegexNode.Bol:
                case RegexNode.Eol:
                case RegexNode.Boundary:
                case RegexNode.Nonboundary:
                case RegexNode.ECMABoundary:
                case RegexNode.NonECMABoundary:
                case RegexNode.Beginning:
                case RegexNode.Start:
                case RegexNode.EndZ:
                case RegexNode.End:
                    Emit(node._type);
                    break;

                default:
                    throw new ArgumentException(SR.Format(SR.UnexpectedOpcode, nodetype.ToString(CultureInfo.CurrentCulture)));
            }
        }
Beispiel #5
0
        internal void EmitFragment(int nodetype, RegexNode node, int CurIndex)
        {
            int num = 0;

            if (nodetype <= 13)
            {
                if (node.UseOptionR())
                {
                    num |= 0x40;
                }
                if ((node._options & RegexOptions.IgnoreCase) != RegexOptions.None)
                {
                    num |= 0x200;
                }
            }
            int num8 = nodetype;

            switch (num8)
            {
            case 3:
            case 4:
            case 6:
            case 7:
                if (node._m > 0)
                {
                    this.Emit((((node._type == 3) || (node._type == 6)) ? 0 : 1) | num, node._ch, node._m);
                }
                if (node._n > node._m)
                {
                    this.Emit(node._type | num, node._ch, (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                }
                return;

            case 5:
            case 8:
                if (node._m > 0)
                {
                    this.Emit(2 | num, this.StringCode(node._str), this.StringCode(node._str2), node._m);
                }
                if (node._n > node._m)
                {
                    this.Emit(node._type | num, this.StringCode(node._str), this.StringCode(node._str2), (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                }
                return;

            case 9:
            case 10:
                this.Emit(node._type | num, node._ch);
                return;

            case 11:
                this.Emit(node._type | num, this.StringCode(node._str), this.StringCode(node._str2));
                return;

            case 12:
                this.Emit(node._type | num, this.StringCode(node._str));
                return;

            case 13:
                this.Emit(node._type | num, this.MapCapnum(node._m));
                return;

            case 14:
            case 15:
            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
            case 20:
            case 0x15:
            case 0x16:
            case 0x29:
            case 0x2a:
                this.Emit(node._type);
                return;

            case 0x17:
            case 0x59:
            case 0x5d:
            case 0x99:
            case 0x9d:
                return;

            case 0x58:
                if (CurIndex < (node._children.Count - 1))
                {
                    this.PushInt(this.CurPos());
                    this.Emit(0x17, 0);
                }
                return;

            case 90:
            case 0x5b:
                if ((node._n >= 0x7fffffff) && (node._m <= 1))
                {
                    this.Emit((node._m == 0) ? 30 : 0x1f);
                }
                else
                {
                    this.Emit((node._m == 0) ? 0x1a : 0x1b, (node._m == 0) ? 0 : (1 - node._m));
                }
                if (node._m == 0)
                {
                    this.PushInt(this.CurPos());
                    this.Emit(0x26, 0);
                }
                this.PushInt(this.CurPos());
                return;

            case 0x5c:
                this.Emit(0x1f);
                return;

            case 0x5e:
                this.Emit(0x22);
                this.Emit(0x1f);
                return;

            case 0x5f:
                this.Emit(0x22);
                this.PushInt(this.CurPos());
                this.Emit(0x17, 0);
                return;

            case 0x60:
                this.Emit(0x22);
                return;

            case 0x61:
                num8 = CurIndex;
                if (num8 == 0)
                {
                    this.Emit(0x22);
                    this.PushInt(this.CurPos());
                    this.Emit(0x17, 0);
                    this.Emit(0x25, this.MapCapnum(node._m));
                    this.Emit(0x24);
                    return;
                }
                return;

            case 0x62:
                num8 = CurIndex;
                if (num8 == 0)
                {
                    this.Emit(0x22);
                    this.Emit(0x1f);
                    this.PushInt(this.CurPos());
                    this.Emit(0x17, 0);
                    return;
                }
                return;

            case 0x98:
            {
                if (CurIndex >= (node._children.Count - 1))
                {
                    for (int i = 0; i < CurIndex; i++)
                    {
                        this.PatchJump(this.PopInt(), this.CurPos());
                    }
                    return;
                }
                int offset = this.PopInt();
                this.PushInt(this.CurPos());
                this.Emit(0x26, 0);
                this.PatchJump(offset, this.CurPos());
                return;
            }

            case 0x9a:
            case 0x9b:
            {
                int jumpDest = this.CurPos();
                int num7     = nodetype - 0x9a;
                if ((node._n >= 0x7fffffff) && (node._m <= 1))
                {
                    this.Emit(0x18 + num7, this.PopInt());
                }
                else
                {
                    this.Emit(0x1c + num7, this.PopInt(), (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                }
                if (node._m == 0)
                {
                    this.PatchJump(this.PopInt(), jumpDest);
                }
                return;
            }

            case 0x9c:
                this.Emit(0x20, this.MapCapnum(node._m), this.MapCapnum(node._n));
                return;

            case 0x9e:
                this.Emit(0x21);
                this.Emit(0x24);
                return;

            case 0x9f:
                this.Emit(0x23);
                this.PatchJump(this.PopInt(), this.CurPos());
                this.Emit(0x24);
                return;

            case 160:
                this.Emit(0x24);
                return;

            case 0xa1:
                switch (CurIndex)
                {
                case 0:
                {
                    int num4 = this.PopInt();
                    this.PushInt(this.CurPos());
                    this.Emit(0x26, 0);
                    this.PatchJump(num4, this.CurPos());
                    this.Emit(0x24);
                    if (node._children.Count > 1)
                    {
                        return;
                    }
                    break;
                }
                }
                return;

            case 0xa2:
                switch (CurIndex)
                {
                case 0:
                    this.Emit(0x21);
                    this.Emit(0x24);
                    return;

                case 1:
                {
                    int num5 = this.PopInt();
                    this.PushInt(this.CurPos());
                    this.Emit(0x26, 0);
                    this.PatchJump(num5, this.CurPos());
                    this.Emit(0x21);
                    this.Emit(0x24);
                    if (node._children.Count > 2)
                    {
                        return;
                    }
                    goto Label_0312;
                }

                case 2:
                    goto Label_0312;
                }
                return;

            default:
                throw MakeException(RegExRes.GetString(4, nodetype.ToString()));
            }
            this.PatchJump(this.PopInt(), this.CurPos());
            return;

Label_0312:
            this.PatchJump(this.PopInt(), this.CurPos());
        }
        internal void EmitFragment(int nodetype, RegexNode node, int CurIndex)
        {
            int num = 0;
            if (nodetype <= 13)
            {
                if (node.UseOptionR())
                {
                    num |= 0x40;
                }
                if ((node._options & RegexOptions.IgnoreCase) != RegexOptions.None)
                {
                    num |= 0x200;
                }
            }
            int num8 = nodetype;
            switch (num8)
            {
                case 3:
                case 4:
                case 6:
                case 7:
                    if (node._m > 0)
                    {
                        this.Emit((((node._type == 3) || (node._type == 6)) ? 0 : 1) | num, node._ch, node._m);
                    }
                    if (node._n > node._m)
                    {
                        this.Emit(node._type | num, node._ch, (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                    }
                    return;

                case 5:
                case 8:
                    if (node._m > 0)
                    {
                        this.Emit(2 | num, this.StringCode(node._str), this.StringCode(node._str2), node._m);
                    }
                    if (node._n > node._m)
                    {
                        this.Emit(node._type | num, this.StringCode(node._str), this.StringCode(node._str2), (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                    }
                    return;

                case 9:
                case 10:
                    this.Emit(node._type | num, node._ch);
                    return;

                case 11:
                    this.Emit(node._type | num, this.StringCode(node._str), this.StringCode(node._str2));
                    return;

                case 12:
                    this.Emit(node._type | num, this.StringCode(node._str));
                    return;

                case 13:
                    this.Emit(node._type | num, this.MapCapnum(node._m));
                    return;

                case 14:
                case 15:
                case 0x10:
                case 0x11:
                case 0x12:
                case 0x13:
                case 20:
                case 0x15:
                case 0x16:
                case 0x29:
                case 0x2a:
                    this.Emit(node._type);
                    return;

                case 0x17:
                case 0x59:
                case 0x5d:
                case 0x99:
                case 0x9d:
                    return;

                case 0x58:
                    if (CurIndex < (node._children.Count - 1))
                    {
                        this.PushInt(this.CurPos());
                        this.Emit(0x17, 0);
                    }
                    return;

                case 90:
                case 0x5b:
                    if ((node._n >= 0x7fffffff) && (node._m <= 1))
                    {
                        this.Emit((node._m == 0) ? 30 : 0x1f);
                    }
                    else
                    {
                        this.Emit((node._m == 0) ? 0x1a : 0x1b, (node._m == 0) ? 0 : (1 - node._m));
                    }
                    if (node._m == 0)
                    {
                        this.PushInt(this.CurPos());
                        this.Emit(0x26, 0);
                    }
                    this.PushInt(this.CurPos());
                    return;

                case 0x5c:
                    this.Emit(0x1f);
                    return;

                case 0x5e:
                    this.Emit(0x22);
                    this.Emit(0x1f);
                    return;

                case 0x5f:
                    this.Emit(0x22);
                    this.PushInt(this.CurPos());
                    this.Emit(0x17, 0);
                    return;

                case 0x60:
                    this.Emit(0x22);
                    return;

                case 0x61:
                    num8 = CurIndex;
                    if (num8 == 0)
                    {
                        this.Emit(0x22);
                        this.PushInt(this.CurPos());
                        this.Emit(0x17, 0);
                        this.Emit(0x25, this.MapCapnum(node._m));
                        this.Emit(0x24);
                        return;
                    }
                    return;

                case 0x62:
                    num8 = CurIndex;
                    if (num8 == 0)
                    {
                        this.Emit(0x22);
                        this.Emit(0x1f);
                        this.PushInt(this.CurPos());
                        this.Emit(0x17, 0);
                        return;
                    }
                    return;

                case 0x98:
                {
                    if (CurIndex >= (node._children.Count - 1))
                    {
                        for (int i = 0; i < CurIndex; i++)
                        {
                            this.PatchJump(this.PopInt(), this.CurPos());
                        }
                        return;
                    }
                    int offset = this.PopInt();
                    this.PushInt(this.CurPos());
                    this.Emit(0x26, 0);
                    this.PatchJump(offset, this.CurPos());
                    return;
                }
                case 0x9a:
                case 0x9b:
                {
                    int jumpDest = this.CurPos();
                    int num7 = nodetype - 0x9a;
                    if ((node._n >= 0x7fffffff) && (node._m <= 1))
                    {
                        this.Emit(0x18 + num7, this.PopInt());
                    }
                    else
                    {
                        this.Emit(0x1c + num7, this.PopInt(), (node._n == 0x7fffffff) ? 0x7fffffff : (node._n - node._m));
                    }
                    if (node._m == 0)
                    {
                        this.PatchJump(this.PopInt(), jumpDest);
                    }
                    return;
                }
                case 0x9c:
                    this.Emit(0x20, this.MapCapnum(node._m), this.MapCapnum(node._n));
                    return;

                case 0x9e:
                    this.Emit(0x21);
                    this.Emit(0x24);
                    return;

                case 0x9f:
                    this.Emit(0x23);
                    this.PatchJump(this.PopInt(), this.CurPos());
                    this.Emit(0x24);
                    return;

                case 160:
                    this.Emit(0x24);
                    return;

                case 0xa1:
                    switch (CurIndex)
                    {
                        case 0:
                        {
                            int num4 = this.PopInt();
                            this.PushInt(this.CurPos());
                            this.Emit(0x26, 0);
                            this.PatchJump(num4, this.CurPos());
                            this.Emit(0x24);
                            if (node._children.Count > 1)
                            {
                                return;
                            }
                            break;
                        }
                    }
                    return;

                case 0xa2:
                    switch (CurIndex)
                    {
                        case 0:
                            this.Emit(0x21);
                            this.Emit(0x24);
                            return;

                        case 1:
                        {
                            int num5 = this.PopInt();
                            this.PushInt(this.CurPos());
                            this.Emit(0x26, 0);
                            this.PatchJump(num5, this.CurPos());
                            this.Emit(0x21);
                            this.Emit(0x24);
                            if (node._children.Count > 2)
                            {
                                return;
                            }
                            goto Label_0312;
                        }
                        case 2:
                            goto Label_0312;
                    }
                    return;

                default:
                    throw MakeException(RegExRes.GetString(4, nodetype.ToString()));
            }
            this.PatchJump(this.PopInt(), this.CurPos());
            return;
            Label_0312:
            this.PatchJump(this.PopInt(), this.CurPos());
        }
Beispiel #7
0
        /// <summary>
        /// The main RegexCode generator. It does a depth-first walk
        /// through the tree and calls EmitFragment to emits code before
        /// and after each child of an interior node, and at each leaf.
        /// </summary>
        private void EmitFragment(int nodetype, RegexNode node, int curIndex)
        {
            int bits = 0;

            if (node.UseOptionR())
            {
                bits |= RegexCode.Rtl;
            }
            if ((node.Options & RegexOptions.IgnoreCase) != 0)
            {
                bits |= RegexCode.Ci;
            }

            switch (nodetype)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Concatenate | AfterChild:
            case RegexNode.Empty:
                break;

            case RegexNode.Alternate | BeforeChild:
                if (curIndex < node.ChildCount() - 1)
                {
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                }
                break;

            case RegexNode.Alternate | AfterChild:
            {
                if (curIndex < node.ChildCount() - 1)
                {
                    int lazyBranchPos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(lazyBranchPos, _emitted.Length);
                }
                else
                {
                    for (int i = 0; i < curIndex; i++)
                    {
                        PatchJump(_intStack.Pop(), _emitted.Length);
                    }
                }
                break;
            }

            case RegexNode.Testref | BeforeChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                    Emit(RegexCode.Testref, MapCapnum(node.M));
                    Emit(RegexCode.Forejump);
                    break;
                }
                break;

            case RegexNode.Testref | AfterChild:
                switch (curIndex)
                {
                case 0:
                {
                    int Branchpos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, _emitted.Length);
                    Emit(RegexCode.Forejump);
                    if (node.ChildCount() > 1)
                    {
                        break;
                    }

                    // else fallthrough
                    goto case 1;
                }

                case 1:
                    PatchJump(_intStack.Pop(), _emitted.Length);
                    break;
                }
                break;

            case RegexNode.Testgroup | BeforeChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Setjump);
                    Emit(RegexCode.Setmark);
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Lazybranch, 0);
                    break;
                }
                break;

            case RegexNode.Testgroup | AfterChild:
                switch (curIndex)
                {
                case 0:
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);
                    break;

                case 1:
                    int Branchpos = _intStack.Pop();
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                    PatchJump(Branchpos, _emitted.Length);
                    Emit(RegexCode.Getmark);
                    Emit(RegexCode.Forejump);

                    if (node.ChildCount() > 2)
                    {
                        break;
                    }
                    // else fallthrough
                    goto case 2;

                case 2:
                    PatchJump(_intStack.Pop(), _emitted.Length);
                    break;
                }
                break;

            case RegexNode.Loop | BeforeChild:
            case RegexNode.Lazyloop | BeforeChild:

                if (node.N < int.MaxValue || node.M > 1)
                {
                    Emit(node.M == 0 ? RegexCode.Nullcount : RegexCode.Setcount, node.M == 0 ? 0 : 1 - node.M);
                }
                else
                {
                    Emit(node.M == 0 ? RegexCode.Nullmark : RegexCode.Setmark);
                }

                if (node.M == 0)
                {
                    _intStack.Append(_emitted.Length);
                    Emit(RegexCode.Goto, 0);
                }
                _intStack.Append(_emitted.Length);
                break;

            case RegexNode.Loop | AfterChild:
            case RegexNode.Lazyloop | AfterChild:
            {
                int StartJumpPos = _emitted.Length;
                int Lazy         = (nodetype - (RegexNode.Loop | AfterChild));

                if (node.N < int.MaxValue || node.M > 1)
                {
                    Emit(RegexCode.Branchcount + Lazy, _intStack.Pop(), node.N == int.MaxValue ? int.MaxValue : node.N - node.M);
                }
                else
                {
                    Emit(RegexCode.Branchmark + Lazy, _intStack.Pop());
                }

                if (node.M == 0)
                {
                    PatchJump(_intStack.Pop(), StartJumpPos);
                }
            }
            break;

            case RegexNode.Group | BeforeChild:
            case RegexNode.Group | AfterChild:
                break;

            case RegexNode.Capture | BeforeChild:
                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Capture | AfterChild:
                Emit(RegexCode.Capturemark, MapCapnum(node.M), MapCapnum(node.N));
                break;

            case RegexNode.Require | BeforeChild:
                Emit(RegexCode.Setjump);     // causes lookahead/lookbehind to be non-backtracking
                Emit(RegexCode.Setmark);
                break;

            case RegexNode.Require | AfterChild:
                Emit(RegexCode.Getmark);
                Emit(RegexCode.Forejump);     // causes lookahead/lookbehind to be non-backtracking
                break;

            case RegexNode.Prevent | BeforeChild:
                Emit(RegexCode.Setjump);
                _intStack.Append(_emitted.Length);
                Emit(RegexCode.Lazybranch, 0);
                break;

            case RegexNode.Prevent | AfterChild:
                Emit(RegexCode.Backjump);
                PatchJump(_intStack.Pop(), _emitted.Length);
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.Atomic | BeforeChild:
                Emit(RegexCode.Setjump);
                break;

            case RegexNode.Atomic | AfterChild:
                Emit(RegexCode.Forejump);
                break;

            case RegexNode.One:
            case RegexNode.Notone:
                Emit(node.Type | bits, node.Ch);
                break;

            case RegexNode.Notoneloop:
            case RegexNode.Notoneloopatomic:
            case RegexNode.Notonelazy:
            case RegexNode.Oneloop:
            case RegexNode.Oneloopatomic:
            case RegexNode.Onelazy:
                if (node.M > 0)
                {
                    Emit(((node.Type == RegexNode.Oneloop || node.Type == RegexNode.Oneloopatomic || node.Type == RegexNode.Onelazy) ?
                          RegexCode.Onerep : RegexCode.Notonerep) | bits, node.Ch, node.M);
                }
                if (node.N > node.M)
                {
                    Emit(node.Type | bits, node.Ch, node.N == int.MaxValue ? int.MaxValue : node.N - node.M);
                }
                break;

            case RegexNode.Setloop:
            case RegexNode.Setloopatomic:
            case RegexNode.Setlazy:
            {
                int stringCode = StringCode(node.Str !);
                if (node.M > 0)
                {
                    Emit(RegexCode.Setrep | bits, stringCode, node.M);
                }
                if (node.N > node.M)
                {
                    Emit(node.Type | bits, stringCode, (node.N == int.MaxValue) ? int.MaxValue : node.N - node.M);
                }
            }
            break;

            case RegexNode.Multi:
                Emit(node.Type | bits, StringCode(node.Str !));
                break;

            case RegexNode.Set:
                Emit(node.Type | bits, StringCode(node.Str !));
                break;

            case RegexNode.Ref:
                Emit(node.Type | bits, MapCapnum(node.M));
                break;

            case RegexNode.Nothing:
            case RegexNode.Bol:
            case RegexNode.Eol:
            case RegexNode.Boundary:
            case RegexNode.Nonboundary:
            case RegexNode.ECMABoundary:
            case RegexNode.NonECMABoundary:
            case RegexNode.Beginning:
            case RegexNode.Start:
            case RegexNode.EndZ:
            case RegexNode.End:
                Emit(node.Type);
                break;

            default:
                throw new ArgumentException(SR.Format(SR.UnexpectedOpcode, nodetype.ToString()));
            }
        }