Exemplo n.º 1
0
        protected PatternCompiler(IMatcher <Lexem> patternLexer)
        {
            var automata = new NonDeterministicAutomata <TValue>();

            _automata     = automata;
            _patternLexer = patternLexer;
            _start        = automata.PushEmpty();
        }
Exemplo n.º 2
0
        private static void ConvertAndMatch <TValue>(NonDeterministicNode <TValue> node, string pattern, bool success, string expectedCapture, TValue?expectedValue) where TValue : struct
        {
            var scanner = new AutomataMatcher <TValue>(node.ToDeterministic());

            using (var reader = new StringReader(pattern))
            {
                var matcher = scanner.Open(reader);

                Assert.That(matcher.TryMatchNext(out var match), Is.EqualTo(success));
                Assert.That(match.Capture, Is.EqualTo(expectedCapture));
                Assert.That(match.Value, Is.EqualTo(expectedValue));
            }
        }
Exemplo n.º 3
0
        /// <Summary>
        /// Convert compiled regular expression node into graph of non-deterministic
        /// states connected to given parent state and return final state of
        /// produced graph.
        /// </Summary>
        public NonDeterministicNode <TValue> ConnectTo <TValue>(NonDeterministicAutomata <TValue> automata, NonDeterministicNode <TValue> parent)
        {
            NonDeterministicNode <TValue> next;

            switch (Type)
            {
            case NodeType.Alternative:
                //           /-- [child1] --\
                // [parent] ---- [child2] ---> [next]
                //           \-- [child3] --/

                next = automata.PushEmpty();

                foreach (var child in Children)
                {
                    child.ConnectTo(automata, parent).EpsilonTo(next);
                }

                break;

            case NodeType.Character:
                // [parent] --{begin, end}--> [next]

                next = automata.PushEmpty();

                foreach (var range in Ranges)
                {
                    parent.BranchTo(range.Begin, range.End, next);
                }

                break;

            case NodeType.Repeat:
                //                           /-- [child] --\ * (max - min)
                // [parent] - [child] * min ----------------> [next]
                //                           \-- [child] --/ * infinite

                // Convert until lower bound is reached
                for (var i = 0; i < RepeatMin; ++i)
                {
                    parent = Children[0].ConnectTo(automata, parent);
                }

                next = automata.PushEmpty();

                parent.EpsilonTo(next);

                // Bounded repeat sequence, perform conversion (max - min) times
                if (RepeatMax >= 0)
                {
                    for (var i = 0; i < RepeatMax - RepeatMin; ++i)
                    {
                        parent = Children[0].ConnectTo(automata, parent);
                        parent.EpsilonTo(next);
                    }
                }

                // Unbounded repeat sequence, loop converted state over itself
                else
                {
                    var loop = Children[0].ConnectTo(automata, parent);

                    loop.EpsilonTo(parent);
                    loop.EpsilonTo(next);
                }

                return(next);

            case NodeType.Sequence:
                // [parent] -> [child1] -> [child2] -> ... -> [next]

                next = parent;

                foreach (var child in Children)
                {
                    next = child.ConnectTo(automata, next);
                }

                break;

            default:
                throw new InvalidOperationException();
            }

            return(next);
        }
Exemplo n.º 4
0
 public void EpsilonTo(NonDeterministicNode <TValue> target)
 {
     _automata.EpsilonTo(_index, target._index);
 }
Exemplo n.º 5
0
 public void BranchTo(int begin, int end, NonDeterministicNode <TValue> target)
 {
     _automata.BranchTo(_index, begin, end, target._index);
 }