void DFA_Graph::Generate(NFA_Graph * nfa) { table = new RegexCharTable(); List<RegexCharSet * > charSets; for (int i=0; i<nfa->translations.Count(); i++) { if (nfa->translations[i]->CharSet && nfa->translations[i]->CharSet->Ranges.Count()) charSets.Add(nfa->translations[i]->CharSet.operator->()); } CharTableGenerator gen(table.operator ->()); int elements = gen.Generate(charSets); CharElements = gen.elements; List<DFA_Node *> L,D; startNode = new DFA_Node(elements); startNode->ID = 0; startNode->Nodes.Add(nfa->start); L.Add(startNode); nodes.Add(startNode); List<Word> charElem; do { DFA_Node * node = L.Last(); L.RemoveAt(L.Count()-1); charElem.Clear(); node->IsFinal = false; for (int i=0; i<node->Nodes.Count(); i++) { CombineCharElements(node->Nodes[i], charElem); if (node->Nodes[i]->IsFinal) node->IsFinal = true; } for (int i=0; i<charElem.Count(); i++) { DFA_Node * n = new DFA_Node(0); for (int j=0; j<node->Nodes.Count(); j++) { for (int k=0; k<node->Nodes[j]->Translations.Count(); k++) { NFA_Translation * trans = node->Nodes[j]->Translations[k]; if (trans->CharSet->Elements.Contains(charElem[i])) { if (!n->Nodes.Contains(node->Nodes[j]->Translations[k]->NodeDest)) n->Nodes.Add(node->Nodes[j]->Translations[k]->NodeDest); } } } int fid = -1; for (int j=0; j<nodes.Count(); j++) { if ((*nodes[j]) == *n) { fid = j; break; } } if (fid == -1) { n->Translations.SetSize(elements); for (int m=0; m<elements; m++) n->Translations[m] = 0; n->ID = nodes.Count(); L.Add(n); nodes.Add(n); fid = nodes.Count()-1; } else delete n; n = nodes[fid].operator ->(); node->Translations[charElem[i]] = n; } } while (L.Count()); // Set Terminal Identifiers HashSet<int> terminalIdentifiers; for (int i=0; i<nodes.Count(); i++) { terminalIdentifiers.Clear(); for (int j=0; j<nodes[i]->Nodes.Count(); j++) { if (nodes[i]->Nodes[j]->IsFinal && !terminalIdentifiers.Contains(nodes[i]->Nodes[j]->TerminalIdentifier)) { nodes[i]->IsFinal = true; terminalIdentifiers.Add(nodes[i]->Nodes[j]->TerminalIdentifier); nodes[i]->TerminalIdentifiers.Add(nodes[i]->Nodes[j]->TerminalIdentifier); } } nodes[i]->TerminalIdentifiers.Sort(); } }