예제 #1
0
 protected override object VisitBackreferenceBlock(BackreferenceBlock block)
 {
     string text;
     if (!_groupValues.TryGetValue(block.GroupIndex, out text))
         throw new ArgumentException("Reference to unspecified group", "block");
     if (CanUseText(_position, text))
         return new[] { _position + text.Length };
     return _errorResult;
 }
        public void GetLinesFromBackreferenceBlockTest()
        {
            Dictionary<int, string> groupValues = new Dictionary<int,string>();
            var input  = "\0\0'";
            int groupId = 1;
            var visitor1 = new BuilderRegexVisitor(0, input, groupValues, null);

            groupValues[groupId] = "ab";
            var backreferenceBlock = new BackreferenceBlock(groupId);

            string[] expectedLines = new string[] { "ab" };
            CheckVisitorResult(visitor1, backreferenceBlock, expectedLines);

            groupValues[groupId] = "abc";
            var visitor2 = new BuilderRegexVisitor(0, input, groupValues, null);
            CheckVisitorResult(visitor2, backreferenceBlock, Enumerable.Empty<string>());
        }
예제 #3
0
        public void GetPositionsFromBackreferenceBlockTest()
        {
            var groupValues = new Dictionary<int, string>();
            string input = "\0\0";
            int groupId = 1;
            var visitor1 = new CheckerRegexVisitor(0, input, groupValues);

            groupValues[groupId] = "ab";
            var backreferenceBlock = new BackreferenceBlock(groupId);

            var positions1 = visitor1.GetPositions(backreferenceBlock);
            positions1.Should().BeEquivalentTo(new[] { 2 });

            groupValues[groupId] = "abc";
            var visitor2 = new CheckerRegexVisitor(0, input, groupValues);
            var positions2 = visitor2.GetPositions(backreferenceBlock);
            positions2.Should().BeEmpty();
        }
예제 #4
0
        public void ParseTest11()
        {
            var parser = new RegexParser();
            string pattern = @".+(.)(.)(.)(.)\4\3\2\1.*";

            // Expected regular expression
            var anyCharacterBlock = new AnyCharacterBlock();
            var oneOrMoreBlock = new OneOrMoreBlock(anyCharacterBlock);
            var zeroOrOneBlock = new ZeroOrMoreBlock(anyCharacterBlock);
            var andGroupBlock = new AndGroupBlock(new [] { anyCharacterBlock });
            var b4 = new BackreferenceBlock(4);
            var b3 = new BackreferenceBlock(3);
            var b2 = new BackreferenceBlock(2);
            var b1 = new BackreferenceBlock(1);
            var groupBlock = new AndGroupBlock(new RegexBlock[] { oneOrMoreBlock, andGroupBlock, andGroupBlock, andGroupBlock, andGroupBlock, b4, b3, b2, b1, zeroOrOneBlock });

            var expected = new RegularExpression(groupBlock);

            var actual = parser.Parse(pattern);
            actual.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
예제 #5
0
        public void ParseTest11()
        {
            var parser = new RegexParser();
            string pattern = @".+(.)(.)(.)(.)\4\3\2\1.*";

            // Expected regular expression
            var anyCharacterBlock = new AnyCharacterBlock();
            var oneOrMoreBlock = new OneOrMoreBlock(anyCharacterBlock);
            var zeroOrOneBlock = new ZeroOrMoreBlock(anyCharacterBlock);
            var andGroupBlock = new AndGroupBlock(new [] { anyCharacterBlock });
            var b4 = new BackreferenceBlock(4);
            var b3 = new BackreferenceBlock(3);
            var b2 = new BackreferenceBlock(2);
            var b1 = new BackreferenceBlock(1);
            var groupBlock = new AndGroupBlock(new RegexBlock[] { oneOrMoreBlock, andGroupBlock, andGroupBlock, andGroupBlock, andGroupBlock, b4, b3, b2, b1, zeroOrOneBlock });

            var expected = new RegularExpression(groupBlock);

            var actual = parser.Parse(pattern);
            Assert.IsTrue(expected.Equals(actual), "Pattern was parsed incorrectly");
        }
예제 #6
0
 protected virtual object VisitBackreferenceBlock(BackreferenceBlock block)
 {
     return block;
 }
예제 #7
0
        public RegularExpression Parse(string pattern)
        {
            var containers = new Stack<BlockContainer>();
            containers.Push(new BlockContainer { Type = BlockContainerType.AndContainer });
            bool expectGoupId = false;
            int position = 0;
            bool startNewBlock = false;
            while (position < pattern.Length)
            {
                char c = pattern[position];
                var currentContainer = containers.Peek();
                if (currentContainer == null)
                    throw new ArgumentException("Invalid position for character" + c, "pattern");
                if (char.IsLetterOrDigit(c))
                {
                    if (expectGoupId)
                    {
                        var backreferenceBlock = new BackreferenceBlock(int.Parse(c.ToString(CultureInfo.InvariantCulture)));
                        currentContainer.PushBlock(backreferenceBlock);
                        expectGoupId = false;
                    }
                    else
                    {
                        if (startNewBlock || !currentContainer.Blocks.Any() || !IsCharacterContainer(currentContainer.PeekBlock()))
                        {
                            currentContainer.PushBlock(new TextBlock(string.Empty));
                        }

                        var characterContainer = currentContainer.PopBlock();
                        currentContainer.PushBlock(AddCharacter(characterContainer, c));
                    }

                    startNewBlock = false;
                }
                else
                {
                    startNewBlock = false;
                    switch (c)
                    {
                        case '.':
                            currentContainer.PushBlock(new AnyCharacterBlock());
                            break;
                        case '+':
                            {
                                SplitTextBlock(currentContainer);

                                var previousBlock = currentContainer.PopBlock();
                                currentContainer.PushBlock(new OneOrMoreBlock(previousBlock));
                            }

                            break;
                        case '*':
                            {
                                SplitTextBlock(currentContainer);

                                var previousBlock = currentContainer.PopBlock();
                                currentContainer.PushBlock(new ZeroOrMoreBlock(previousBlock));
                            }

                            break;
                        case '?':
                            {
                                SplitTextBlock(currentContainer);

                                var previousBlock = currentContainer.PopBlock();
                                currentContainer.PushBlock(new ZeroOrOneBlock(previousBlock));
                            }

                            break;
                        case '[':
                            currentContainer.PushBlock(new InclusiveSetBlock(string.Empty));
                            break;
                        case ']':
                            startNewBlock = true;
                            break;
                        case '^':
                            {
                                var inclusiveSetBlock = currentContainer.PopBlock() as InclusiveSetBlock;
                                if (inclusiveSetBlock == null || inclusiveSetBlock.Characters.Any()) throw new ArgumentException("Invalid position for character ^", "pattern");
                                currentContainer.PushBlock(new ExclusiveSetBlock(inclusiveSetBlock.Characters));
                            }

                            break;
                        case '(':
                            containers.Push(new BlockContainer());
                            break;
                        case ')':
                            {
                                if (currentContainer.Type == BlockContainerType.Undefined) currentContainer.Type = BlockContainerType.AndContainer;
                                GroupBlock containerBlock = ConvertToBlock(currentContainer);
                                containers.Pop();
                                var outerBlockContainer = containers.Peek();
                                if (outerBlockContainer == null) throw new ArgumentException("Invalid position for character ]", "pattern");
                                outerBlockContainer.PushBlock(containerBlock);
                            }

                            break;
                        case '|':
                            startNewBlock = true;
                            currentContainer.Type = BlockContainerType.OrContainer;
                            break;
                        case '\\':
                            expectGoupId = true;
                            break;
                        default:
                            throw new ArgumentException("Unrecognized symbol in pattern", "pattern");
                    }
                }

                position++;
            }

            var container = containers.Pop();

            GroupBlock block = ConvertToBlock(container);

            // Remove redundant group group if any.
            if (block.InnerBlocks.Count() == 1)
            {
                var orGroupBlock = block.InnerBlocks.First() as OrGroupBlock;
                if (orGroupBlock != null)
                    block = orGroupBlock;
            }

            return new RegularExpression(block);
        }