private static void computeClasses(Spec spec) { SimplifyNfa.original_charset_size = spec.dtrans_ncols; SimplifyNfa.ccls = new char[SimplifyNfa.original_charset_size]; char c = '\u0001'; BitSet bitSet = new BitSet(); BitSet bitSet2 = new BitSet(); Dictionary <char, char> dictionary = new Dictionary <char, char>(); Console.WriteLine("Working on character classes."); for (int i = 0; i < spec.nfa_states.Count; i++) { Nfa nfa = spec.nfa_states[i]; if (nfa.Edge != '�' && nfa.Edge != '') { bitSet.ClearAll(); bitSet2.ClearAll(); for (int j = 0; j < SimplifyNfa.ccls.Length; j++) { if ((int)nfa.Edge == j || (nfa.Edge == '' && nfa.GetCharSet().contains(j))) { bitSet.Set((int)SimplifyNfa.ccls[j], true); } else { bitSet2.Set((int)SimplifyNfa.ccls[j], true); } } bitSet.And(bitSet2); if (bitSet.GetLength() != 0) { dictionary.Clear(); for (int k = 0; k < SimplifyNfa.ccls.Length; k++) { if (bitSet.Get((int)SimplifyNfa.ccls[k]) && ((int)nfa.Edge == k || (nfa.Edge == '' && nfa.GetCharSet().contains(k)))) { char c2 = SimplifyNfa.ccls[k]; if (!dictionary.ContainsKey(c2)) { Dictionary <char, char> arg_14F_0 = dictionary; char arg_14F_1 = c2; char expr_14A = c; c = (char)(expr_14A + '\u0001'); arg_14F_0.Add(arg_14F_1, expr_14A); } SimplifyNfa.ccls[k] = dictionary[c2]; } } } } } SimplifyNfa.mapped_charset_size = (int)c; }
/* * Compute minimum set of character classes needed to disambiguate * edges. We optimistically assume that every character belongs to * a single character class, and then incrementally split classes * as we see edges that require discrimination between characters in * the class. */ static private void computeClasses(Spec spec) { original_charset_size = spec.dtrans_ncols; ccls = new int[original_charset_size]; // initially all zero. int nextcls = 1; BitSet clsA = new BitSet(); BitSet clsB = new BitSet(); Hashtable h = new Hashtable(); Console.WriteLine("Working on character classes."); for (int index = 0; index < spec.nfa_states.Count; index++) { Nfa nfa = (Nfa)spec.nfa_states[index]; if (nfa.GetEdge() == Nfa.EMPTY || nfa.GetEdge() == Nfa.EPSILON) { continue; // no discriminatory information. } clsA.ClearAll(); clsB.ClearAll(); for (int i = 0; i < ccls.Length; i++) { if (nfa.GetEdge() == i || // edge labeled with a character nfa.GetEdge() == Nfa.CCL && nfa.GetCharSet().contains(i)) // set of characters { clsA.Set(ccls[i], true); } else { clsB.Set(ccls[i], true); } } /* * now figure out which character classes we need to split. */ clsA.And(clsB); // split the classes which show up on both sides of edge if (clsA.GetLength() == 0) { Console.Write("."); continue; } Console.Write(":"); /* * and split them. */ h.Clear(); // h will map old to new class name for (int i = 0; i < ccls.Length; i++) { if (clsA.Get(ccls[i])) // a split class { if (nfa.GetEdge() == i || nfa.GetEdge() == Nfa.CCL && nfa.GetCharSet().contains(i)) { // on A side int split = ccls[i]; if (!h.ContainsKey(split)) { h.Add(split, nextcls++); // make new class #if DEBUG Console.WriteLine("Adding char " + (nextcls - 1) + " split=" + split + " i=" + i); #endif } ccls[i] = (int)h[split]; } } } } Console.WriteLine(); Console.WriteLine("NFA has " + nextcls + " distinct character classes."); mapped_charset_size = nextcls; }