/// <summary>Transverse the tree and create the follows table</summary> /// <param name="node">The current node</param> private void CreateFollowsTable(Node node) { if (node != null) { CreateFollowsTable(node.LeftChild); CreateFollowsTable(node.RightChild); if (node.LeftChild != null || node.RightChild != null) { if (node.Value.Equals("·")) { Tuple <int, string> key = new Tuple <int, string>(node.LeftChild.Identifier, node.LeftChild.Value); Tuple <List <int>[], bool> c1 = FirstLastTable[key]; key = new Tuple <int, string>(node.RightChild.Identifier, node.RightChild.Value); Tuple <List <int>[], bool> c2 = FirstLastTable[key]; foreach (int last in c1.Item1[1]) { Tuple <int, string> insert = FollowsTable.FirstOrDefault(x => x.Key.Item1 == last).Key; FollowsTable[insert].AddRange(c2.Item1[0]); } } else if (node.Value.Equals("*") || node.Value.Equals("+")) { Tuple <int, string> key = new Tuple <int, string>(node.LeftChild.Identifier, node.LeftChild.Value); Tuple <List <int>[], bool> c1 = FirstLastTable[key]; foreach (int last in c1.Item1[1]) { Tuple <int, string> insert = FollowsTable.FirstOrDefault(x => x.Key.Item1 == last).Key; FollowsTable[insert].AddRange(c1.Item1[0]); } } } } }
/// <summary>Create the transitions</summary> private void CreateTransitions() { int cont = 0; List <int> initialStateValue = FirstLastTable.FirstOrDefault(x => x.Key.Item1 == Tree.Identifier).Value .Item1[0]; Tuple <string, List <int> > initialState = new Tuple <string, List <int> >("State 0", initialStateValue); Queue <Tuple <string, List <int> > > pendingStates = new Queue <Tuple <string, List <int> > >(); pendingStates.Enqueue(initialState); while (pendingStates.Count > 0) { Dictionary <string, List <int> > values = new Dictionary <string, List <int> >(); Tuple <string, List <int> > state = pendingStates.Peek(); foreach (int number in state.Item2) { Tuple <int, string> followKey = FollowsTable.FirstOrDefault(x => x.Key.Item1 == number).Key; string transitionWith = followKey.Item2; List <int> transitionValues = new List <int>(FollowsTable[followKey]); if (transitionValues.Count > 0) { if (values.ContainsKey(transitionWith)) { foreach (int element in transitionValues) { if (!values[transitionWith].Contains(element)) { values[transitionWith].Add(element); } } } else { values.Add(transitionWith, transitionValues); } values[transitionWith].Sort(); } } foreach (KeyValuePair <string, List <int> > value in values) { if (!Transitions.Any(x => x.Key.Item2.SequenceEqual(value.Value)) && !pendingStates.Any(x => x.Item2.SequenceEqual(value.Value))) { cont++; Tuple <string, List <int> > newState = new Tuple <string, List <int> >("State " + cont, value.Value); pendingStates.Enqueue(newState); } } Tuple <string, List <int>, bool> key; if (state.Item2.Contains(Tree.RightChild.Identifier)) { key = new Tuple <string, List <int>, bool>(state.Item1, state.Item2, true); } else { key = new Tuple <string, List <int>, bool>(state.Item1, state.Item2, false); } pendingStates.Dequeue(); Transitions.Add(key, values); } }