/// <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); } }
/// <summary>Transverse the tree and create the first and lasts</summary> /// <param name="node">The current node</param> private void CreateFirstlastsTable(Node node) { if (node != null) { CreateFirstlastsTable(node.LeftChild); CreateFirstlastsTable(node.RightChild); if (node.LeftChild == null && node.RightChild == null) { List <int> firsts = new List <int> { node.Identifier }; List <int> lasts = new List <int> { node.Identifier }; List <int>[] values = new List <int>[2] { firsts, lasts }; Tuple <int, string> identifier = new Tuple <int, string>(node.Identifier, node.Value); Tuple <List <int>[], bool> data = new Tuple <List <int>[], bool>(values, false); FirstLastTable.Add(identifier, data); } else { List <int> firsts = new List <int>(); List <int> lasts = new List <int>(); bool nullable = false; Tuple <int, string> key = new Tuple <int, string>(node.LeftChild.Identifier, node.LeftChild.Value); Tuple <List <int>[], bool> c1 = FirstLastTable[key]; if (node.Value.Equals("|")) { key = new Tuple <int, string>(node.RightChild.Identifier, node.RightChild.Value); Tuple <List <int>[], bool> c2 = FirstLastTable[key]; firsts.AddRange(c1.Item1[0]); firsts.AddRange(c2.Item1[0]); lasts.AddRange(c1.Item1[1]); lasts.AddRange(c2.Item1[1]); if (c1.Item2 || c2.Item2) { nullable = true; } } else if (node.Value.Equals("·")) { key = new Tuple <int, string>(node.RightChild.Identifier, node.RightChild.Value); Tuple <List <int>[], bool> c2 = FirstLastTable[key]; if (c1.Item2) { firsts.AddRange(c1.Item1[0]); firsts.AddRange(c2.Item1[0]); } else { firsts.AddRange(c1.Item1[0]); } if (c2.Item2) { lasts.AddRange(c1.Item1[1]); lasts.AddRange(c2.Item1[1]); } else { lasts.AddRange(c2.Item1[1]); } if (c1.Item2 && c2.Item2) { nullable = true; } } else if (node.Value.Equals("*")) { firsts.AddRange(c1.Item1[0]); lasts.AddRange(c1.Item1[1]); nullable = true; } else if (node.Value.Equals("+")) { firsts.AddRange(c1.Item1[0]); lasts.AddRange(c1.Item1[1]); } else { firsts.AddRange(c1.Item1[0]); lasts.AddRange(c1.Item1[1]); nullable = true; } List <int>[] values = new List <int>[2] { firsts, lasts }; Tuple <int, string> identifier = new Tuple <int, string>(node.Identifier, node.Value); Tuple <List <int>[], bool> data = new Tuple <List <int>[], bool>(values, nullable); FirstLastTable.Add(identifier, data); } } }