internal RegexInterpreter(RegexCode code, CultureInfo culture) {
     runcode       = code;
     runcodes      = code._codes;
     runstrings    = code._strings;
     runfcPrefix   = code._fcPrefix;
     runbmPrefix   = code._bmPrefix;
     runanchors    = code._anchors;
     runculture    = culture;
 }
Example #2
0
 internal RegexInterpreter(RegexCode code, CultureInfo culture)
 {
     _runcode     = code;
     _runcodes    = code._codes;
     _runstrings  = code._strings;
     _runfcPrefix = code._fcPrefix;
     _runbmPrefix = code._bmPrefix;
     _runanchors  = code._anchors;
     _runculture  = culture;
 }
 internal RegexCode(int[] codes, List <string> stringlist, int trackcount, Hashtable caps, int capsize, RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix, int anchors, bool rightToLeft)
 {
     this._codes       = codes;
     this._strings     = new string[stringlist.Count];
     this._trackcount  = trackcount;
     this._caps        = caps;
     this._capsize     = capsize;
     this._bmPrefix    = bmPrefix;
     this._fcPrefix    = fcPrefix;
     this._anchors     = anchors;
     this._rightToLeft = rightToLeft;
     stringlist.CopyTo(0, this._strings, 0, stringlist.Count);
 }
 internal RegexCode(int[] codes, ArrayList stringlist, int trackcount, System.Collections.Generic.Dictionary <object, object> caps, int capsize, RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix, RegexPrefix scPrefix, int anchors, bool rightToLeft)
 {
     this._codes       = codes;
     this._strings     = new string[stringlist.Count];
     this._trackcount  = trackcount;
     this._caps        = caps;
     this._capsize     = capsize;
     this._bmPrefix    = bmPrefix;
     this._fcPrefix    = fcPrefix;
     this._scPrefix    = scPrefix;
     this._anchors     = anchors;
     this._rightToLeft = rightToLeft;
     stringlist.CopyTo(0, this._strings, 0, stringlist.Count);
 }
Example #5
0
 internal RegexCode(int[] codes, ArrayList stringlist, int trackcount, System.Collections.Generic.Dictionary<object,object> caps, int capsize, RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix, RegexPrefix scPrefix, int anchors, bool rightToLeft)
 {
     this._codes = codes;
     this._strings = new string[stringlist.Count];
     this._trackcount = trackcount;
     this._caps = caps;
     this._capsize = capsize;
     this._bmPrefix = bmPrefix;
     this._fcPrefix = fcPrefix;
     this._scPrefix = scPrefix;
     this._anchors = anchors;
     this._rightToLeft = rightToLeft;
     stringlist.CopyTo(0, this._strings, 0, stringlist.Count);
 }
Example #6
0
        internal bool _rightToLeft;                   // true if right to left

        // optimizations

        // constructor

        internal RegexCode(int [] codes, ArrayList stringlist, int trackcount,
                           Hashtable caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                           int anchors, bool rightToLeft)
        {
            _codes       = codes;
            _strings     = new String[stringlist.Count];
            _trackcount  = trackcount;
            _caps        = caps;
            _capsize     = capsize;
            _bmPrefix    = bmPrefix;
            _fcPrefix    = fcPrefix;
            _anchors     = anchors;
            _rightToLeft = rightToLeft;
            stringlist.CopyTo(0, _strings, 0, stringlist.Count);
        }
Example #7
0
        internal bool _rightToLeft;               // true if right to left

        // optimizations

        // constructor

        internal RegexCode(int[] codes, List <String> stringlist, int trackcount,
                           Dictionary <Int32, Int32> caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                           int anchors, bool rightToLeft)
        {
            _codes       = codes;
            _strings     = new String[stringlist.Count];
            _trackcount  = trackcount;
            _caps        = caps;
            _capsize     = capsize;
            _bmPrefix    = bmPrefix;
            _fcPrefix    = fcPrefix;
            _anchors     = anchors;
            _rightToLeft = rightToLeft;
            stringlist.CopyTo(0, _strings, 0, stringlist.Count);
        }
Example #8
0
        internal readonly bool _rightToLeft;         // true if right to left

        internal RegexCode(int[] codes, List <string> stringlist, int trackcount,
                           Hashtable caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                           int anchors, bool rightToLeft)
        {
            Debug.Assert(codes != null, "codes cannot be null.");
            Debug.Assert(stringlist != null, "stringlist cannot be null.");

            _codes       = codes;
            _strings     = stringlist.ToArray();
            _trackcount  = trackcount;
            _caps        = caps;
            _capsize     = capsize;
            _bmPrefix    = bmPrefix;
            _fcPrefix    = fcPrefix;
            _anchors     = anchors;
            _rightToLeft = rightToLeft;
        }
Example #9
0
        public readonly bool RightToLeft;         // true if right to left

        public RegexCode(int[] codes, List <string> stringlist, int trackcount,
                         Hashtable caps, int capsize,
                         RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                         int anchors, bool rightToLeft)
        {
            Debug.Assert(codes != null, "codes cannot be null.");
            Debug.Assert(stringlist != null, "stringlist cannot be null.");

            Codes       = codes;
            Strings     = stringlist.ToArray();
            TrackCount  = trackcount;
            Caps        = caps;
            CapSize     = capsize;
            BMPrefix    = bmPrefix;
            FCPrefix    = fcPrefix;
            Anchors     = anchors;
            RightToLeft = rightToLeft;
        }
Example #10
0
        internal RegexCode RegexCodeFromRegexTree(RegexTree tree)
        {
            int             length;
            RegexBoyerMoore moore;

            if ((tree._capnumlist == null) || (tree._captop == tree._capnumlist.Length))
            {
                length     = tree._captop;
                this._caps = null;
            }
            else
            {
                length     = tree._capnumlist.Length;
                this._caps = tree._caps;
                for (int i = 0; i < tree._capnumlist.Length; i++)
                {
                    this._caps[tree._capnumlist[i]] = i;
                }
            }
            this._counting = true;
Label_0076:
            if (!this._counting)
            {
                this._emitted = new int[this._count];
            }
            RegexNode node     = tree._root;
            int       curIndex = 0;

            this.Emit(0x17, 0);
Label_00A1:
            if (node._children == null)
            {
                this.EmitFragment(node._type, node, 0);
            }
            else if (curIndex < node._children.Count)
            {
                this.EmitFragment(node._type | 0x40, node, curIndex);
                node = (RegexNode)node._children[curIndex];
                this.PushInt(curIndex);
                curIndex = 0;
                goto Label_00A1;
            }
            if (!this.EmptyStack())
            {
                curIndex = this.PopInt();
                node     = node._next;
                this.EmitFragment(node._type | 0x80, node, curIndex);
                curIndex++;
                goto Label_00A1;
            }
            this.PatchJump(0, this.CurPos());
            this.Emit(40);
            if (this._counting)
            {
                this._counting = false;
                goto Label_0076;
            }
            RegexPrefix fcPrefix = RegexFCD.FirstChars(tree);

            if ((fcPrefix != null) && (RegexCharClass.SetSize(fcPrefix.Prefix) > 0))
            {
                fcPrefix = null;
            }
            RegexPrefix scPrefix    = null;
            RegexPrefix prefix3     = RegexFCD.Prefix(tree);
            bool        rightToLeft = (tree._options & RegexOptions.RightToLeft) != RegexOptions.None;
            CultureInfo culture     = ((tree._options & RegexOptions.CultureInvariant) != RegexOptions.None) ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;

            if ((prefix3 != null) && (prefix3.Prefix.Length > 0))
            {
                moore = new RegexBoyerMoore(prefix3.Prefix, prefix3.CaseInsensitive, rightToLeft, culture);
            }
            else
            {
                moore = null;
            }
            return(new RegexCode(this._emitted, this._stringtable, this._trackcount, this._caps, length, moore, fcPrefix, scPrefix, RegexFCD.Anchors(tree), rightToLeft));
        }
Example #11
0
        /// <summary>
        /// The top level 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>
        public RegexCode RegexCodeFromRegexTree(RegexTree tree)
        {
            // construct sparse capnum mapping if some numbers are unused
            int capsize;

            if (tree.CapNumList == null || tree.CapTop == tree.CapNumList.Length)
            {
                capsize = tree.CapTop;
                _caps   = null;
            }
            else
            {
                capsize = tree.CapNumList.Length;
                _caps   = tree.Caps;
                for (int i = 0; i < tree.CapNumList.Length; i++)
                {
                    _caps[tree.CapNumList[i]] = i;
                }
            }

            RegexNode?curNode  = tree.Root;
            int       curChild = 0;

            Emit(RegexCode.Lazybranch, 0);

            while (true)
            {
                if (curNode.Children == null)
                {
                    EmitFragment(curNode.NType, curNode, 0);
                }
                else if (curChild < curNode.Children.Count)
                {
                    EmitFragment(curNode.NType | BeforeChild, curNode, curChild);

                    curNode = curNode.Children[curChild];
                    _intStack.Append(curChild);
                    curChild = 0;
                    continue;
                }

                if (_intStack.Length == 0)
                {
                    break;
                }

                curChild = _intStack.Pop();
                curNode  = curNode.Next;

                EmitFragment(curNode !.NType | AfterChild, curNode, curChild);
                curChild++;
            }

            PatchJump(0, _emitted.Length);
            Emit(RegexCode.Stop);

            RegexPrefix?fcPrefix = RegexFCD.FirstChars(tree);
            RegexPrefix prefix   = RegexFCD.Prefix(tree);
            bool        rtl      = ((tree.Options & RegexOptions.RightToLeft) != 0);

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

            if (prefix.Prefix.Length > 0)
            {
                bmPrefix = new RegexBoyerMoore(prefix.Prefix, prefix.CaseInsensitive, rtl, culture);
            }
            else
            {
                bmPrefix = null;
            }

            int anchors = RegexFCD.Anchors(tree);

            int[] emitted = _emitted.AsSpan().ToArray();

            return(new RegexCode(emitted, _stringTable, _trackCount, _caps, capsize, bmPrefix, fcPrefix, anchors, rtl));
        }
Example #12
0
        // The top-level driver. Initializes everything then calls the Generate* methods.
        internal Type FactoryFromCode(RegexCode code, RegexOptions options, String typeprefix) {
            String runnertypename;
            String runnerfactoryname;
            Type runnertype;
            Type factory;

            _code       = code;
            _codes      = code._codes;
            _strings    = code._strings;
            _fcPrefix   = code._fcPrefix;
            _scPrefix   = code._scPrefix;
            _bmPrefix   = code._bmPrefix;
            _anchors    = code._anchors;
            _trackcount = code._trackcount;
            _options    = options;

            // pick a name for the class

            lock (_syncObject) {

                // Note: Class names must be unique within assemblies, not just 
                // within modules.  We append the modulename to the runner name 
                // to make our name unique across the assembly

                runnertypename = typeprefix + "Runner" + _typeCount.ToString();
                runnerfactoryname = typeprefix + "Factory" + _typeCount.ToString();
                _typeCount++;
            }

            // Generate a RegexRunner class
            // (blocks are simply illustrative)

            DefineType(runnertypename, false, typeof(RegexRunner));
            {
                DefineMethod("Go", null);
                {
                    GenerateGo();
                    BakeMethod();
                }

                DefineMethod("FindFirstChar", typeof(bool));
                {
                    GenerateFindFirstChar();
                    BakeMethod();
                }

                DefineMethod("InitTrackCount", null);
                {
                    GenerateInitTrackCount();
                    BakeMethod();
                }

                runnertype = BakeType();
            }

            // Generate a RegexRunnerFactory class

            DefineType(runnerfactoryname, false, typeof(RegexRunnerFactory));
            {
                DefineMethod("CreateInstance", typeof(RegexRunner));
                {
                    GenerateCreateInstance(runnertype);
                    BakeMethod();
                }

                factory = BakeType();
            }

            return factory;
        }
Example #13
0
        internal readonly bool _rightToLeft;                // true if right to left

        internal RegexCode(int[] codes, List<String> stringlist, int trackcount,
                           Dictionary<Int32, Int32> caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                           int anchors, bool rightToLeft)
        {
            Debug.Assert(codes != null, "codes cannot be null.");
            Debug.Assert(stringlist != null, "stringlist cannot be null.");

            _codes = codes;
            _strings = new String[stringlist.Count];
            _trackcount = trackcount;
            _caps = caps;
            _capsize = capsize;
            _bmPrefix = bmPrefix;
            _fcPrefix = fcPrefix;
            _anchors = anchors;
            _rightToLeft = rightToLeft;
            stringlist.CopyTo(0, _strings, 0, stringlist.Count);
        }
Example #14
0
        internal readonly int _trackcount; // how many instructions use backtracking

        #endregion Fields

        #region Constructors

        internal RegexCode(int[] codes, List<string> stringlist, int trackcount,
                           Hashtable caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix,
                           int anchors, bool rightToLeft)
        {
            Debug.Assert(codes != null, "codes cannot be null.");
            Debug.Assert(stringlist != null, "stringlist cannot be null.");

            _codes = codes;
            _strings = stringlist.ToArray();
            _trackcount = trackcount;
            _caps = caps;
            _capsize = capsize;
            _bmPrefix = bmPrefix;
            _fcPrefix = fcPrefix;
            _anchors = anchors;
            _rightToLeft = rightToLeft;
        }
Example #15
0
        /// <summary>
        /// The top level RegexCode generator. It does a depth-first walk
        /// through the tree and calls EmitFragment to emit code before
        /// and after each child of an interior node and at each leaf.
        /// It also computes various information about the tree, such as
        /// prefix data to help with optimizations.
        /// </summary>
        public RegexCode RegexCodeFromRegexTree(RegexTree tree)
        {
            // Construct sparse capnum mapping if some numbers are unused.
            int capsize;

            if (tree.CapNumList == null || tree.CapTop == tree.CapNumList.Length)
            {
                capsize = tree.CapTop;
                _caps   = null;
            }
            else
            {
                capsize = tree.CapNumList.Length;
                _caps   = tree.Caps;
                for (int i = 0; i < tree.CapNumList.Length; i++)
                {
                    _caps[tree.CapNumList[i]] = i;
                }
            }

            // Every written code begins with a lazy branch.  This will be back-patched
            // to point to the ending Stop after the whole expression has been written.
            Emit(RegexCode.Lazybranch, 0);

            // Emit every node.
            RegexNode curNode  = tree.Root;
            int       curChild = 0;

            while (true)
            {
                int curNodeChildCount = curNode.ChildCount();
                if (curNodeChildCount == 0)
                {
                    EmitFragment(curNode.Type, curNode, 0);
                }
                else if (curChild < curNodeChildCount)
                {
                    EmitFragment(curNode.Type | BeforeChild, curNode, curChild);

                    curNode = curNode.Child(curChild);
                    _intStack.Append(curChild);
                    curChild = 0;
                    continue;
                }

                if (_intStack.Length == 0)
                {
                    break;
                }

                curChild = _intStack.Pop();
                curNode  = curNode.Next !;

                EmitFragment(curNode.Type | AfterChild, curNode, curChild);
                curChild++;
            }

            // Patch the starting Lazybranch, emit the final Stop, and get the resulting code array.
            PatchJump(0, _emitted.Length);
            Emit(RegexCode.Stop);
            int[] emitted = _emitted.AsSpan().ToArray();

            bool rtl = (tree.Options & RegexOptions.RightToLeft) != 0;

            // Compute prefixes to help optimize FindFirstChar.
            RegexBoyerMoore?bmPrefix = null;
            RegexPrefix?    fcPrefix = null;
            RegexPrefix     prefix   = RegexFCD.Prefix(tree);

            if (prefix.Prefix.Length > 1 && prefix.Prefix.Length <= RegexBoyerMoore.MaxLimit) // if it's <= 1 || > MaxLimit, perf is better using fcPrefix
            {
                // Compute a Boyer-Moore prefix if we find a single string of sufficient length that always begins the expression.
                CultureInfo culture = (tree.Options & RegexOptions.CultureInvariant) != 0 ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;
                bmPrefix = new RegexBoyerMoore(prefix.Prefix, prefix.CaseInsensitive, rtl, culture);
            }
            else
            {
                // If we didn't find such a string, try to compute the characters set that might begin the string.
                fcPrefix = RegexFCD.FirstChars(tree);
            }

            // Compute any anchors starting the expression.
            int anchors = RegexFCD.Anchors(tree);

            // Convert the string table into an ordered string array/
            var strings = new string[_stringTable.Count];

            foreach (KeyValuePair <string, int> stringEntry in _stringTable)
            {
                strings[stringEntry.Value] = stringEntry.Key;
            }

            // Return all that in a RegexCode object.
            return(new RegexCode(tree, emitted, strings, _trackCount, _caps, capsize, bmPrefix, fcPrefix, anchors, rtl));
        }
Example #16
0
        /// <summary>
        /// The top level 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>
        public RegexCode RegexCodeFromRegexTree(RegexTree tree)
        {
            Span <int>  emittedSpan  = stackalloc int[EmittedSize];
            Span <int>  intStackSpan = stackalloc int[IntStackSize];
            RegexWriter writer       = new RegexWriter(emittedSpan, intStackSpan);

            // construct sparse capnum mapping if some numbers are unused
            int capsize;

            if (tree._capnumlist == null || tree._captop == tree._capnumlist.Length)
            {
                capsize      = tree._captop;
                writer._caps = null;
            }
            else
            {
                capsize      = tree._capnumlist.Length;
                writer._caps = tree._caps;
                for (int i = 0; i < tree._capnumlist.Length; i++)
                {
                    writer._caps[tree._capnumlist[i]] = i;
                }
            }

            RegexNode curNode  = tree._root;
            int       curChild = 0;

            writer.Emit(RegexCode.Lazybranch, 0);

            for (; ;)
            {
                if (curNode._children == null)
                {
                    writer.EmitFragment(curNode._type, curNode, 0);
                }
                else if (curChild < curNode._children.Count)
                {
                    writer.EmitFragment(curNode._type | BeforeChild, curNode, curChild);

                    curNode = curNode._children[curChild];
                    writer._intStack.Append(curChild);
                    curChild = 0;
                    continue;
                }

                if (writer._intStack.Length == 0)
                {
                    break;
                }

                curChild = writer._intStack.Pop();
                curNode  = curNode._next;

                writer.EmitFragment(curNode._type | AfterChild, curNode, curChild);
                curChild++;
            }

            writer.PatchJump(0, writer._emitted.Length);
            writer.Emit(RegexCode.Stop);

            RegexPrefix fcPrefix = RegexFCD.FirstChars(tree);
            RegexPrefix prefix   = RegexFCD.Prefix(tree);
            bool        rtl      = ((tree._options & RegexOptions.RightToLeft) != 0);

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

            if (prefix != null && prefix.Prefix.Length > 0)
            {
                bmPrefix = new RegexBoyerMoore(prefix.Prefix, prefix.CaseInsensitive, rtl, culture);
            }
            else
            {
                bmPrefix = null;
            }

            int anchors = RegexFCD.Anchors(tree);

            int[] emitted = writer._emitted.AsReadOnlySpan().ToArray();

            // Cleaning up and returning the borrowed arrays
            writer._emitted.Dispose();
            writer._intStack.Dispose();

            return(new RegexCode(emitted, writer._stringTable, writer._trackCount, writer._caps, capsize, bmPrefix, fcPrefix, anchors, rtl));
        }
Example #17
0
        internal bool         _rightToLeft;           // true if right to left

        // optimizations

        // constructor

        internal RegexCode(int [] codes, ArrayList stringlist, int trackcount,
                           Hashtable caps, int capsize,
                           RegexBoyerMoore bmPrefix, RegexPrefix fcPrefix, RegexPrefix scPrefix,
                           int anchors, bool rightToLeft) {
            _codes = codes;
            _strings = new String[stringlist.Count];
            _trackcount = trackcount;
            _caps = caps;
            _capsize = capsize;
            _bmPrefix = bmPrefix;
            _fcPrefix = fcPrefix;
            _scPrefix = scPrefix;
            _anchors = anchors;
            _rightToLeft = rightToLeft;
            stringlist.CopyTo(0, _strings, 0, stringlist.Count);
        }