Пример #1
0
        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);
            }
        }
Пример #2
0
        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));
        }
Пример #3
0
        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);
        }