private void FindDFAParameters(IEnumerable <string> alphabet, IEnumerable <NodeNFA> startingNodes, ref Dictionary <NodeDFA, Dictionary <string, IEnumerable <NodeNFA> > > rawDFAParameters) { var newNodeDFAName = string.Concat(startingNodes.Select(x => x.Name)); if (rawDFAParameters.Keys.Select(x => x.Name).Contains(newNodeDFAName)) { return; } var isAccepting = startingNodes.Any(x => x.IsAccepting); var newNodeDFA = new NodeDFA(newNodeDFAName, isAccepting); rawDFAParameters.Add(newNodeDFA, new Dictionary <string, IEnumerable <NodeNFA> >()); foreach (var symbol in alphabet) { var symbolNodes = new HashSet <NodeNFA>(); foreach (var node in startingNodes) { symbolNodes.UnionWith(node.Associations[symbol]); } rawDFAParameters[newNodeDFA].Add(symbol, symbolNodes); FindDFAParameters(alphabet, symbolNodes, ref rawDFAParameters); } }
public void AutomateMatchWorks(string candidate, bool expected) { //Automate pour le regex (ab)* NodeDFA s0 = new NodeDFA(true); NodeDFA s1 = new NodeDFA(false); NodeDFA s2 = new NodeDFA(false); NodeDFA s3 = new NodeDFA(false); s0.Add('a', s1); s0.Add('b', s3); s1.Add('a', s3); s1.Add('b', s2); s2.Add('a', s1); s2.Add('b', s3); s3.Add('a', s3); s3.Add('b', s3); Automate dfa = new Automate(s0); Assert.That(dfa.Match(candidate), Is.EqualTo(expected)); }
public DFA ToDFA() { var nodes = GetAllNodes().Select(n => n as NodeNFA); foreach (var node in nodes) { if (node.EpsilonPath != null && node.EpsilonPath.Any()) { nodes = RemoveEpsilonPasses().GetAllNodes().Select(n => n as NodeNFA); break; } } // At this point I for sure have NFA var nodesDFA = new List <NodeDFA>(); var startingNode = nodes.Where(n => n.Name == StartingNode.Name).Single(); var rawDFAParameters = new Dictionary <NodeDFA, Dictionary <string, IEnumerable <NodeNFA> > >(); FindDFAParameters(Alphabet, new[] { startingNode }, ref rawDFAParameters); nodesDFA.AddRange(rawDFAParameters.Keys); // If any qx(symbol) leads to null, create nullnode foreach (var nodeDFA in rawDFAParameters) { var a = nodeDFA.Value.Values.ToList(); if (nodeDFA.Value.Values.Any(x => x == null || !x.Any())) { var nullNode = new NodeDFA("null", false); foreach (var symbol in Alphabet) { nullNode.ConnectWith(nullNode, symbol); } nodesDFA.Add(nullNode); break; } } /* * What I have here: * - DFA nodes with no connections created * - rawDFAParameters */ foreach (var nodeDFA in nodesDFA.Where(x => x.Name != "null")) { foreach (var symbol in Alphabet) { var rawConnection = rawDFAParameters[nodeDFA][symbol]; if (rawConnection == null || !rawConnection.Any()) { nodeDFA.ConnectWith(nodesDFA.Where(x => x.Name == "null").Single(), symbol); } else { var nodeToConnect = nodesDFA.Where(x => x.Name == string.Concat(rawConnection.Select(x => x.Name))).Single(); nodeDFA.ConnectWith(nodeToConnect, symbol); } } } var startingNodeDFA = nodesDFA.Where(x => x.Name == startingNode.Name).Single(); var newDFA = new DFA(Alphabet, startingNodeDFA); return(newDFA); }