Esempio n. 1
0
        private readonly int[] _rules;      // negative -> group #, positive -> string #

        /// <summary>
        /// Since RegexReplacement shares the same parser as Regex,
        /// the constructor takes a RegexNode which is a concatenation
        /// of constant strings and backreferences.
        /// </summary>
        public RegexReplacement(string rep, RegexNode concat, Hashtable _caps)
        {
            if (concat.Type != RegexNode.Concatenate)
            {
                throw ThrowHelper.CreateArgumentException(ExceptionResource.ReplacementError);
            }

            Span <char>      vsbStack     = stackalloc char[256];
            var              vsb          = new ValueStringBuilder(vsbStack);
            FourStackStrings stackStrings = default;
            var              strings      = new ValueListBuilder <string>(MemoryMarshal.CreateSpan(ref stackStrings.Item1 !, 4));
            var              rules        = new ValueListBuilder <int>(stackalloc int[64]);

            int childCount = concat.ChildCount();

            for (int i = 0; i < childCount; i++)
            {
                RegexNode child = concat.Child(i);

                switch (child.Type)
                {
                case RegexNode.Multi:
                    vsb.Append(child.Str !);
                    break;

                case RegexNode.One:
                    vsb.Append(child.Ch);
                    break;

                case RegexNode.Ref:
                    if (vsb.Length > 0)
                    {
                        rules.Append(strings.Length);
                        strings.Append(vsb.ToString());
                        vsb = new ValueStringBuilder(vsbStack);
                    }
                    int slot = child.M;

                    if (_caps != null && slot >= 0)
                    {
                        slot = (int)_caps[slot] !;
                    }

                    rules.Append(-Specials - 1 - slot);
                    break;

                default:
                    throw ThrowHelper.CreateArgumentException(ExceptionResource.ReplacementError);
                }
            }

            if (vsb.Length > 0)
            {
                rules.Append(strings.Length);
                strings.Append(vsb.ToString());
            }

            Pattern  = rep;
            _strings = strings.AsSpan().ToArray();
            _rules   = rules.AsSpan().ToArray();

            rules.Dispose();
        }
Esempio n. 2
0
        private bool _hasBackreferences;    // true if the replacement has any backreferences; otherwise, false

        /// <summary>
        /// Since RegexReplacement shares the same parser as Regex,
        /// the constructor takes a RegexNode which is a concatenation
        /// of constant strings and backreferences.
        /// </summary>
        public RegexReplacement(string rep, RegexNode concat, Hashtable _caps)
        {
            Debug.Assert(concat.Kind == RegexNodeKind.Concatenate, $"Expected Concatenate, got {concat.Kind}");

            var vsb = new ValueStringBuilder(stackalloc char[256]);
            FourStackStrings stackStrings = default;
            var strings = new ValueListBuilder <string>(MemoryMarshal.CreateSpan(ref stackStrings.Item1 !, 4));
            var rules   = new ValueListBuilder <int>(stackalloc int[64]);

            int childCount = concat.ChildCount();

            for (int i = 0; i < childCount; i++)
            {
                RegexNode child = concat.Child(i);

                switch (child.Kind)
                {
                case RegexNodeKind.Multi:
                    vsb.Append(child.Str !);
                    break;

                case RegexNodeKind.One:
                    vsb.Append(child.Ch);
                    break;

                case RegexNodeKind.Backreference:
                    if (vsb.Length > 0)
                    {
                        rules.Append(strings.Length);
                        strings.Append(vsb.AsSpan().ToString());
                        vsb.Length = 0;
                    }
                    int slot = child.M;

                    if (_caps != null && slot >= 0)
                    {
                        slot = (int)_caps[slot] !;
                    }

                    rules.Append(-Specials - 1 - slot);
                    _hasBackreferences = true;
                    break;

                default:
                    Debug.Fail($"Unexpected child kind {child.Kind}");
                    break;
                }
            }

            if (vsb.Length > 0)
            {
                rules.Append(strings.Length);
                strings.Append(vsb.ToString());
            }
            vsb.Dispose();

            Pattern  = rep;
            _strings = strings.AsSpan().ToArray();
            _rules   = rules.AsSpan().ToArray();

            rules.Dispose();
        }