示例#1
0
        public static IAutomaton Alternate(IEnumerable <IAutomaton> automata)
        {
            var builder = new AutomatonBuilder();
            var start   = builder.AddState();
            var end     = builder.AddState();

            builder.SetStartState(start);
            builder.AcceptState(end);
            foreach (var automaton in automata)
            {
                automaton.CopyTo(builder, out var oldStart, out var oldAcceptings);
                builder.AddEpsilonTransition(start, oldStart);
                foreach (var accepting in oldAcceptings)
                {
                    builder.AddEpsilonTransition(accepting, end);
                }
            }
            return(builder.Build());
        }
示例#2
0
        public static IAutomaton Concat(IEnumerable <IAutomaton> automata)
        {
            var builder = new AutomatonBuilder();
            var start   = builder.AddState();

            builder.SetStartState(start);
            foreach (var automaton in automata)
            {
                var end = builder.AddState();
                automaton.CopyTo(builder, out var oldNewStart, out var oldNewAcceptings);
                builder.AddEpsilonTransition(start, oldNewStart);
                foreach (var st in oldNewAcceptings)
                {
                    builder.AddEpsilonTransition(st, end);
                }
                start = end;
            }
            builder.AcceptState(start);
            return(builder.Build());
        }
示例#3
0
        public static IAutomaton Repeat(IAutomaton automaton, int min = 0, int max = -1)
        {
            if (min < 0 || (max >= 0 && min > max))
            {
                throw new ArgumentException(nameof(min));
            }
            var builder       = new AutomatonBuilder();
            var start         = builder.AddState();
            var accept        = builder.AddState();
            var previousStart = -1;

            builder.SetStartState(start);
            builder.AcceptState(accept);
            int?count = null;

            if (max != -1)
            {
                count = max - min;
            }
            while (min > 0)
            {
                var end = builder.AddState();
                automaton.CopyTo(builder, out var oldNewStart, out var oldNewAcceptings);
                builder.AddEpsilonTransition(start, oldNewStart);
                foreach (var st in oldNewAcceptings)
                {
                    builder.AddEpsilonTransition(st, end);
                }
                min--;
                previousStart = start;
                start         = end;
            }
            builder.AddEpsilonTransition(start, accept);
            if (count == null) //no upper limit, loop!
            {
                if (previousStart == -1)
                {
                    var end = builder.AddState();
                    automaton.CopyTo(builder, out var oldNewStart, out var oldNewAcceptings);
                    builder.AddEpsilonTransition(start, oldNewStart);
                    builder.AddEpsilonTransition(end, accept);
                    foreach (var st in oldNewAcceptings)
                    {
                        builder.AddEpsilonTransition(st, end);
                    }
                    previousStart = start;
                    start         = end;
                }
                builder.AddEpsilonTransition(start, previousStart);
            }
            else
            {
                while (count > 0)//existing upper limit, no loop!
                {
                    var end = builder.AddState();
                    automaton.CopyTo(builder, out var oldNewStart, out var oldNewAcceptings);
                    builder.AddEpsilonTransition(start, oldNewStart);
                    foreach (var st in oldNewAcceptings)
                    {
                        builder.AddEpsilonTransition(st, end);
                    }
                    builder.AddEpsilonTransition(end, accept);
                    count--;
                    start = end;
                }
            }
            return(builder.Build());
        }