Beispiel #1
0
        internal bool AddFC(RegexFC fc, bool concatenate)
        {
            if (!_cc.CanMerge || !fc._cc.CanMerge)
            {
                return(false);
            }

            if (concatenate)
            {
                if (!_nullable)
                {
                    return(true);
                }

                if (!fc._nullable)
                {
                    _nullable = false;
                }
            }
            else
            {
                if (fc._nullable)
                {
                    _nullable = true;
                }
            }

            _caseInsensitive |= fc._caseInsensitive;
            _cc.AddCharClass(fc._cc);
            return(true);
        }
Beispiel #2
0
        internal void AddFC(RegexFC fc, bool concatenate)
        {
            if (concatenate)
            {
                if (!_nullable)
                {
                    return;
                }

                if (!fc._nullable)
                {
                    _nullable = false;
                }
            }
            else
            {
                if (fc._nullable)
                {
                    _nullable = true;
                }
            }

            _caseInsensitive |= fc._caseInsensitive;
            _cc.AddCharClass(fc._cc);
        }
 internal bool AddFC(RegexFC fc, bool concatenate)
 {
     if (!this._cc.CanMerge || !fc._cc.CanMerge)
     {
         return false;
     }
     if (concatenate)
     {
         if (!this._nullable)
         {
             return true;
         }
         if (!fc._nullable)
         {
             this._nullable = false;
         }
     }
     else if (fc._nullable)
     {
         this._nullable = true;
     }
     this._caseInsensitive |= fc._caseInsensitive;
     this._cc.AddCharClass(fc._cc);
     return true;
 }
Beispiel #4
0
        private RegexFC PopFC()
        {
            RegexFC item = TopFC();

            _fcStack.RemoveAt(_fcStack.Count - 1);

            return(item);
        }
Beispiel #5
0
 private void PushFC(RegexFC fc)
 {
     if (this._fcDepth >= this._fcStack.Length)
     {
         RegexFC[] destinationArray = new RegexFC[this._fcDepth * 2];
         Array.Copy(this._fcStack, 0, destinationArray, 0, this._fcDepth);
         this._fcStack = destinationArray;
     }
     this._fcStack[this._fcDepth++] = fc;
 }
Beispiel #6
0
        /*
         * We also use a stack of RegexFC objects.
         * This is the push.
         */
        private void PushFC(RegexFC fc)
        {
            if (_fcDepth >= _fcStack.Length)
            {
                RegexFC[] expanded = new RegexFC[_fcDepth * 2];

                System.Array.Copy(_fcStack, 0, expanded, 0, _fcDepth);
                _fcStack = expanded;
            }

            _fcStack[_fcDepth++] = fc;
        }
Beispiel #7
0
        /*
         * This is the one of the only two functions that should be called from outside.
         * It takes a RegexTree and computes the set of chars that can start it.
         */
        internal static RegexPrefix FirstChars(RegexTree t)
        {
            RegexFCD s  = new RegexFCD();
            RegexFC  fc = s.RegexFCFromRegexTree(t);

            if (fc == null || fc._nullable)
            {
                return(null);
            }

            CultureInfo culture = ((t._options & RegexOptions.CultureInvariant) != 0) ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;

            return(new RegexPrefix(fc.GetFirstChars(culture), fc.IsCaseInsensitive()));
        }
Beispiel #8
0
        /// <summary>
        /// This is the one of the only two functions that should be called from outside.
        /// It takes a RegexTree and computes the set of chars that can start it.
        /// </summary>
        public static RegexPrefix?FirstChars(RegexTree t)
        {
            // Create/rent buffers
            Span <int> intSpan = stackalloc int[StackBufferSize];

            RegexFCD s  = new RegexFCD(intSpan);
            RegexFC  fc = s.RegexFCFromRegexTree(t);

            s.Dispose();

            if (fc == null || fc._nullable)
            {
                return(null);
            }

            CultureInfo culture = ((t.Options & RegexOptions.CultureInvariant) != 0) ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;

            return(new RegexPrefix(fc.GetFirstChars(culture), fc.CaseInsensitive));
        }
Beispiel #9
0
        /*
         * FC computation and shortcut cases for each node type
         */
        private void CalculateFC(int NodeType, RegexNode node, int CurIndex)
        {
            bool ci  = false;
            bool rtl = false;

            if (NodeType <= RegexNode.Ref)
            {
                if ((node._options & RegexOptions.IgnoreCase) != 0)
                {
                    ci = true;
                }
                if ((node._options & RegexOptions.RightToLeft) != 0)
                {
                    rtl = true;
                }
            }

            switch (NodeType)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Alternate | BeforeChild:
            case RegexNode.Testref | BeforeChild:
            case RegexNode.Loop | BeforeChild:
            case RegexNode.Lazyloop | BeforeChild:
                break;

            case RegexNode.Testgroup | BeforeChild:
                if (CurIndex == 0)
                {
                    SkipChild();
                }
                break;

            case RegexNode.Empty:
                PushFC(new RegexFC(true));
                break;

            case RegexNode.Concatenate | AfterChild:
                if (CurIndex != 0)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    _failed = !cumul.AddFC(child, true);
                }

                if (!TopFC()._nullable)
                {
                    _skipAllChildren = true;
                }
                break;

            case RegexNode.Testgroup | AfterChild:
                if (CurIndex > 1)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    _failed = !cumul.AddFC(child, false);
                }
                break;

            case RegexNode.Alternate | AfterChild:
            case RegexNode.Testref | AfterChild:
                if (CurIndex != 0)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    _failed = !cumul.AddFC(child, false);
                }
                break;

            case RegexNode.Loop | AfterChild:
            case RegexNode.Lazyloop | AfterChild:
                if (node._m == 0)
                {
                    TopFC()._nullable = true;
                }
                break;

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

            case RegexNode.Require | BeforeChild:
            case RegexNode.Prevent | BeforeChild:
                SkipChild();
                PushFC(new RegexFC(true));
                break;

            case RegexNode.Require | AfterChild:
            case RegexNode.Prevent | AfterChild:
                break;

            case RegexNode.One:
            case RegexNode.Notone:
                PushFC(new RegexFC(node._ch, NodeType == RegexNode.Notone, false, ci));
                break;

            case RegexNode.Oneloop:
            case RegexNode.Onelazy:
                PushFC(new RegexFC(node._ch, false, node._m == 0, ci));
                break;

            case RegexNode.Notoneloop:
            case RegexNode.Notonelazy:
                PushFC(new RegexFC(node._ch, true, node._m == 0, ci));
                break;

            case RegexNode.Multi:
                if (node._str.Length == 0)
                {
                    PushFC(new RegexFC(true));
                }
                else if (!rtl)
                {
                    PushFC(new RegexFC(node._str[0], false, false, ci));
                }
                else
                {
                    PushFC(new RegexFC(node._str[node._str.Length - 1], false, false, ci));
                }
                break;

            case RegexNode.Set:
                PushFC(new RegexFC(node._str, false, ci));
                break;

            case RegexNode.Setloop:
            case RegexNode.Setlazy:
                PushFC(new RegexFC(node._str, node._m == 0, ci));
                break;

            case RegexNode.Ref:
                PushFC(new RegexFC(RegexCharClass.AnyClass, true, false));
                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:
                PushFC(new RegexFC(true));
                break;

            default:
                throw new ArgumentException(SR.Format(SR.UnexpectedOpcode, NodeType.ToString(CultureInfo.CurrentCulture)));
            }
        }
Beispiel #10
0
        /*
          * We also use a stack of RegexFC objects.
          * This is the push.
          */
        private void PushFC(RegexFC fc)
        {
            if (_fcDepth >= _fcStack.Length)
            {
                RegexFC[] expanded = new RegexFC[_fcDepth * 2];

                System.Array.Copy(_fcStack, 0, expanded, 0, _fcDepth);
                _fcStack = expanded;
            }

            _fcStack[_fcDepth++] = fc;
        }
Beispiel #11
0
 internal void PushFC(RegexFC fc)
 {
     if (this._fcDepth >= this._fcStack.Length)
     {
         RegexFC[] destinationArray = new RegexFC[this._fcDepth * 2];
         Array.Copy(this._fcStack, 0, destinationArray, 0, this._fcDepth);
         this._fcStack = destinationArray;
     }
     this._fcStack[this._fcDepth++] = fc;
 }
Beispiel #12
0
        private void CalculateFC(int NodeType, RegexNode node, int CurIndex)
        {
            bool caseInsensitive = false;
            bool flag2           = false;

            if (NodeType <= 13)
            {
                if ((node._options & RegexOptions.IgnoreCase) != RegexOptions.None)
                {
                    caseInsensitive = true;
                }
                if ((node._options & RegexOptions.RightToLeft) != RegexOptions.None)
                {
                    flag2 = true;
                }
            }
            switch (NodeType)
            {
            case 3:
            case 6:
                this.PushFC(new RegexFC(node._ch, false, node._m == 0, caseInsensitive));
                return;

            case 4:
            case 7:
                this.PushFC(new RegexFC(node._ch, true, node._m == 0, caseInsensitive));
                return;

            case 5:
            case 8:
                this.PushFC(new RegexFC(node._str, node._m == 0, caseInsensitive));
                return;

            case 9:
            case 10:
                this.PushFC(new RegexFC(node._ch, NodeType == 10, false, caseInsensitive));
                return;

            case 11:
                this.PushFC(new RegexFC(node._str, false, caseInsensitive));
                return;

            case 12:
                if (node._str.Length != 0)
                {
                    if (!flag2)
                    {
                        this.PushFC(new RegexFC(node._str[0], false, false, caseInsensitive));
                        return;
                    }
                    this.PushFC(new RegexFC(node._str[node._str.Length - 1], false, false, caseInsensitive));
                    return;
                }
                this.PushFC(new RegexFC(true));
                return;

            case 13:
                this.PushFC(new RegexFC("\0\x0001\0\0", true, false));
                return;

            case 14:
            case 15:
            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
            case 20:
            case 0x15:
            case 0x16:
            case 0x29:
            case 0x2a:
                this.PushFC(new RegexFC(true));
                return;

            case 0x17:
                this.PushFC(new RegexFC(true));
                return;

            case 0x58:
            case 0x59:
            case 90:
            case 0x5b:
            case 0x5c:
            case 0x5d:
            case 0x60:
            case 0x61:
            case 0x9c:
            case 0x9d:
            case 0x9e:
            case 0x9f:
            case 160:
                return;

            case 0x5e:
            case 0x5f:
                this.SkipChild();
                this.PushFC(new RegexFC(true));
                return;

            case 0x62:
                if (CurIndex == 0)
                {
                    this.SkipChild();
                }
                return;

            case 0x98:
            case 0xa1:
                if (CurIndex != 0)
                {
                    RegexFC fc   = this.PopFC();
                    RegexFC xfc6 = this.TopFC();
                    this._failed = !xfc6.AddFC(fc, false);
                }
                return;

            case 0x99:
                if (CurIndex != 0)
                {
                    RegexFC xfc  = this.PopFC();
                    RegexFC xfc2 = this.TopFC();
                    this._failed = !xfc2.AddFC(xfc, true);
                }
                if (!this.TopFC()._nullable)
                {
                    this._skipAllChildren = true;
                }
                return;

            case 0x9a:
            case 0x9b:
                if (node._m == 0)
                {
                    this.TopFC()._nullable = true;
                }
                return;

            case 0xa2:
                if (CurIndex > 1)
                {
                    RegexFC xfc3 = this.PopFC();
                    RegexFC xfc4 = this.TopFC();
                    this._failed = !xfc4.AddFC(xfc3, false);
                }
                return;
            }
            throw new ArgumentException(SR.GetString("UnexpectedOpcode", new object[] { NodeType.ToString(CultureInfo.CurrentCulture) }));
        }
Beispiel #13
0
        /*
         * FC computation and shortcut cases for each node type
         */
        internal void CalculateFC(int NodeType, RegexNode node, int CurIndex)
        {
            bool ci  = false;
            bool rtl = false;

            if (NodeType <= RegexNode.Ref)
            {
                if ((node._options & RegexOptions.IgnoreCase) != 0)
                {
                    ci = true;
                }
                if ((node._options & RegexOptions.RightToLeft) != 0)
                {
                    rtl = true;
                }
            }

            switch (NodeType)
            {
            case RegexNode.Concatenate | BeforeChild:
            case RegexNode.Alternate | BeforeChild:
            case RegexNode.Testref | BeforeChild:
            case RegexNode.Loop | BeforeChild:
            case RegexNode.Lazyloop | BeforeChild:
                break;

            case RegexNode.Testgroup | BeforeChild:
                if (CurIndex == 0)
                {
                    SkipChild();
                }
                break;

            case RegexNode.Empty:
                PushFC(new RegexFC(true));
                break;

            case RegexNode.Concatenate | AfterChild:
                if (CurIndex != 0)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    cumul.AddFC(child, true);
                }

                if (!TopFC()._nullable)
                {
                    EarlyExit();
                }
                break;

            case RegexNode.Testgroup | AfterChild:
                if (CurIndex > 1)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    cumul.AddFC(child, false);
                }
                break;

            case RegexNode.Alternate | AfterChild:
            case RegexNode.Testref | AfterChild:
                if (CurIndex != 0)
                {
                    RegexFC child = PopFC();
                    RegexFC cumul = TopFC();

                    cumul.AddFC(child, false);
                }
                break;

            case RegexNode.Loop | AfterChild:
            case RegexNode.Lazyloop | AfterChild:
                if (node._m == 0)
                {
                    TopFC()._nullable = true;
                }
                break;

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

            case RegexNode.Require | BeforeChild:
            case RegexNode.Prevent | BeforeChild:
                SkipChild();
                PushFC(new RegexFC(true));
                break;

            case RegexNode.Require | AfterChild:
            case RegexNode.Prevent | AfterChild:
                break;

            case RegexNode.One:
            case RegexNode.Notone:
                PushFC(new RegexFC(node._ch, NodeType == RegexNode.Notone, false, ci));
                break;

            case RegexNode.Oneloop:
            case RegexNode.Onelazy:
                PushFC(new RegexFC(node._ch, false, node._m == 0, ci));
                break;

            case RegexNode.Notoneloop:
            case RegexNode.Notonelazy:
                PushFC(new RegexFC(node._ch, true, node._m == 0, ci));
                break;

            case RegexNode.Multi:
                if (node._str.Length == 0)
                {
                    PushFC(new RegexFC(true));
                }
                else if (!rtl)
                {
                    PushFC(new RegexFC(node._str[0], false, false, ci));
                }
                else
                {
                    PushFC(new RegexFC(node._str[node._str.Length - 1], false, false, ci));
                }
                break;

            case RegexNode.Set:
                // mark this node as nullable if we have some categories
                PushFC(new RegexFC(node._str, !(node._str2 == null || node._str2.Length == 0), ci));
                break;

            case RegexNode.Setloop:
            case RegexNode.Setlazy:
                // don't need to worry about categories since this is nullable
                PushFC(new RegexFC(node._str, true, ci));
                break;

            case RegexNode.Ref:
                PushFC(new RegexFC(RegexCharClass.Any, true, false));
                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:
                PushFC(new RegexFC(true));
                break;

            default:
                throw new ArgumentException(SR.GetString(SR.UnexpectedOpcode, NodeType.ToString()));
            }
        }
        internal void CalculateFC(int NodeType, RegexNode node, int CurIndex)
        {
            bool caseInsensitive = false;
            bool flag2           = false;

            if (NodeType <= 13)
            {
                if ((node._options & RegexOptions.IgnoreCase) != RegexOptions.None)
                {
                    caseInsensitive = true;
                }
                if ((node._options & RegexOptions.RightToLeft) != RegexOptions.None)
                {
                    flag2 = true;
                }
            }
            switch (NodeType)
            {
            case 3:
            case 6:
                this.PushFC(new RegexFC(node._ch, false, node._m == 0, caseInsensitive));
                return;

            case 4:
            case 7:
                this.PushFC(new RegexFC(node._ch, true, node._m == 0, caseInsensitive));
                return;

            case 5:
            case 8:
                this.PushFC(new RegexFC(node._str, true, caseInsensitive));
                return;

            case 9:
            case 10:
                this.PushFC(new RegexFC(node._ch, NodeType == 10, false, caseInsensitive));
                return;

            case 11:
                this.PushFC(new RegexFC(node._str, (node._str2 != null) && (node._str2.Length != 0), caseInsensitive));
                return;

            case 12:
                if (node._str.Length != 0)
                {
                    if (!flag2)
                    {
                        this.PushFC(new RegexFC(node._str[0], false, false, caseInsensitive));
                        return;
                    }
                    this.PushFC(new RegexFC(node._str[node._str.Length - 1], false, false, caseInsensitive));
                    return;
                }
                this.PushFC(new RegexFC(true));
                return;

            case 13:
                this.PushFC(new RegexFC("\0", true, false));
                return;

            case 14:
            case 15:
            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
            case 20:
            case 0x15:
            case 0x16:
            case 0x29:
            case 0x2a:
                this.PushFC(new RegexFC(true));
                return;

            case 0x17:
                this.PushFC(new RegexFC(true));
                return;

            case 0x58:
            case 0x59:
            case 90:
            case 0x5b:
            case 0x5c:
            case 0x5d:
            case 0x60:
            case 0x61:
            case 0x9c:
            case 0x9d:
            case 0x9e:
            case 0x9f:
            case 160:
                return;

            case 0x5e:
            case 0x5f:
                this.SkipChild();
                this.PushFC(new RegexFC(true));
                return;

            case 0x62:
                if (CurIndex == 0)
                {
                    this.SkipChild();
                }
                return;

            case 0x98:
            case 0xa1:
                if (CurIndex != 0)
                {
                    RegexFC fc = this.PopFC();
                    this.TopFC().AddFC(fc, false);
                }
                return;

            case 0x99:
                if (CurIndex != 0)
                {
                    RegexFC xfc = this.PopFC();
                    this.TopFC().AddFC(xfc, true);
                }
                if (!this.TopFC()._nullable)
                {
                    this.EarlyExit();
                }
                return;

            case 0x9a:
            case 0x9b:
                if (node._m == 0)
                {
                    this.TopFC()._nullable = true;
                }
                return;

            case 0xa2:
                if (CurIndex > 1)
                {
                    RegexFC xfc3 = this.PopFC();
                    this.TopFC().AddFC(xfc3, false);
                }
                return;
            }
            throw new ArgumentException(RegExRes.GetString(4, NodeType.ToString()));
        }
Beispiel #15
0
 /// <summary>
 /// We also use a stack of RegexFC objects.
 /// </summary>
 private void PushFC(RegexFC fc)
 {
     _fcStack.Add(fc);
 }
Beispiel #16
0
        internal void AddFC(RegexFC fc, bool concatenate) {
            if (concatenate) {
                if (!_nullable)
                    return;

                if (!fc._nullable)
                    _nullable = false;
            }
            else {
                if (fc._nullable)
                    _nullable = true;
            }

            _caseInsensitive |= fc._caseInsensitive;
            _cc.AddCharClass(fc._cc);
        }