コード例 #1
0
ファイル: RegexDFA.cpp プロジェクト: Angelineguan/Spire
	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();
		}
	}