Ejemplo n.º 1
0
 /// <summary>
 /// Returns a <see cref="PartialNFA"/> constructed
 /// by concatenating the left and right partials with a epsilon transition between
 /// them
 /// </summary>
 /// <param name="left">Left partial NFA</param>
 /// <param name="right">Right partial NFA</param>
 /// <returns></returns>
 public PartialNFA Concatenation(PartialNFA left, PartialNFA right)
 {
     return(new PartialNFA(
                left.Initial,
                right.Terminal,
                left.Transitions
                .Union(right.Transitions)
                .Union(new[] { Transition(left.Terminal, Epsilon, right.Initial) })
                ));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a clone of the supplied <see cref="PartialNFA"/>
        /// where each state is replaced with a new state and all transitions are mapped
        /// across to use the new states
        /// </summary>
        /// <param name="partial"><see cref="PartialNFA"/>
        /// to be cloned</param>
        /// <returns></returns>
        public PartialNFA Clone(
            PartialNFA partial)
        {
            var map = Enumerable.Union(
                partial.Transitions.Select(t => t.Source),
                partial.Transitions.Select(t => t.Target)
                ).Distinct().ToDictionary(s => s, s => State());

            return(new PartialNFA(
                       map[partial.Initial],
                       map[partial.Terminal],
                       partial.Transitions.Select(t => Transition(map[t.Source], t.Input, map[t.Target]))
                       ));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns a <see cref="PartialNFA"/> constructed
        /// to make the inner partial optional using the Kleene star expression
        /// </summary>
        /// <param name="inner">Inner partial NFA to make optional</param>
        /// <returns></returns>
        public PartialNFA OptionalRepeating(PartialNFA inner)
        {
            var initial  = State();
            var terminal = State();

            return(new PartialNFA(
                       initial,
                       terminal,
                       inner.Transitions
                       .Union(new[] {
                Transition(initial, Epsilon, inner.Initial),
                Transition(initial, Epsilon, terminal),
                Transition(inner.Terminal, Epsilon, terminal),
                Transition(inner.Terminal, Epsilon, inner.Initial),
            })
                       ));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns a <see cref="PartialNFA"/> constructed
        /// to give alternative routes between the left and right partials with epsilon
        /// transitions from the new initial to the partial initials, and from the partial
        /// terminals to the new terminal
        /// </summary>
        /// <param name="left">Left partial NFA</param>
        /// <param name="right">Right partial NFA</param>s
        /// <returns></returns>
        public PartialNFA Alternative(PartialNFA left, PartialNFA right)
        {
            var initial  = State();
            var terminal = State();

            return(new PartialNFA(
                       initial,
                       terminal,
                       left.Transitions
                       .Union(right.Transitions)
                       .Union(new[] {
                Transition(initial, Epsilon, left.Initial),
                Transition(initial, Epsilon, right.Initial),
                Transition(left.Terminal, Epsilon, terminal),
                Transition(right.Terminal, Epsilon, terminal),
            })
                       ));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Returns a <see cref="PartialNFA"/> constructed
 /// to optionally match the inner partial
 /// </summary>
 /// <param name="inner"></param>
 /// <returns></returns>
 public PartialNFA Optional(PartialNFA inner)
 => Alternative(inner, Input(Epsilon));
Ejemplo n.º 6
0
 /// <summary>
 /// Returns a <see cref="PartialNFA"/> constructed
 /// to match one or more instances of the inner partial
 /// </summary>
 /// <param name="inner"></param>
 /// <returns></returns>
 public PartialNFA RequiredRepeating(PartialNFA inner)
 => Concatenation(inner, OptionalRepeating(Clone(inner)));