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>()); }
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(); }
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()); }
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"); }
protected virtual object VisitBackreferenceBlock(BackreferenceBlock block) { return block; }
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); }