internal void ReplaceSource(NfaNode oldSource, NfaNode newSource) { // owner is the target node here unlink(owner.Connections.from, oldSource); foreach (NfaEdge.Fiber fiber in unlink(oldSource.Connections.to, owner)) { Link(newSource, fiber, owner); } }
internal void ReplaceTarget(NfaNode oldTarget, NfaNode newTarget) { // owner is the source node here unlink(owner.Connections.to, oldTarget); foreach (NfaEdge.Fiber fiber in unlink(oldTarget.Connections.from, owner)) { Link(owner, fiber, newTarget); } }
internal void ConnectTo(NfaNode targetNode, NfaEdge edge) { // store current edges, to work with clear space between given nodes Connections this_connections = this.Connections.Reset(); Connections targetNode_connections = targetNode.Connections.Reset(); // fibers in edge are sorted from the longest to the shortest foreach (IEnumerable <NfaEdge.Fiber> fiber_chain in edge.Fibers) { connectBetween(this, targetNode, fiber_chain.Reverse()); } // merge previous edges with newly created this.Connections.Merge(this_connections); targetNode.Connections.Merge(targetNode_connections); }
// UTF-8 by definition differentiates head of bytes, but the tail can be shared // thus we handle the chain in reverse order to merge the tails static private void connectBetween(NfaNode start, NfaNode end, IEnumerable <NfaEdge.Fiber> revFiberChain) { if (revFiberChain.Count() == 1) { start.linkTo(end, revFiberChain.Single()); } else { NfaNode prec_node = end.Connections.From .Where(it => it.Item1.Equals(revFiberChain.First())) .Select(it => it.Item2) .SingleOrDefault(); if (prec_node == null) { prec_node = new NfaNode(); prec_node.linkTo(end, revFiberChain.First()); } connectBetween(start, prec_node, revFiberChain.Skip(1)); } }
private void linkTo(NfaNode target, NfaEdge.Fiber fiber) { Connections.Link(this, fiber, target); }
internal Nfa() { this.StartNode = new NfaNode(); }
static private IEnumerable <NfaEdge.Fiber> unlink(List <Tuple <NfaEdge.Fiber, NfaNode> > links, NfaNode node) { var removed = new List <NfaEdge.Fiber>(); for (int i = links.Count - 1; i >= 0; --i) { if (links[i].Item2 == node) { removed.Add(links[i].Item1); links.RemoveAt(i); } } return(removed); }
static internal void Link(NfaNode source, NfaEdge.Fiber fiber, NfaNode target) { source.Connections.to.Add(Tuple.Create(fiber, target)); target.Connections.from.Add(Tuple.Create(fiber, source)); }
internal Connections(NfaNode owner) { this.owner = owner; init(); }