Beispiel #1
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)
        {
            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.CaseInsensitive));
        }
Beispiel #2
0
        public void Dump()
        {
            int i;

            Debug.WriteLine("Direction:  " + (RightToLeft ? "right-to-left" : "left-to-right"));
            Debug.WriteLine("Firstchars: " + (FCPrefix == null ? "n/a" : RegexCharClass.SetDescription(FCPrefix.GetValueOrDefault().Prefix)));
            Debug.WriteLine("Prefix:     " + (BMPrefix == null ? "n/a" : RegexParser.Escape(BMPrefix.ToString())));
            Debug.WriteLine("Anchors:    " + RegexFCD.AnchorDescription(Anchors));
            Debug.WriteLine("");
            if (BMPrefix != null)
            {
                Debug.WriteLine("BoyerMoore:");
                Debug.WriteLine(BMPrefix.Dump("    "));
            }
            for (i = 0; i < Codes.Length;)
            {
                Debug.WriteLine(OpcodeDescription(i));
                i += OpcodeSize(Codes[i]);
            }

            Debug.WriteLine("");
        }
Beispiel #3
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);

            for (; ;)
            {
                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.Push(curChild);
                    curChild = 0;
                    continue;
                }

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

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

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

            PatchJump(0, _emitted.Count);
            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.ToArray();

            return(new RegexCode(emitted, _stringTable, _trackCount, _caps, capsize, bmPrefix, fcPrefix, anchors, rtl));
        }